actually ended up being pretty easy to remove for a time-based timelock
diff --git a/test/functional/mempool_reorg.py b/test/functional/mempool_reorg.py
index 3906117e8b..0f6124f9ab 100755
--- a/test/functional/mempool_reorg.py
+++ b/test/functional/mempool_reorg.py
@@ -28,5 +28,6 @@ from test_framework.blocktools import (
# Number of blocks to create in temporary blockchain branch for reorg testing
-FORK_LENGTH = 10
+# Needs to be long enough to allow MTP to move arbitrarily forward
+FORK_LENGTH = 20
class MempoolCoinbaseTest(BitcoinTestFramework):
@@ -125,4 +126,8 @@ class MempoolCoinbaseTest(BitcoinTestFramework):
wallet = self.wallet
+ # Prevent clock from moving blocks further forward in time
+ now = int(time.time())
+ self.nodes[0].setmocktime(now)
+
# Start with a 200 block chain
assert_equal(self.nodes[0].getblockcount(), 200)
@@ -148,9 +153,11 @@ class MempoolCoinbaseTest(BitcoinTestFramework):
spend_3 = wallet.create_self_transfer(utxo_to_spend=utxo_3)
- self.log.info("Create another transaction which is time-locked to two blocks in the future")
+ future = now + 300
+
+ self.log.info("Create another transaction which is time-locked to 300 seconds in the future")
utxo = wallet.get_utxo(txid=coinbase_txids[0])
timelock_tx = wallet.create_self_transfer(
utxo_to_spend=utxo,
- locktime=self.nodes[0].getblockcount() + 2,
+ locktime=future,
)['hex']
@@ -174,7 +181,13 @@ class MempoolCoinbaseTest(BitcoinTestFramework):
self.log.info("Generate a block")
- # Prep for fork
+ # Prep for fork, only go FORK_LENGTH seconds into the MTP future max
fork_blocks = create_empty_fork(self.nodes[0], fork_length=FORK_LENGTH)
- self.generate(self.nodes[0], 1)
+
+ # Jump node and MTP 300 seconds and generate a slighty weaker chain than reorg one
+ self.nodes[0].setmocktime(future)
+ self.generate(self.nodes[0], FORK_LENGTH - 1)
+ block_time = self.nodes[0].getblock(self.nodes[0].getbestblockhash())['time']
+ assert(block_time >= now + 300)
+
# generate() implicitly syncs blocks, so that peer 1 gets the block before timelock_tx
# Otherwise, peer 1 would put the timelock_tx in m_lazy_recent_rejects
@@ -193,7 +206,11 @@ class MempoolCoinbaseTest(BitcoinTestFramework):
self.sync_blocks()
+ # We went backwards in time to boot timelock_tx_id
+ fork_block_time = self.nodes[0].getblock(self.nodes[0].getbestblockhash())['time']
+ assert fork_block_time < block_time
+
self.log.info("The time-locked transaction is now too immature and has been removed from the mempool")
self.log.info("spend_3_1 has been re-orged out of the chain and is back in the mempool")
- assert_equal(set(self.nodes[0].getrawmempool()), {spend_1_id, spend_2_1_id, spend_3_1_id, timelock_tx_id})
+ assert_equal(set(self.nodes[0].getrawmempool()), {spend_1_id, spend_2_1_id, spend_3_1_id})
self.log.info("Use invalidateblock to re-org back and make all those coinbase spends immature/invalid")