Merge bitcoin/bitcoin#35673: refactor: Move LoadGenesisBlock to ChainstateManager

fa615bd163 refactor: Move LoadGenesisBlock to ChainstateManager (MarcoFalke)

Pull request description:

  The function does not need anything from any chainstate, so it should not sit in the Chainstate class.

ACKs for top commit:
  l0rinc:
    Tested ACK fa615bd163
  janb84:
    reACK fa615bd163
  sedited:
    ACK fa615bd163

Tree-SHA512: 482b5c140faa35944a890c941fd185a896a3c04fec46d0cc6dd56830f62ee8fe5200fd13d25f7a80a5da0eb4fb42717f42c8bce837d933668432f5786f8380e3
This commit is contained in:
merge-script
2026-07-08 10:07:44 +02:00
6 changed files with 17 additions and 16 deletions

View File

@@ -1305,7 +1305,7 @@ void ImportBlocks(ChainstateManager& chainman, std::span<const fs::path> import_
chainman.m_blockman.m_blockfiles_indexed = true;
LogInfo("Reindexing finished");
// To avoid ending up in a situation without genesis block, re-try initializing (no-op if reindexing worked):
chainman.ActiveChainstate().LoadGenesisBlock();
(void)chainman.LoadGenesisBlock();
}
// -loadblock=

View File

@@ -62,7 +62,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 (chainman.m_blockman.m_blockfiles_indexed && !chainman.ActiveChainstate().LoadGenesisBlock()) {
if (chainman.m_blockman.m_blockfiles_indexed && !chainman.LoadGenesisBlock()) {
return {ChainstateLoadStatus::FAILURE, _("Error initializing block database")};
}

View File

@@ -80,7 +80,7 @@ CreateAndActivateUTXOSnapshot(
node.chainman->ResetChainstates();
node.chainman->InitializeChainstate(node.mempool.get());
Chainstate& chain = node.chainman->ActiveChainstate();
Assert(chain.LoadGenesisBlock());
Assert(node.chainman->LoadGenesisBlock());
// These cache values will be corrected shortly in `MaybeRebalanceCaches`.
chain.InitCoinsDB(1_MiB, /*in_memory=*/true, /*should_wipe=*/false);
chain.InitCoinsCache(1_MiB);

View File

@@ -43,7 +43,7 @@ BOOST_AUTO_TEST_CASE(validation_chainstate_resize_caches)
c1.InitCoinsDB(
/*cache_size_bytes=*/8_MiB, /*in_memory=*/true, /*should_wipe=*/false);
WITH_LOCK(::cs_main, c1.InitCoinsCache(8_MiB));
BOOST_REQUIRE(c1.LoadGenesisBlock()); // Need at least one block loaded to be able to flush caches
BOOST_REQUIRE(manager.LoadGenesisBlock()); // Need at least one block loaded to be able to flush caches
// Add a coin to the in-memory cache, upsize once, then downsize.
{

View File

@@ -4943,30 +4943,30 @@ bool ChainstateManager::LoadBlockIndex()
return true;
}
bool Chainstate::LoadGenesisBlock()
bool ChainstateManager::LoadGenesisBlock()
{
LOCK(cs_main);
const CChainParams& params{m_chainman.GetParams()};
const CBlock& genesis_block{GetParams().GenesisBlock()};
// Check whether we're already initialized by checking for genesis in
// m_blockman.m_block_index. Note that we can't use m_chain here, since it is
// m_blockman.m_block_index. Note that we can't use a chainstate's m_chain here, since it is
// set based on the coins db, not the block index db, which is the only
// thing loaded at this point.
if (m_blockman.m_block_index.contains(params.GenesisBlock().GetHash()))
if (m_blockman.m_block_index.contains(genesis_block.GetHash())) {
return true;
}
try {
const CBlock& block = params.GenesisBlock();
FlatFilePos blockPos{m_blockman.WriteBlock(block, 0)};
FlatFilePos blockPos{m_blockman.WriteBlock(genesis_block, 0)};
if (blockPos.IsNull()) {
LogError("%s: writing genesis block to disk failed\n", __func__);
LogError("Writing genesis block to disk failed");
return false;
}
CBlockIndex* pindex = m_blockman.AddToBlockIndex(block, m_chainman.m_best_header);
m_chainman.ReceivedBlockTransactions(block, pindex, blockPos);
CBlockIndex* pindex{m_blockman.AddToBlockIndex(genesis_block, m_best_header)};
ReceivedBlockTransactions(genesis_block, pindex, blockPos);
} catch (const std::runtime_error& e) {
LogError("%s: failed to write genesis block: %s\n", __func__, e.what());
LogError("Failed to write genesis block: %s", e.what());
return false;
}

View File

@@ -809,8 +809,6 @@ public:
/** Whether the chain state needs to be redownloaded due to lack of witness data */
[[nodiscard]] bool NeedsRedownload() const EXCLUSIVE_LOCKS_REQUIRED(cs_main);
/** Ensures we have a genesis block in the block tree, possibly writing one to disk. */
bool LoadGenesisBlock();
/** Add a block to the candidate set if it has as much work as the current tip. */
void TryAddBlockIndexCandidate(CBlockIndex* pindex) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
@@ -1085,6 +1083,9 @@ public:
//! coins databases. This will be split somehow across chainstates.
size_t m_total_coinsdb_cache{0};
/// Ensures a genesis block is in the block tree, possibly writing one to disk.
[[nodiscard]] bool LoadGenesisBlock();
//! Instantiate a new chainstate.
//!
//! @param[in] mempool The mempool to pass to the chainstate