From 071354813783768e3dec3b209b539e3d0fd7a1a0 Mon Sep 17 00:00:00 2001 From: Sjors Provoost Date: Fri, 3 Jan 2025 15:23:39 +0100 Subject: [PATCH] refactor: add GetMinimumTime() helper Before bip94 there was an assumption that the minimum permitted timestamp is GetMedianTimePast() + 1. This commit splits a helper function out of UpdateTime() to obtain the minimum time in a way that takes the timewarp attack rule into account. --- src/node/miner.cpp | 23 ++++++++++++++++------- src/node/miner.h | 7 +++++++ 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/src/node/miner.cpp b/src/node/miner.cpp index 1e6f1c53a93..9995adc0d0f 100644 --- a/src/node/miner.cpp +++ b/src/node/miner.cpp @@ -28,16 +28,25 @@ #include namespace node { + +int64_t GetMinimumTime(const CBlockIndex* pindexPrev, const int64_t difficulty_adjustment_interval) +{ + int64_t min_time{pindexPrev->GetMedianTimePast() + 1}; + // Height of block to be mined. + const int height{pindexPrev->nHeight + 1}; + // Account for BIP94 timewarp rule on all networks. This makes future + // activation safer. + if (height % difficulty_adjustment_interval == 0) { + min_time = std::max(min_time, pindexPrev->GetBlockTime() - MAX_TIMEWARP); + } + return min_time; +} + int64_t UpdateTime(CBlockHeader* pblock, const Consensus::Params& consensusParams, const CBlockIndex* pindexPrev) { int64_t nOldTime = pblock->nTime; - int64_t nNewTime{std::max(pindexPrev->GetMedianTimePast() + 1, TicksSinceEpoch(NodeClock::now()))}; - - // Height of block to be mined. - const int height{pindexPrev->nHeight + 1}; - if (height % consensusParams.DifficultyAdjustmentInterval() == 0) { - nNewTime = std::max(nNewTime, pindexPrev->GetBlockTime() - MAX_TIMEWARP); - } + int64_t nNewTime{std::max(GetMinimumTime(pindexPrev, consensusParams.DifficultyAdjustmentInterval()), + TicksSinceEpoch(NodeClock::now()))}; if (nOldTime < nNewTime) { pblock->nTime = nNewTime; diff --git a/src/node/miner.h b/src/node/miner.h index 3c4c66b0bad..5e5d0b25f30 100644 --- a/src/node/miner.h +++ b/src/node/miner.h @@ -211,6 +211,13 @@ private: void SortForBlock(const CTxMemPool::setEntries& package, std::vector& sortedEntries); }; +/** + * Get the minimum time a miner should use in the next block. This always + * accounts for the BIP94 timewarp rule, so does not necessarily reflect the + * consensus limit. + */ +int64_t GetMinimumTime(const CBlockIndex* pindexPrev, const int64_t difficulty_adjustment_interval); + int64_t UpdateTime(CBlockHeader* pblock, const Consensus::Params& consensusParams, const CBlockIndex* pindexPrev); /** Update an old GenerateCoinbaseCommitment from CreateNewBlock after the block txs have changed */