Skip to content

Commit

Permalink
Merge bitcoin#11028: Avoid masking of difficulty adjustment errors by…
Browse files Browse the repository at this point in the history
… checkpoints

85c82b5 Avoid masking of difficulty adjustment errors by checkpoints (Pieter Wuille)

Pull request description:

  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.

Tree-SHA512: 33666f2c3459151b28c42041a463779e6df18f61d3dd5b1879a0af4e5b199ef74d1e33e06af68bebfdfb211569ad5fb56556bfebe9d63b5688d910ea211b839a
  • Loading branch information
laanwj authored and PastaPastaPasta committed Sep 20, 2019
1 parent f5a4e2f commit fda3ffa
Showing 1 changed file with 15 additions and 25 deletions.
40 changes: 15 additions & 25 deletions src/validation.cpp
Expand Up @@ -3231,30 +3231,16 @@ bool CheckBlock(const CBlock& block, CValidationState& state, const Consensus::P
return true;
}

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

int nHeight = pindexPrev->nHeight+1;
// 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(chainparams.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");

return true;
}

/** Context-dependent validity checks.
* By "context", we mean only the previous block headers, but not the UTXO
* set; UTXO-related validity checks are done in ConnectBlock(). */
static bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& state, const Consensus::Params& consensusParams, const CBlockIndex* pindexPrev, int64_t nAdjustedTime)
static bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& state, const CChainParams& params, const CBlockIndex* pindexPrev, int64_t nAdjustedTime)
{
assert(pindexPrev != nullptr);
const int nHeight = pindexPrev->nHeight + 1;

// Check proof of work
const Consensus::Params& consensusParams = params.GetConsensus();
if(Params().NetworkIDString() == CBaseChainParams::MAIN && nHeight <= 68589){
// architecture issues with DGW v1 and v2)
unsigned int nBitsNext = GetNextWorkRequired(pindexPrev, &block, consensusParams);
Expand All @@ -3269,6 +3255,16 @@ static bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationSta
return state.DoS(100, false, REJECT_INVALID, "bad-diffbits", false, strprintf("incorrect proof of work at %d", nHeight));
}

// 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", strprintf("block's timestamp is too early %d %d", block.GetBlockTime(), pindexPrev->GetMedianTimePast()));
Expand Down Expand Up @@ -3386,10 +3382,7 @@ static bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state
// it's ok-ish, the other node is probably missing the latest chainlock
return state.DoS(10, error("%s: prev block %s conflicts with chainlock", __func__, block.hashPrevBlock.ToString()), REJECT_INVALID, "bad-prevblk-chainlock");

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

if (!ContextualCheckBlockHeader(block, state, chainparams.GetConsensus(), pindexPrev, GetAdjustedTime()))
if (!ContextualCheckBlockHeader(block, state, chainparams, pindexPrev, GetAdjustedTime()))
return error("%s: Consensus::ContextualCheckBlockHeader: %s, %s", __func__, hash.ToString(), FormatStateMessage(state));

if (llmq::chainLocksHandler->HasConflictingChainLock(pindexPrev->nHeight + 1, hash)) {
Expand Down Expand Up @@ -3553,9 +3546,6 @@ bool TestBlockValidity(CValidationState& state, const CChainParams& chainparams,
assert(pindexPrev && pindexPrev == chainActive.Tip());

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

if (llmq::chainLocksHandler->HasConflictingChainLock(pindexPrev->nHeight + 1, hash)) {
return state.DoS(10, error("%s: conflicting with chainlock", __func__), REJECT_INVALID, "bad-chainlock");
}
Expand All @@ -3569,7 +3559,7 @@ bool TestBlockValidity(CValidationState& state, const CChainParams& chainparams,
auto dbTx = evoDb->BeginTransaction();

// NOTE: CheckBlockHeader is called by CheckBlock
if (!ContextualCheckBlockHeader(block, state, chainparams.GetConsensus(), pindexPrev, GetAdjustedTime()))
if (!ContextualCheckBlockHeader(block, state, chainparams, pindexPrev, GetAdjustedTime()))
return error("%s: Consensus::ContextualCheckBlockHeader: %s", __func__, FormatStateMessage(state));
if (!CheckBlock(block, state, chainparams.GetConsensus(), fCheckPOW, fCheckMerkleRoot))
return error("%s: Consensus::CheckBlock: %s", __func__, FormatStateMessage(state));
Expand Down

0 comments on commit fda3ffa

Please sign in to comment.