|
|
@ -2719,18 +2719,23 @@ bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bo |
|
|
|
return true; |
|
|
|
return true; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& state, CBlockIndex * const pindexPrev) |
|
|
|
static bool CheckIndexAgainstCheckpoint(const CBlockIndex* pindexPrev, CValidationState& state, const CChainParams& chainparams, const uint256& hash) |
|
|
|
{ |
|
|
|
{ |
|
|
|
const CChainParams& chainParams = Params(); |
|
|
|
if (*pindexPrev->phashBlock == chainparams.GetConsensus().hashGenesisBlock) |
|
|
|
const Consensus::Params& consensusParams = chainParams.GetConsensus(); |
|
|
|
|
|
|
|
uint256 hash = block.GetHash(); |
|
|
|
|
|
|
|
if (hash == consensusParams.hashGenesisBlock) |
|
|
|
|
|
|
|
return true; |
|
|
|
return true; |
|
|
|
|
|
|
|
|
|
|
|
assert(pindexPrev); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int nHeight = pindexPrev->nHeight+1; |
|
|
|
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 ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& state, 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, error("%s: incorrect proof of work", __func__), |
|
|
|
return state.DoS(100, error("%s: incorrect proof of work", __func__), |
|
|
@ -2741,14 +2746,6 @@ bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& sta |
|
|
|
return state.Invalid(error("%s: block's timestamp is too early", __func__), |
|
|
|
return state.Invalid(error("%s: block's timestamp is too early", __func__), |
|
|
|
REJECT_INVALID, "time-too-old"); |
|
|
|
REJECT_INVALID, "time-too-old"); |
|
|
|
|
|
|
|
|
|
|
|
if (fCheckpointsEnabled) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
// 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)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Reject block.nVersion=1 blocks when 95% (75% on testnet) of the network has upgraded:
|
|
|
|
// Reject block.nVersion=1 blocks when 95% (75% on testnet) of the network has upgraded:
|
|
|
|
if (block.nVersion < 2 && IsSuperMajority(2, pindexPrev, consensusParams.nMajorityRejectBlockOutdated, consensusParams)) |
|
|
|
if (block.nVersion < 2 && IsSuperMajority(2, pindexPrev, consensusParams.nMajorityRejectBlockOutdated, consensusParams)) |
|
|
|
return state.Invalid(error("%s: rejected nVersion=1 block", __func__), |
|
|
|
return state.Invalid(error("%s: rejected nVersion=1 block", __func__), |
|
|
@ -2818,6 +2815,9 @@ bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state, CBloc |
|
|
|
if (pindexPrev->nStatus & BLOCK_FAILED_MASK) |
|
|
|
if (pindexPrev->nStatus & BLOCK_FAILED_MASK) |
|
|
|
return state.DoS(100, error("%s: prev block invalid", __func__), REJECT_INVALID, "bad-prevblk"); |
|
|
|
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)) |
|
|
|
if (!ContextualCheckBlockHeader(block, state, pindexPrev)) |
|
|
|
return false; |
|
|
|
return false; |
|
|
@ -2933,8 +2933,11 @@ bool ProcessNewBlock(CValidationState &state, CNode* pfrom, CBlock* pblock, bool |
|
|
|
|
|
|
|
|
|
|
|
bool TestBlockValidity(CValidationState &state, const CBlock& block, CBlockIndex * const pindexPrev, bool fCheckPOW, bool fCheckMerkleRoot) |
|
|
|
bool TestBlockValidity(CValidationState &state, const CBlock& block, CBlockIndex * const pindexPrev, bool fCheckPOW, bool fCheckMerkleRoot) |
|
|
|
{ |
|
|
|
{ |
|
|
|
|
|
|
|
const CChainParams& chainparams = Params(); |
|
|
|
AssertLockHeld(cs_main); |
|
|
|
AssertLockHeld(cs_main); |
|
|
|
assert(pindexPrev == chainActive.Tip()); |
|
|
|
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); |
|
|
|
CCoinsViewCache viewNew(pcoinsTip); |
|
|
|
CBlockIndex indexDummy(block); |
|
|
|
CBlockIndex indexDummy(block); |
|
|
|