aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFabian Jahr <fjahr@protonmail.com>2024-05-03 10:05:48 +0900
committerFabian Jahr <fjahr@protonmail.com>2024-08-06 01:38:12 +0200
commit6bfa26048dbafb91e9ca63ea8d3960271e798098 (patch)
tree60ee627aa87c784f5b49dc2bb8ba2c07bd402b89
parent0100907ca168c53e8fe044bdda396f308825162c (diff)
testnet: Add timewarp attack prevention for Testnet4
-rw-r--r--src/validation.cpp12
1 files changed, 12 insertions, 0 deletions
diff --git a/src/validation.cpp b/src/validation.cpp
index d8c1c27aae..f7250778fc 100644
--- a/src/validation.cpp
+++ b/src/validation.cpp
@@ -4182,6 +4182,18 @@ static bool ContextualCheckBlockHeader(const CBlockHeader& block, BlockValidatio
if (block.GetBlockTime() <= pindexPrev->GetMedianTimePast())
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
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");