|
|
@ -2223,7 +2223,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin |
|
|
|
int64_t nTimeStart = GetTimeMicros(); |
|
|
|
int64_t nTimeStart = GetTimeMicros(); |
|
|
|
|
|
|
|
|
|
|
|
// Check it again in case a previous version let a bad block in
|
|
|
|
// Check it again in case a previous version let a bad block in
|
|
|
|
if (!CheckBlock(block, state, !fJustCheck, !fJustCheck)) |
|
|
|
if (!CheckBlock(block, state, chainparams.GetConsensus(), GetAdjustedTime(), !fJustCheck, !fJustCheck)) |
|
|
|
return error("%s: Consensus::CheckBlock: %s", __func__, FormatStateMessage(state)); |
|
|
|
return error("%s: Consensus::CheckBlock: %s", __func__, FormatStateMessage(state)); |
|
|
|
|
|
|
|
|
|
|
|
// verify that the view's current state corresponds to the previous block
|
|
|
|
// verify that the view's current state corresponds to the previous block
|
|
|
@ -3234,20 +3234,20 @@ bool FindUndoPos(CValidationState &state, int nFile, CDiskBlockPos &pos, unsigne |
|
|
|
return true; |
|
|
|
return true; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
bool CheckBlockHeader(const CBlockHeader& block, CValidationState& state, bool fCheckPOW) |
|
|
|
bool CheckBlockHeader(const CBlockHeader& block, CValidationState& state, const Consensus::Params& consensusParams, int64_t nAdjustedTime, bool fCheckPOW) |
|
|
|
{ |
|
|
|
{ |
|
|
|
// Check proof of work matches claimed amount
|
|
|
|
// Check proof of work matches claimed amount
|
|
|
|
if (fCheckPOW && !CheckProofOfWork(block.GetHash(), block.nBits, Params().GetConsensus())) |
|
|
|
if (fCheckPOW && !CheckProofOfWork(block.GetHash(), block.nBits, consensusParams)) |
|
|
|
return state.DoS(50, false, REJECT_INVALID, "high-hash", false, "proof of work failed"); |
|
|
|
return state.DoS(50, false, REJECT_INVALID, "high-hash", false, "proof of work failed"); |
|
|
|
|
|
|
|
|
|
|
|
// Check timestamp
|
|
|
|
// Check timestamp
|
|
|
|
if (block.GetBlockTime() > GetAdjustedTime() + 2 * 60 * 60) |
|
|
|
if (block.GetBlockTime() > nAdjustedTime + 2 * 60 * 60) |
|
|
|
return state.Invalid(false, REJECT_INVALID, "time-too-new", "block timestamp too far in the future"); |
|
|
|
return state.Invalid(false, REJECT_INVALID, "time-too-new", "block timestamp too far in the future"); |
|
|
|
|
|
|
|
|
|
|
|
return true; |
|
|
|
return true; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bool fCheckMerkleRoot) |
|
|
|
bool CheckBlock(const CBlock& block, CValidationState& state, const Consensus::Params& consensusParams, int64_t nAdjustedTime, bool fCheckPOW, bool fCheckMerkleRoot) |
|
|
|
{ |
|
|
|
{ |
|
|
|
// These are checks that are independent of context.
|
|
|
|
// These are checks that are independent of context.
|
|
|
|
|
|
|
|
|
|
|
@ -3256,7 +3256,7 @@ bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bo |
|
|
|
|
|
|
|
|
|
|
|
// Check that the header is valid (particularly PoW). This is mostly
|
|
|
|
// Check that the header is valid (particularly PoW). This is mostly
|
|
|
|
// redundant with the call in AcceptBlockHeader.
|
|
|
|
// redundant with the call in AcceptBlockHeader.
|
|
|
|
if (!CheckBlockHeader(block, state, fCheckPOW)) |
|
|
|
if (!CheckBlockHeader(block, state, consensusParams, nAdjustedTime, fCheckPOW)) |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
|
|
|
|
|
|
|
|
// Check the merkle root.
|
|
|
|
// Check the merkle root.
|
|
|
@ -3322,9 +3322,8 @@ static bool CheckIndexAgainstCheckpoint(const CBlockIndex* pindexPrev, CValidati |
|
|
|
return true; |
|
|
|
return true; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& state, CBlockIndex * const pindexPrev) |
|
|
|
bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& state, const Consensus::Params& consensusParams, CBlockIndex * const pindexPrev) |
|
|
|
{ |
|
|
|
{ |
|
|
|
const Consensus::Params& consensusParams = Params().GetConsensus(); |
|
|
|
|
|
|
|
// Check proof of work
|
|
|
|
// Check proof of work
|
|
|
|
if (block.nBits != GetNextWorkRequired(pindexPrev, &block, consensusParams)) |
|
|
|
if (block.nBits != GetNextWorkRequired(pindexPrev, &block, consensusParams)) |
|
|
|
return state.DoS(100, false, REJECT_INVALID, "bad-diffbits", false, "incorrect proof of work"); |
|
|
|
return state.DoS(100, false, REJECT_INVALID, "bad-diffbits", false, "incorrect proof of work"); |
|
|
@ -3397,7 +3396,7 @@ static bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state |
|
|
|
return true; |
|
|
|
return true; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (!CheckBlockHeader(block, state)) |
|
|
|
if (!CheckBlockHeader(block, state, chainparams.GetConsensus(), GetAdjustedTime())) |
|
|
|
return error("%s: Consensus::CheckBlockHeader: %s, %s", __func__, hash.ToString(), FormatStateMessage(state)); |
|
|
|
return error("%s: Consensus::CheckBlockHeader: %s, %s", __func__, hash.ToString(), FormatStateMessage(state)); |
|
|
|
|
|
|
|
|
|
|
|
// Get prev block index
|
|
|
|
// Get prev block index
|
|
|
@ -3413,7 +3412,7 @@ static bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state |
|
|
|
if (fCheckpointsEnabled && !CheckIndexAgainstCheckpoint(pindexPrev, state, chainparams, hash)) |
|
|
|
if (fCheckpointsEnabled && !CheckIndexAgainstCheckpoint(pindexPrev, state, chainparams, hash)) |
|
|
|
return error("%s: CheckIndexAgainstCheckpoint(): %s", __func__, state.GetRejectReason().c_str()); |
|
|
|
return error("%s: CheckIndexAgainstCheckpoint(): %s", __func__, state.GetRejectReason().c_str()); |
|
|
|
|
|
|
|
|
|
|
|
if (!ContextualCheckBlockHeader(block, state, pindexPrev)) |
|
|
|
if (!ContextualCheckBlockHeader(block, state, chainparams.GetConsensus(), pindexPrev)) |
|
|
|
return error("%s: Consensus::ContextualCheckBlockHeader: %s, %s", __func__, hash.ToString(), FormatStateMessage(state)); |
|
|
|
return error("%s: Consensus::ContextualCheckBlockHeader: %s, %s", __func__, hash.ToString(), FormatStateMessage(state)); |
|
|
|
} |
|
|
|
} |
|
|
|
if (pindex == NULL) |
|
|
|
if (pindex == NULL) |
|
|
@ -3457,7 +3456,7 @@ static bool AcceptBlock(const CBlock& block, CValidationState& state, const CCha |
|
|
|
if (fTooFarAhead) return true; // Block height is too high
|
|
|
|
if (fTooFarAhead) return true; // Block height is too high
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if ((!CheckBlock(block, state)) || !ContextualCheckBlock(block, state, pindex->pprev)) { |
|
|
|
if ((!CheckBlock(block, state, chainparams.GetConsensus(), GetAdjustedTime())) || !ContextualCheckBlock(block, state, pindex->pprev)) { |
|
|
|
if (state.IsInvalid() && !state.CorruptionPossible()) { |
|
|
|
if (state.IsInvalid() && !state.CorruptionPossible()) { |
|
|
|
pindex->nStatus |= BLOCK_FAILED_VALID; |
|
|
|
pindex->nStatus |= BLOCK_FAILED_VALID; |
|
|
|
setDirtyBlockIndex.insert(pindex); |
|
|
|
setDirtyBlockIndex.insert(pindex); |
|
|
@ -3542,9 +3541,9 @@ bool TestBlockValidity(CValidationState& state, const CChainParams& chainparams, |
|
|
|
indexDummy.nHeight = pindexPrev->nHeight + 1; |
|
|
|
indexDummy.nHeight = pindexPrev->nHeight + 1; |
|
|
|
|
|
|
|
|
|
|
|
// NOTE: CheckBlockHeader is called by CheckBlock
|
|
|
|
// NOTE: CheckBlockHeader is called by CheckBlock
|
|
|
|
if (!ContextualCheckBlockHeader(block, state, pindexPrev)) |
|
|
|
if (!ContextualCheckBlockHeader(block, state, chainparams.GetConsensus(), pindexPrev)) |
|
|
|
return error("%s: Consensus::ContextualCheckBlockHeader: %s", __func__, FormatStateMessage(state)); |
|
|
|
return error("%s: Consensus::ContextualCheckBlockHeader: %s", __func__, FormatStateMessage(state)); |
|
|
|
if (!CheckBlock(block, state, fCheckPOW, fCheckMerkleRoot)) |
|
|
|
if (!CheckBlock(block, state, chainparams.GetConsensus(), GetAdjustedTime(), fCheckPOW, fCheckMerkleRoot)) |
|
|
|
return error("%s: Consensus::CheckBlock: %s", __func__, FormatStateMessage(state)); |
|
|
|
return error("%s: Consensus::CheckBlock: %s", __func__, FormatStateMessage(state)); |
|
|
|
if (!ContextualCheckBlock(block, state, pindexPrev)) |
|
|
|
if (!ContextualCheckBlock(block, state, pindexPrev)) |
|
|
|
return error("%s: Consensus::ContextualCheckBlock: %s", __func__, FormatStateMessage(state)); |
|
|
|
return error("%s: Consensus::ContextualCheckBlock: %s", __func__, FormatStateMessage(state)); |
|
|
@ -3876,7 +3875,7 @@ bool CVerifyDB::VerifyDB(const CChainParams& chainparams, CCoinsView *coinsview, |
|
|
|
if (!ReadBlockFromDisk(block, pindex, chainparams.GetConsensus())) |
|
|
|
if (!ReadBlockFromDisk(block, pindex, chainparams.GetConsensus())) |
|
|
|
return error("VerifyDB(): *** ReadBlockFromDisk failed at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString()); |
|
|
|
return error("VerifyDB(): *** ReadBlockFromDisk failed at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString()); |
|
|
|
// check level 1: verify block validity
|
|
|
|
// check level 1: verify block validity
|
|
|
|
if (nCheckLevel >= 1 && !CheckBlock(block, state)) |
|
|
|
if (nCheckLevel >= 1 && !CheckBlock(block, state, chainparams.GetConsensus(), GetAdjustedTime())) |
|
|
|
return error("%s: *** found bad block at %d, hash=%s (%s)\n", __func__, |
|
|
|
return error("%s: *** found bad block at %d, hash=%s (%s)\n", __func__, |
|
|
|
pindex->nHeight, pindex->GetBlockHash().ToString(), FormatStateMessage(state)); |
|
|
|
pindex->nHeight, pindex->GetBlockHash().ToString(), FormatStateMessage(state)); |
|
|
|
// check level 2: verify undo validity
|
|
|
|
// check level 2: verify undo validity
|
|
|
|