Skip to content

Commit 85c82b5

Browse files
committed
Avoid masking of difficulty adjustment errors by checkpoints
Currently difficulty adjustment violations are not reported for chains that branch off before the last checkpoint. Change this by moving the checkpoint check after the difficulty check.
1 parent e526ca6 commit 85c82b5

File tree

1 file changed

+15
-27
lines changed

1 file changed

+15
-27
lines changed

src/validation.cpp

Lines changed: 15 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2830,22 +2830,6 @@ bool CheckBlock(const CBlock& block, CValidationState& state, const Consensus::P
28302830
return true;
28312831
}
28322832

2833-
static bool CheckIndexAgainstCheckpoint(const CBlockIndex* pindexPrev, CValidationState& state, const CChainParams& chainparams, const uint256& hash)
2834-
{
2835-
if (*pindexPrev->phashBlock == chainparams.GetConsensus().hashGenesisBlock)
2836-
return true;
2837-
2838-
int nHeight = pindexPrev->nHeight+1;
2839-
// Don't accept any forks from the main chain prior to last checkpoint.
2840-
// GetLastCheckpoint finds the last checkpoint in MapCheckpoints that's in our
2841-
// MapBlockIndex.
2842-
CBlockIndex* pcheckpoint = Checkpoints::GetLastCheckpoint(chainparams.Checkpoints());
2843-
if (pcheckpoint && nHeight < pcheckpoint->nHeight)
2844-
return state.DoS(100, error("%s: forked chain older than last checkpoint (height %d)", __func__, nHeight), REJECT_CHECKPOINT, "bad-fork-prior-to-checkpoint");
2845-
2846-
return true;
2847-
}
2848-
28492833
bool IsWitnessEnabled(const CBlockIndex* pindexPrev, const Consensus::Params& params)
28502834
{
28512835
LOCK(cs_main);
@@ -2911,14 +2895,26 @@ std::vector<unsigned char> GenerateCoinbaseCommitment(CBlock& block, const CBloc
29112895
/** Context-dependent validity checks.
29122896
* By "context", we mean only the previous block headers, but not the UTXO
29132897
* set; UTXO-related validity checks are done in ConnectBlock(). */
2914-
static bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& state, const Consensus::Params& consensusParams, const CBlockIndex* pindexPrev, int64_t nAdjustedTime)
2898+
static bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& state, const CChainParams& params, const CBlockIndex* pindexPrev, int64_t nAdjustedTime)
29152899
{
29162900
assert(pindexPrev != NULL);
29172901
const int nHeight = pindexPrev->nHeight + 1;
2902+
29182903
// Check proof of work
2904+
const Consensus::Params& consensusParams = params.GetConsensus();
29192905
if (block.nBits != GetNextWorkRequired(pindexPrev, &block, consensusParams))
29202906
return state.DoS(100, false, REJECT_INVALID, "bad-diffbits", false, "incorrect proof of work");
29212907

2908+
// Check against checkpoints
2909+
if (fCheckpointsEnabled) {
2910+
// Don't accept any forks from the main chain prior to last checkpoint.
2911+
// GetLastCheckpoint finds the last checkpoint in MapCheckpoints that's in our
2912+
// MapBlockIndex.
2913+
CBlockIndex* pcheckpoint = Checkpoints::GetLastCheckpoint(params.Checkpoints());
2914+
if (pcheckpoint && nHeight < pcheckpoint->nHeight)
2915+
return state.DoS(100, error("%s: forked chain older than last checkpoint (height %d)", __func__, nHeight), REJECT_CHECKPOINT, "bad-fork-prior-to-checkpoint");
2916+
}
2917+
29222918
// Check timestamp against prev
29232919
if (block.GetBlockTime() <= pindexPrev->GetMedianTimePast())
29242920
return state.Invalid(false, REJECT_INVALID, "time-too-old", "block's timestamp is too early");
@@ -3049,12 +3045,7 @@ static bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state
30493045
pindexPrev = (*mi).second;
30503046
if (pindexPrev->nStatus & BLOCK_FAILED_MASK)
30513047
return state.DoS(100, error("%s: prev block invalid", __func__), REJECT_INVALID, "bad-prevblk");
3052-
3053-
assert(pindexPrev);
3054-
if (fCheckpointsEnabled && !CheckIndexAgainstCheckpoint(pindexPrev, state, chainparams, hash))
3055-
return error("%s: CheckIndexAgainstCheckpoint(): %s", __func__, state.GetRejectReason().c_str());
3056-
3057-
if (!ContextualCheckBlockHeader(block, state, chainparams.GetConsensus(), pindexPrev, GetAdjustedTime()))
3048+
if (!ContextualCheckBlockHeader(block, state, chainparams, pindexPrev, GetAdjustedTime()))
30583049
return error("%s: Consensus::ContextualCheckBlockHeader: %s, %s", __func__, hash.ToString(), FormatStateMessage(state));
30593050
}
30603051
if (pindex == NULL)
@@ -3203,16 +3194,13 @@ bool TestBlockValidity(CValidationState& state, const CChainParams& chainparams,
32033194
{
32043195
AssertLockHeld(cs_main);
32053196
assert(pindexPrev && pindexPrev == chainActive.Tip());
3206-
if (fCheckpointsEnabled && !CheckIndexAgainstCheckpoint(pindexPrev, state, chainparams, block.GetHash()))
3207-
return error("%s: CheckIndexAgainstCheckpoint(): %s", __func__, state.GetRejectReason().c_str());
3208-
32093197
CCoinsViewCache viewNew(pcoinsTip);
32103198
CBlockIndex indexDummy(block);
32113199
indexDummy.pprev = pindexPrev;
32123200
indexDummy.nHeight = pindexPrev->nHeight + 1;
32133201

32143202
// NOTE: CheckBlockHeader is called by CheckBlock
3215-
if (!ContextualCheckBlockHeader(block, state, chainparams.GetConsensus(), pindexPrev, GetAdjustedTime()))
3203+
if (!ContextualCheckBlockHeader(block, state, chainparams, pindexPrev, GetAdjustedTime()))
32163204
return error("%s: Consensus::ContextualCheckBlockHeader: %s", __func__, FormatStateMessage(state));
32173205
if (!CheckBlock(block, state, chainparams.GetConsensus(), fCheckPOW, fCheckMerkleRoot))
32183206
return error("%s: Consensus::CheckBlock: %s", __func__, FormatStateMessage(state));

0 commit comments

Comments
 (0)