Skip to content

Commit d0c6e61

Browse files
committed
validation: don't modify genesis during snapshot load
Avoid modifying the genesis block index entry during snapshot load. This is because, in a future change that fixes LoadBlockIndex for UTXO snapshots, we detect block index entries that are reliant on assumed-valid ancestors and treat them specially. Since the genesis block doesn't have BLOCK_VALID_SCRIPTS, it would be erroneously marked BLOCK_ASSUMED_VALID during snapshot load if we didn't skip it here. This would cause a "setBlockIndexCandidates() empty" assertion to be tripped since all block index entries would be marked assume-valid due to genesis, which is never re-validated. There's probably no good reason to modify the genesis block index entry during snapshot load anyway...
1 parent af4275e commit d0c6e61

File tree

2 files changed

+13
-3
lines changed

2 files changed

+13
-3
lines changed

src/test/validation_chainstatemanager_tests.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,9 @@ BOOST_FIXTURE_TEST_CASE(chainstatemanager_activate_snapshot, TestChain100Setup)
232232
*chainman.ActiveChainstate().m_from_snapshot_blockhash,
233233
*chainman.SnapshotBlockhash());
234234

235+
// Ensure that the genesis block was not marked assumed-valid.
236+
BOOST_CHECK(!chainman.ActiveChain().Genesis()->IsAssumedValid());
237+
235238
const AssumeutxoData& au_data = *ExpectedAssumeutxo(snapshot_height, ::Params());
236239
const CBlockIndex* tip = chainman.ActiveTip();
237240

src/validation.cpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4909,7 +4909,14 @@ bool ChainstateManager::PopulateAndValidateSnapshot(
49094909

49104910
// Fake various pieces of CBlockIndex state:
49114911
CBlockIndex* index = nullptr;
4912-
for (int i = 0; i <= snapshot_chainstate.m_chain.Height(); ++i) {
4912+
4913+
// Don't make any modifications to the genesis block.
4914+
// This is especially important because we don't want to erroneously
4915+
// apply BLOCK_ASSUMED_VALID to genesis, which would happen if we didn't skip
4916+
// it here (since it apparently isn't BLOCK_VALID_SCRIPTS).
4917+
constexpr int AFTER_GENESIS_START{1};
4918+
4919+
for (int i = AFTER_GENESIS_START; i <= snapshot_chainstate.m_chain.Height(); ++i) {
49134920
index = snapshot_chainstate.m_chain[i];
49144921

49154922
// Fake nTx so that LoadBlockIndex() loads assumed-valid CBlockIndex
@@ -4918,7 +4925,7 @@ bool ChainstateManager::PopulateAndValidateSnapshot(
49184925
index->nTx = 1;
49194926
}
49204927
// Fake nChainTx so that GuessVerificationProgress reports accurately
4921-
index->nChainTx = index->pprev ? index->pprev->nChainTx + index->nTx : 1;
4928+
index->nChainTx = index->pprev->nChainTx + index->nTx;
49224929

49234930
// Mark unvalidated block index entries beneath the snapshot base block as assumed-valid.
49244931
if (!index->IsValid(BLOCK_VALID_SCRIPTS)) {
@@ -4929,7 +4936,7 @@ bool ChainstateManager::PopulateAndValidateSnapshot(
49294936

49304937
// Fake BLOCK_OPT_WITNESS so that CChainState::NeedsRedownload()
49314938
// won't ask to rewind the entire assumed-valid chain on startup.
4932-
if (index->pprev && DeploymentActiveAt(*index, ::Params().GetConsensus(), Consensus::DEPLOYMENT_SEGWIT)) {
4939+
if (DeploymentActiveAt(*index, ::Params().GetConsensus(), Consensus::DEPLOYMENT_SEGWIT)) {
49334940
index->nStatus |= BLOCK_OPT_WITNESS;
49344941
}
49354942

0 commit comments

Comments
 (0)