test: Require named arg for create_block ntime arg
What changed, and why it matters
This is a test-only code cleanup. It changes how test scripts call a helper function named create_block so that the timestamp argument must be passed by its keyword name (ntime=...) rather than as a plain positional number. This makes the tests easier to read and prevents developers from accidentally swapping the height and timestamp arguments, but it does not change Bitcoin Core's production code or network behavior at all.
No security action needed. Treat as ordinary test-code refactoring.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The commit modifies test_framework/blocktools.py to make the ntime parameter of create_block keyword-only by moving it after the * separator in the function signature. It then updates all functional-test call sites to pass ntime as a named argument. In mining_template_verification.py and p2p_fingerprint.py it also switches from passing an explicit coinbase transaction to using the helper’s built-in height parameter. No consensus, networking, wallet, or RPC code is touched.
Changed components
test/functional/test_framework/blocktools.pytest/functional/feature_assumevalid.pytest/functional/feature_block.pytest/functional/feature_coinstatsindex.pytest/functional/feature_taproot.pytest/functional/mining_template_verification.pytest/functional/p2p_fingerprint.pytest/functional/p2p_invalid_block.pytest/functional/rpc_blockchain.pytest/functional/rpc_getchaintips.pyInspect captured patch +21 / −24
diff --git a/test/functional/feature_assumevalid.py b/test/functional/feature_assumevalid.py
index 7a1fe13c..426c79d9 100755
--- a/test/functional/feature_assumevalid.py
+++ b/test/functional/feature_assumevalid.py
@@ -91,7 +91,7 @@ class AssumeValidTest(BitcoinTestFramework):
# Create the first block with a coinbase output to our key
height = 1
- block = create_block(self.tip, create_coinbase(height, coinbase_pubkey), self.block_time)
+ block = create_block(self.tip, create_coinbase(height, coinbase_pubkey), ntime=self.block_time)
self.blocks.append(block)
self.block_time += 1
block.solve()
diff --git a/test/functional/feature_block.py b/test/functional/feature_block.py
index 6803bb33..5600eeec 100755
--- a/test/functional/feature_block.py
+++ b/test/functional/feature_block.py
@@ -1374,12 +1374,12 @@ class FullBlockTest(BitcoinTestFramework):
for additional_script in additional_output_scripts:
coinbase.vout.append(CTxOut(0, additional_script))
if spend is None:
- block = create_block(base_block_hash, coinbase, block_time, version=version)
+ block = create_block(base_block_hash, coinbase, ntime=block_time, version=version)
else:
coinbase.vout[0].nValue += spend.vout[0].nValue - 1 # all but one satoshi to fees
tx = self.create_tx(spend, 0, 1, output_script=script) # spend 1 satoshi
self.sign_tx(tx, spend)
- block = create_block(base_block_hash, coinbase, block_time, version=version, txlist=[tx])
+ block = create_block(base_block_hash, coinbase, ntime=block_time, version=version, txlist=[tx])
# Block is created. Find a valid nonce.
block.solve()
self.tip = block
diff --git a/test/functional/feature_coinstatsindex.py b/test/functional/feature_coinstatsindex.py
index 05efb525..729c4db8 100755
--- a/test/functional/feature_coinstatsindex.py
+++ b/test/functional/feature_coinstatsindex.py
@@ -194,7 +194,7 @@ class CoinStatsIndexTest(BitcoinTestFramework):
# Generate a block that includes previous coinbase
tip = self.nodes[0].getbestblockhash()
block_time = self.nodes[0].getblock(tip)['time'] + 1
- block = create_block(int(tip, 16), cb, block_time)
+ block = create_block(int(tip, 16), cb, ntime=block_time)
block.solve()
self.nodes[0].submitblock(block.serialize().hex())
self.sync_all()
diff --git a/test/functional/feature_taproot.py b/test/functional/feature_taproot.py
index b2d1d0f5..eb3bb86e 100755
--- a/test/functional/feature_taproot.py
+++ b/test/functional/feature_taproot.py
@@ -1425,7 +1425,7 @@ class TaprootTest(BitcoinTestFramework):
extra_output_script = CScript(bytes([OP_CHECKSIG]*((MAX_BLOCK_SIGOPS_WEIGHT - sigops_weight) // WITNESS_SCALE_FACTOR)))
coinbase_tx = create_coinbase(self.lastblockheight + 1, pubkey=cb_pubkey, extra_output_script=extra_output_script, fees=fees)
- block = create_block(self.tip, coinbase_tx, self.lastblocktime + 1, txlist=txs)
+ block = create_block(self.tip, coinbase_tx, ntime=self.lastblocktime + 1, txlist=txs)
witness and add_witness_commitment(block)
block.solve()
block_response = node.submitblock(block.serialize().hex())
diff --git a/test/functional/mining_template_verification.py b/test/functional/mining_template_verification.py
index 2087aff4..a30fd960 100755
--- a/test/functional/mining_template_verification.py
+++ b/test/functional/mining_template_verification.py
@@ -13,7 +13,6 @@ import copy
from test_framework.blocktools import (
create_block,
- create_coinbase,
add_witness_commitment,
)
@@ -183,8 +182,8 @@ class MiningTemplateVerificationTest(BitcoinTestFramework):
block_3 = create_block(
int(block_2_hash, 16),
- create_coinbase(block_0_height + 3),
- block_1["mediantime"] + 1,
+ height=block_0_height + 3,
+ ntime=block_1["mediantime"] + 1,
txlist=[tx["hex"]],
)
assert_equal(len(block_3.vtx), 2)
@@ -211,8 +210,8 @@ class MiningTemplateVerificationTest(BitcoinTestFramework):
)
block_3 = create_block(
int(block_2_hash, 16),
- create_coinbase(block_0_height + 3),
- block_1["mediantime"] + 1,
+ height=block_0_height + 3,
+ ntime=block_1["mediantime"] + 1,
txlist=[bad_tx_hex],
)
assert_equal(len(block_3.vtx), 2)
@@ -239,8 +238,8 @@ class MiningTemplateVerificationTest(BitcoinTestFramework):
)
block_3 = create_block(
int(block_2_hash, 16),
- create_coinbase(block_0_height + 3),
- block_1["mediantime"] + 1,
+ height=block_0_height + 3,
+ ntime=block_1["mediantime"] + 1,
txlist=[tx_hex, tx_2_hex],
)
assert_equal(len(block_3.vtx), 3)
@@ -269,8 +268,8 @@ class MiningTemplateVerificationTest(BitcoinTestFramework):
block_1 = node.getblock(node.getbestblockhash())
block_2 = create_block(
int(block_1["hash"], 16),
- create_coinbase(block_0_height + 2),
- block_1["mediantime"] + 1,
+ height=block_0_height + 2,
+ ntime=block_1["mediantime"] + 1,
)
self.valid_block_test(node, block_2)
diff --git a/test/functional/p2p_fingerprint.py b/test/functional/p2p_fingerprint.py
index 0d97a161..d847c732 100755
--- a/test/functional/p2p_fingerprint.py
+++ b/test/functional/p2p_fingerprint.py
@@ -10,7 +10,7 @@ the node should pretend that it does not have it to avoid fingerprinting.
import time
-from test_framework.blocktools import (create_block, create_coinbase)
+from test_framework.blocktools import create_block
from test_framework.messages import CInv, MSG_BLOCK
from test_framework.p2p import (
P2PInterface,
@@ -35,15 +35,13 @@ class P2PFingerprintTest(BitcoinTestFramework):
def build_chain(self, nblocks, prev_hash, prev_height, prev_median_time):
blocks = []
for _ in range(nblocks):
- coinbase = create_coinbase(prev_height + 1)
- block_time = prev_median_time + 1
- block = create_block(int(prev_hash, 16), coinbase, block_time)
+ block = create_block(int(prev_hash, 16), height=prev_height + 1, ntime=prev_median_time + 1)
block.solve()
blocks.append(block)
prev_hash = block.hash_hex
prev_height += 1
- prev_median_time = block_time
+ prev_median_time += 1
return blocks
# Send a getdata request for a given block hash
diff --git a/test/functional/p2p_invalid_block.py b/test/functional/p2p_invalid_block.py
index 86568f70..2e712a43 100755
--- a/test/functional/p2p_invalid_block.py
+++ b/test/functional/p2p_invalid_block.py
@@ -99,7 +99,7 @@ class InvalidBlockRequestTest(BitcoinTestFramework):
self.log.info("Test very broken block.")
- block3 = create_block(tip, create_coinbase(height, nValue=100), block_time)
+ block3 = create_block(tip, create_coinbase(height, nValue=100), ntime=block_time)
block_time += 1
block3.solve()
diff --git a/test/functional/rpc_blockchain.py b/test/functional/rpc_blockchain.py
index 9ae00745..bf7c7d11 100755
--- a/test/functional/rpc_blockchain.py
+++ b/test/functional/rpc_blockchain.py
@@ -741,7 +741,7 @@ class BlockchainTest(BitcoinTestFramework):
self.log.info("Test getblock when only header is known")
current_height = node.getblock(node.getbestblockhash())['height']
block_time = node.getblock(node.getbestblockhash())['time'] + 1
- block = create_block(int(blockhash, 16), create_coinbase(current_height + 1, nValue=100), block_time)
+ block = create_block(int(blockhash, 16), create_coinbase(current_height + 1, nValue=100), ntime=block_time)
block.solve()
node.submitheader(block.serialize().hex())
assert_raises_rpc_error(-1, "Block not available (not fully downloaded)", lambda: node.getblock(block.hash_hex))
@@ -749,7 +749,7 @@ class BlockchainTest(BitcoinTestFramework):
self.log.info("Test getblock when block data is available but undo data isn't")
# Submits a block building on the header-only block, so it can't be connected and has no undo data
tx = create_tx_with_script(block.vtx[0], 0, script_sig=bytes([OP_TRUE]), amount=50 * COIN)
- block_noundo = create_block(block.hash_int, create_coinbase(current_height + 2, nValue=100), block_time + 1, txlist=[tx])
+ block_noundo = create_block(block.hash_int, create_coinbase(current_height + 2, nValue=100), ntime=block_time + 1, txlist=[tx])
block_noundo.solve()
node.submitblock(block_noundo.serialize().hex())
diff --git a/test/functional/rpc_getchaintips.py b/test/functional/rpc_getchaintips.py
index cdaacda3..f2e31fe1 100755
--- a/test/functional/rpc_getchaintips.py
+++ b/test/functional/rpc_getchaintips.py
@@ -69,7 +69,7 @@ class GetChainTipsTest (BitcoinTestFramework):
start_height = self.nodes[0].getblockcount()
# Create invalid block (too high coinbase)
block_time = n0.getblock(n0.getbestblockhash())['time'] + 1
- invalid_block = create_block(tip, create_coinbase(start_height+1, nValue=100), block_time)
+ invalid_block = create_block(tip, create_coinbase(start_height + 1, nValue=100), ntime=block_time)
invalid_block.solve()
block_time += 1
diff --git a/test/functional/test_framework/blocktools.py b/test/functional/test_framework/blocktools.py
index 00e599d9..0a393d89 100644
--- a/test/functional/test_framework/blocktools.py
+++ b/test/functional/test_framework/blocktools.py
@@ -95,7 +95,7 @@ def nbits_str(nbits):
def target_str(target):
return f"{target:064x}"
-def create_block(hashprev=None, coinbase=None, ntime=None, *, height=None, version=None, tmpl=None, txlist=None):
+def create_block(hashprev=None, coinbase=None, *, ntime=None, height=None, version=None, tmpl=None, txlist=None):
"""Create a block (with regtest difficulty)."""
block = CBlock()
if tmpl is None:
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.