|
|
@ -4182,6 +4182,18 @@ static bool ContextualCheckBlockHeader(const CBlockHeader& block, BlockValidatio
|
|
|
|
if (block.GetBlockTime() <= pindexPrev->GetMedianTimePast())
|
|
|
|
if (block.GetBlockTime() <= pindexPrev->GetMedianTimePast())
|
|
|
|
return state.Invalid(BlockValidationResult::BLOCK_INVALID_HEADER, "time-too-old", "block's timestamp is too early");
|
|
|
|
return state.Invalid(BlockValidationResult::BLOCK_INVALID_HEADER, "time-too-old", "block's timestamp is too early");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Testnet4 only: Check timestamp against prev for difficulty-adjustment
|
|
|
|
|
|
|
|
// blocks to prevent timewarp attacks (see https://github.com/bitcoin/bitcoin/pull/15482).
|
|
|
|
|
|
|
|
if (consensusParams.enforce_BIP94) {
|
|
|
|
|
|
|
|
// Check timestamp for the first block of each difficulty adjustment
|
|
|
|
|
|
|
|
// interval, except the genesis block.
|
|
|
|
|
|
|
|
if (nHeight % consensusParams.DifficultyAdjustmentInterval() == 0) {
|
|
|
|
|
|
|
|
if (block.GetBlockTime() < pindexPrev->GetBlockTime() - 60 * 60 * 2) {
|
|
|
|
|
|
|
|
return state.Invalid(BlockValidationResult::BLOCK_INVALID_HEADER, "time-timewarp-attack", "block's timestamp is too early on diff adjustment block");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Check timestamp
|
|
|
|
// Check timestamp
|
|
|
|
if (block.Time() > NodeClock::now() + std::chrono::seconds{MAX_FUTURE_BLOCK_TIME}) {
|
|
|
|
if (block.Time() > NodeClock::now() + std::chrono::seconds{MAX_FUTURE_BLOCK_TIME}) {
|
|
|
|
return state.Invalid(BlockValidationResult::BLOCK_TIME_FUTURE, "time-too-new", "block timestamp too far in the future");
|
|
|
|
return state.Invalid(BlockValidationResult::BLOCK_TIME_FUTURE, "time-too-new", "block timestamp too far in the future");
|
|
|
|