test: extract `bulk_vout` from `bulk_tx` so it can be used by wallet tests
What changed, and why it matters
This commit is a simple code cleanup in Bitcoin Core's test framework. It moves a helper function called bulk_vout from one test-only file to another so it can be reused by wallet tests. There is no change to the actual Bitcoin network code, consensus rules, or wallet logic that real users run.
No action required. This is a test-framework refactoring with no security relevance.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The change extracts the bulk_vout padding helper from MiniWallet.bulk_tx in test/functional/test_framework/wallet.py into a standalone function in test/functional/test_framework/script_util.py. The original wallet.py method now imports and calls bulk_vout. The logic is identical: append a zero-value OP_RETURN output and pad it with OP_1 bytes until the transaction reaches a target virtual size. Imports are adjusted accordingly (ser_compact_size and assert_equal move to script_util.py; OP_1 and ser_compact_size removed from wallet.py).
Changed components
test/functional/test_framework/script_util.pytest/functional/test_framework/wallet.pyInspect captured patch +16 / −12
diff --git a/test/functional/test_framework/script_util.py b/test/functional/test_framework/script_util.py
index 97578579..5736eb6b 100755
--- a/test/functional/test_framework/script_util.py
+++ b/test/functional/test_framework/script_util.py
@@ -13,6 +13,7 @@ from test_framework.messages import (
CTxIn,
CTxInWitness,
CTxOut,
+ ser_compact_size,
sha256,
)
from test_framework.script import (
@@ -35,6 +36,8 @@ from test_framework.script import (
hash160,
)
+from test_framework.util import assert_equal
+
# Maximum number of potentially executed legacy signature operations in validating a transaction.
MAX_STD_LEGACY_SIGOPS = 2_500
@@ -128,6 +131,16 @@ def script_to_p2sh_p2wsh_script(script):
p2shscript = CScript([OP_0, sha256(script)])
return script_to_p2sh_script(p2shscript)
+def bulk_vout(tx, target_vsize):
+ if target_vsize < tx.get_vsize():
+ raise RuntimeError(f"target_vsize {target_vsize} is less than transaction virtual size {tx.get_vsize()}")
+ # determine number of needed padding bytes
+ dummy_vbytes = target_vsize - tx.get_vsize()
+ # compensate for the increase of the compact-size encoded script length
+ # (note that the length encoding of the unpadded output script needs one byte)
+ dummy_vbytes -= len(ser_compact_size(dummy_vbytes)) - 1
+ tx.vout[-1].scriptPubKey = CScript([OP_RETURN] + [OP_1] * dummy_vbytes)
+ assert_equal(tx.get_vsize(), target_vsize)
def output_key_to_p2tr_script(key):
assert len(key) == 32
diff --git a/test/functional/test_framework/wallet.py b/test/functional/test_framework/wallet.py
index ab462f79..a47ccab0 100644
--- a/test/functional/test_framework/wallet.py
+++ b/test/functional/test_framework/wallet.py
@@ -33,11 +33,9 @@ from test_framework.messages import (
CTxInWitness,
CTxOut,
hash256,
- ser_compact_size,
)
from test_framework.script import (
CScript,
- OP_1,
OP_NOP,
OP_RETURN,
OP_TRUE,
@@ -45,6 +43,7 @@ from test_framework.script import (
taproot_construct,
)
from test_framework.script_util import (
+ bulk_vout,
key_to_p2pk_script,
key_to_p2pkh_script,
key_to_p2sh_p2wpkh_script,
@@ -121,17 +120,9 @@ class MiniWallet:
"""Pad a transaction with extra outputs until it reaches a target vsize.
returns the tx
"""
- if target_vsize < tx.get_vsize():
- raise RuntimeError(f"target_vsize {target_vsize} is less than transaction virtual size {tx.get_vsize()}")
-
tx.vout.append(CTxOut(nValue=0, scriptPubKey=CScript([OP_RETURN])))
- # determine number of needed padding bytes
- dummy_vbytes = target_vsize - tx.get_vsize()
- # compensate for the increase of the compact-size encoded script length
- # (note that the length encoding of the unpadded output script needs one byte)
- dummy_vbytes -= len(ser_compact_size(dummy_vbytes)) - 1
- tx.vout[-1].scriptPubKey = CScript([OP_RETURN] + [OP_1] * dummy_vbytes)
- assert_equal(tx.get_vsize(), target_vsize)
+ bulk_vout(tx, target_vsize)
+
def get_balance(self):
return sum(u['value'] for u in self._utxos)
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.