Skip to content

Commit 75b826c

Browse files
committed
Enforce checkpoints at their specific block height
This ensures checkpoints can't be bypassed even prior to getting the main chain's headers. This partially reverts dce8360.
1 parent 1248d0d commit 75b826c

File tree

3 files changed

+15
-1
lines changed

3 files changed

+15
-1
lines changed

src/kernel/chainparams.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,12 @@ struct CCheckpointData {
3333
const auto& final_checkpoint = mapCheckpoints.rbegin();
3434
return final_checkpoint->first /* height */;
3535
}
36+
37+
bool CheckBlock(int height, const uint256& hash) const {
38+
const auto i = mapCheckpoints.find(height);
39+
if (i == mapCheckpoints.end()) return true;
40+
return hash == i->second;
41+
}
3642
};
3743

3844
struct AssumeutxoHash : public BaseHash<uint256> {

src/test/util/setup_common.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,7 @@ ChainTestingSetup::ChainTestingSetup(const ChainType chainType, TestOpts opts)
250250
.chainparams = chainparams,
251251
.datadir = m_args.GetDataDirNet(),
252252
.check_block_index = 1,
253+
.checkpoints_enabled = false,
253254
.notifications = *m_node.notifications,
254255
.signals = m_node.validation_signals.get(),
255256
.worker_threads_num = 2,

src/validation.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4171,11 +4171,18 @@ static bool ContextualCheckBlockHeader(const CBlockHeader& block, BlockValidatio
41714171
// Don't accept any forks from the main chain prior to last checkpoint.
41724172
// GetLastCheckpoint finds the last checkpoint in MapCheckpoints that's in our
41734173
// BlockIndex().
4174-
const CBlockIndex* pcheckpoint = blockman.GetLastCheckpoint(chainman.GetParams().Checkpoints());
4174+
const auto& checkpoint_data = chainman.GetParams().Checkpoints();
4175+
const CBlockIndex* pcheckpoint = blockman.GetLastCheckpoint(checkpoint_data);
41754176
if (pcheckpoint && nHeight < pcheckpoint->nHeight) {
41764177
LogPrintf("ERROR: %s: forked chain older than last checkpoint (height %d)\n", __func__, nHeight);
41774178
return state.Invalid(BlockValidationResult::BLOCK_CHECKPOINT, "bad-fork-prior-to-checkpoint");
41784179
}
4180+
4181+
// Check that the block chain matches the known block chain up to a checkpoint
4182+
if (!checkpoint_data.CheckBlock(nHeight, block.GetHash())) {
4183+
LogPrintf("ERROR: %s: rejected by checkpoint lock-in at %d\n", __func__, nHeight);
4184+
return state.Invalid(BlockValidationResult::BLOCK_CHECKPOINT, "checkpoint-mismatch");
4185+
}
41794186
}
41804187

41814188
// Check timestamp against prev

0 commit comments

Comments
 (0)