Skip to content

Commit

Permalink
validation: avoid masking of difficulty adjustment errors
Browse files Browse the repository at this point in the history
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.

Backported from: 85c82b5
Original Author: Pieter Wuille <pieter.wuille@gmail.com>
  • Loading branch information
patricklodder committed Jul 3, 2024
1 parent 962b020 commit 215fc33
Showing 1 changed file with 12 additions and 20 deletions.
32 changes: 12 additions & 20 deletions src/validation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2998,20 +2998,6 @@ bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bo
return true;
}

static bool CheckIndexAgainstCheckpoint(const CBlockIndex* pindexPrev, CValidationState& state, const CChainParams& chainparams, const uint256& hash)
{
if (*pindexPrev->phashBlock == chainparams.GetConsensus(0).hashGenesisBlock)
return true;

int nHeight = pindexPrev->nHeight+1;
// Don't accept any forks from the main chain prior to last checkpoint
CBlockIndex* pcheckpoint = Checkpoints::GetLastCheckpoint(chainparams.Checkpoints());
if (pcheckpoint && nHeight < pcheckpoint->nHeight)
return state.DoS(100, error("%s: forked chain older than last checkpoint (height %d)", __func__, nHeight));

return true;
}

bool IsWitnessEnabled(const CBlockIndex* pindexPrev, const Consensus::Params& params)
{
// Dogecoin: Disable SegWit
Expand Down Expand Up @@ -3079,7 +3065,8 @@ std::vector<unsigned char> GenerateCoinbaseCommitment(CBlock& block, const CBloc
bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& state, const CBlockIndex* pindexPrev, int64_t nAdjustedTime)
{
const int nHeight = pindexPrev == NULL ? 0 : pindexPrev->nHeight + 1;
const Consensus::Params& consensusParams = Params().GetConsensus(nHeight);
const CChainParams& params = Params();
const Consensus::Params& consensusParams = params.GetConsensus(nHeight);

// Disallow legacy blocks after merge-mining start.
if (!consensusParams.fAllowLegacyBlocks
Expand All @@ -3101,6 +3088,16 @@ bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& sta
if (block.nBits != GetNextWorkRequired(pindexPrev, &block, consensusParams))
return state.DoS(100, false, REJECT_INVALID, "bad-diffbits", false, "incorrect proof of work");

// Check against checkpoints
if (fCheckpointsEnabled) {
// Don't accept any forks from the main chain prior to last checkpoint.
// GetLastCheckpoint finds the last checkpoint in MapCheckpoints that's in our
// MapBlockIndex.
CBlockIndex* pcheckpoint = Checkpoints::GetLastCheckpoint(params.Checkpoints());
if (pcheckpoint && nHeight < pcheckpoint->nHeight)
return state.DoS(100, error("%s: forked chain older than last checkpoint (height %d)", __func__, nHeight), REJECT_CHECKPOINT, "bad-fork-prior-to-checkpoint");
}

// Check timestamp against prev
if (block.GetBlockTime() <= pindexPrev->GetMedianTimePast())
return state.Invalid(false, REJECT_INVALID, "time-too-old", "block's timestamp is too early");
Expand Down Expand Up @@ -3236,8 +3233,6 @@ static bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state
return state.DoS(100, error("%s: prev block invalid", __func__), REJECT_INVALID, "bad-prevblk");

assert(pindexPrev);
if (fCheckpointsEnabled && !CheckIndexAgainstCheckpoint(pindexPrev, state, chainparams, hash))
return error("%s: CheckIndexAgainstCheckpoint(): %s", __func__, state.GetRejectReason().c_str());

if (!ContextualCheckBlockHeader(block, state, pindexPrev, GetAdjustedTime()))
return error("%s: Consensus::ContextualCheckBlockHeader: %s, %s", __func__, hash.ToString(), FormatStateMessage(state));
Expand Down Expand Up @@ -3417,9 +3412,6 @@ bool TestBlockValidity(CValidationState& state, const CChainParams& chainparams,
{
AssertLockHeld(cs_main);
assert(pindexPrev && pindexPrev == chainActive.Tip());
if (fCheckpointsEnabled && !CheckIndexAgainstCheckpoint(pindexPrev, state, chainparams, block.GetHash()))
return error("%s: CheckIndexAgainstCheckpoint(): %s", __func__, state.GetRejectReason().c_str());

CCoinsViewCache viewNew(pcoinsTip);
CBlockIndex indexDummy(block);
indexDummy.pprev = pindexPrev;
Expand Down

0 comments on commit 215fc33

Please sign in to comment.