mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-03-10 09:06:15 +01:00
Add timewarp attack mitigation test
This commit is contained in:
parent
e85f386c4b
commit
e929054e12
1 changed files with 44 additions and 0 deletions
|
@ -34,6 +34,9 @@ from test_framework.util import (
|
||||||
from test_framework.wallet import MiniWallet
|
from test_framework.wallet import MiniWallet
|
||||||
|
|
||||||
|
|
||||||
|
DIFFICULTY_ADJUSTMENT_INTERVAL = 144
|
||||||
|
MAX_FUTURE_BLOCK_TIME = 2 * 3600
|
||||||
|
MAX_TIMEWARP = 600
|
||||||
VERSIONBITS_TOP_BITS = 0x20000000
|
VERSIONBITS_TOP_BITS = 0x20000000
|
||||||
VERSIONBITS_DEPLOYMENT_TESTDUMMY_BIT = 28
|
VERSIONBITS_DEPLOYMENT_TESTDUMMY_BIT = 28
|
||||||
DEFAULT_BLOCK_MIN_TX_FEE = 1000 # default `-blockmintxfee` setting [sat/kvB]
|
DEFAULT_BLOCK_MIN_TX_FEE = 1000 # default `-blockmintxfee` setting [sat/kvB]
|
||||||
|
@ -115,6 +118,46 @@ class MiningTest(BitcoinTestFramework):
|
||||||
assert tx_below_min_feerate['txid'] not in block_template_txids
|
assert tx_below_min_feerate['txid'] not in block_template_txids
|
||||||
assert tx_below_min_feerate['txid'] not in block_txids
|
assert tx_below_min_feerate['txid'] not in block_txids
|
||||||
|
|
||||||
|
def test_timewarp(self):
|
||||||
|
self.log.info("Test timewarp attack mitigation (BIP94)")
|
||||||
|
node = self.nodes[0]
|
||||||
|
|
||||||
|
self.log.info("Mine until the last block of the retarget period")
|
||||||
|
blockchain_info = self.nodes[0].getblockchaininfo()
|
||||||
|
n = DIFFICULTY_ADJUSTMENT_INTERVAL - blockchain_info['blocks'] % DIFFICULTY_ADJUSTMENT_INTERVAL - 2
|
||||||
|
t = blockchain_info['time']
|
||||||
|
|
||||||
|
for _ in range(n):
|
||||||
|
t += 600
|
||||||
|
self.nodes[0].setmocktime(t)
|
||||||
|
self.generate(self.wallet, 1, sync_fun=self.no_op)
|
||||||
|
|
||||||
|
self.log.info("Create block two hours in the future")
|
||||||
|
self.nodes[0].setmocktime(t + MAX_FUTURE_BLOCK_TIME)
|
||||||
|
self.generate(self.wallet, 1, sync_fun=self.no_op)
|
||||||
|
assert_equal(node.getblock(node.getbestblockhash())['time'], t + MAX_FUTURE_BLOCK_TIME)
|
||||||
|
|
||||||
|
self.log.info("First block template of retarget period can't use wall clock time")
|
||||||
|
self.nodes[0].setmocktime(t)
|
||||||
|
assert_raises_rpc_error(-1, "time-timewarp-attack, block's timestamp is too early on diff adjustment block",
|
||||||
|
lambda: node.getblocktemplate(NORMAL_GBT_REQUEST_PARAMS))
|
||||||
|
|
||||||
|
# Create template with an acceptable timestamp and then modify it
|
||||||
|
self.nodes[0].setmocktime(t + MAX_FUTURE_BLOCK_TIME)
|
||||||
|
tmpl = node.getblocktemplate(NORMAL_GBT_REQUEST_PARAMS)
|
||||||
|
|
||||||
|
block = CBlock()
|
||||||
|
block.nVersion = tmpl["version"]
|
||||||
|
block.hashPrevBlock = int(tmpl["previousblockhash"], 16)
|
||||||
|
block.nTime = t
|
||||||
|
block.nBits = int(tmpl["bits"], 16)
|
||||||
|
block.nNonce = 0
|
||||||
|
block.vtx = [create_coinbase(height=int(tmpl["height"]))]
|
||||||
|
block.solve()
|
||||||
|
|
||||||
|
self.nodes[0].setmocktime(t)
|
||||||
|
assert_raises_rpc_error(-25, 'time-timewarp-attack', lambda: node.submitheader(hexdata=CBlockHeader(block).serialize().hex()))
|
||||||
|
|
||||||
def run_test(self):
|
def run_test(self):
|
||||||
node = self.nodes[0]
|
node = self.nodes[0]
|
||||||
self.wallet = MiniWallet(node)
|
self.wallet = MiniWallet(node)
|
||||||
|
@ -322,6 +365,7 @@ class MiningTest(BitcoinTestFramework):
|
||||||
assert_equal(node.submitblock(hexdata=block.serialize().hex()), 'duplicate') # valid
|
assert_equal(node.submitblock(hexdata=block.serialize().hex()), 'duplicate') # valid
|
||||||
|
|
||||||
self.test_blockmintxfee_parameter()
|
self.test_blockmintxfee_parameter()
|
||||||
|
self.test_timewarp()
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|
Loading…
Add table
Reference in a new issue