Skip to content

Commit 59ff17e

Browse files
committed
miner: adjust clock to timewarp rule
1 parent e929054 commit 59ff17e

File tree

4 files changed

+24
-15
lines changed

4 files changed

+24
-15
lines changed

src/consensus/consensus.h

+7
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,11 @@ static const size_t MIN_SERIALIZABLE_TRANSACTION_WEIGHT = WITNESS_SCALE_FACTOR *
2727
/** Interpret sequence numbers as relative lock-time constraints. */
2828
static constexpr unsigned int LOCKTIME_VERIFY_SEQUENCE = (1 << 0);
2929

30+
/**
31+
* Maximum number of seconds that the timestamp of the first
32+
* block of a difficulty adjustment period is allowed to
33+
* be earlier than the last block of the previous period (BIP94).
34+
*/
35+
static constexpr int64_t MAX_TIMEWARP = 600;
36+
3037
#endif // BITCOIN_CONSENSUS_CONSENSUS_H

src/node/miner.cpp

+8
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,14 @@ int64_t UpdateTime(CBlockHeader* pblock, const Consensus::Params& consensusParam
3333
int64_t nOldTime = pblock->nTime;
3434
int64_t nNewTime{std::max<int64_t>(pindexPrev->GetMedianTimePast() + 1, TicksSinceEpoch<std::chrono::seconds>(NodeClock::now()))};
3535

36+
if (consensusParams.enforce_BIP94) {
37+
// Height of block to be mined.
38+
const int height{pindexPrev->nHeight + 1};
39+
if (height % consensusParams.DifficultyAdjustmentInterval() == 0) {
40+
nNewTime = std::max<int64_t>(nNewTime, pindexPrev->GetBlockTime() - MAX_TIMEWARP);
41+
}
42+
}
43+
3644
if (nOldTime < nNewTime) {
3745
pblock->nTime = nNewTime;
3846
}

src/validation.cpp

-7
Original file line numberDiff line numberDiff line change
@@ -107,13 +107,6 @@ const std::vector<std::string> CHECKLEVEL_DOC {
107107
* */
108108
static constexpr int PRUNE_LOCK_BUFFER{10};
109109

110-
/**
111-
* Maximum number of seconds that the timestamp of the first
112-
* block of a difficulty adjustment period is allowed to
113-
* be earlier than the last block of the previous period (BIP94).
114-
*/
115-
static constexpr int64_t MAX_TIMEWARP = 600;
116-
117110
GlobalMutex g_best_block_mutex;
118111
std::condition_variable g_best_block_cv;
119112
uint256 g_best_block;

test/functional/mining_basic.py

+9-8
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
from test_framework.test_framework import BitcoinTestFramework
2929
from test_framework.util import (
3030
assert_equal,
31+
assert_greater_than_or_equal,
3132
assert_raises_rpc_error,
3233
get_fee,
3334
)
@@ -139,24 +140,24 @@ def test_timewarp(self):
139140

140141
self.log.info("First block template of retarget period can't use wall clock time")
141142
self.nodes[0].setmocktime(t)
142-
assert_raises_rpc_error(-1, "time-timewarp-attack, block's timestamp is too early on diff adjustment block",
143-
lambda: node.getblocktemplate(NORMAL_GBT_REQUEST_PARAMS))
144-
145-
# Create template with an acceptable timestamp and then modify it
146-
self.nodes[0].setmocktime(t + MAX_FUTURE_BLOCK_TIME)
143+
# The template will have an adjusted timestamp, which we then modify
147144
tmpl = node.getblocktemplate(NORMAL_GBT_REQUEST_PARAMS)
145+
assert_greater_than_or_equal(tmpl['curtime'], t + MAX_FUTURE_BLOCK_TIME - MAX_TIMEWARP)
148146

149147
block = CBlock()
150148
block.nVersion = tmpl["version"]
151149
block.hashPrevBlock = int(tmpl["previousblockhash"], 16)
152-
block.nTime = t
150+
block.nTime = tmpl["curtime"]
153151
block.nBits = int(tmpl["bits"], 16)
154152
block.nNonce = 0
155153
block.vtx = [create_coinbase(height=int(tmpl["height"]))]
156154
block.solve()
155+
assert_template(node, block, None)
157156

158-
self.nodes[0].setmocktime(t)
159-
assert_raises_rpc_error(-25, 'time-timewarp-attack', lambda: node.submitheader(hexdata=CBlockHeader(block).serialize().hex()))
157+
bad_block = copy.deepcopy(block)
158+
bad_block.nTime = t
159+
bad_block.solve()
160+
assert_raises_rpc_error(-25, 'time-timewarp-attack', lambda: node.submitheader(hexdata=CBlockHeader(bad_block).serialize().hex()))
160161

161162
def run_test(self):
162163
node = self.nodes[0]

0 commit comments

Comments
 (0)