test: avoid unneeded hash -> uint256 -> hash roundtrips

In the functional test framework, we often treat hashes
as uint256 integers, which seems to be confusing and for no
good reason, as hashes are just sequences of bytes. This commit
gets rid of obvious internal instances of that where individual
functional tests are not affected. In the long-term, it might make
sense to store other hashes (mostly txids) as actual bytes to
avoid annoying conversions and improve code readability.
This commit is contained in:
Sebastian Falbesoner 2025-03-12 20:16:04 +01:00
parent aa68ed27b8
commit 346a099fc1
2 changed files with 13 additions and 15 deletions

View file

@ -28,7 +28,6 @@ from .messages import (
ser_uint256, ser_uint256,
tx_from_hex, tx_from_hex,
uint256_from_compact, uint256_from_compact,
uint256_from_str,
WITNESS_SCALE_FACTOR, WITNESS_SCALE_FACTOR,
) )
from .script import ( from .script import (
@ -111,8 +110,8 @@ def create_block(hashprev=None, coinbase=None, ntime=None, *, version=None, tmpl
return block return block
def get_witness_script(witness_root, witness_nonce): def get_witness_script(witness_root, witness_nonce):
witness_commitment = uint256_from_str(hash256(ser_uint256(witness_root) + ser_uint256(witness_nonce))) witness_commitment = hash256(ser_uint256(witness_root) + ser_uint256(witness_nonce))
output_data = WITNESS_COMMITMENT_HEADER + ser_uint256(witness_commitment) output_data = WITNESS_COMMITMENT_HEADER + witness_commitment
return CScript([OP_RETURN, output_data]) return CScript([OP_RETURN, output_data])
def add_witness_commitment(block, nonce=0): def add_witness_commitment(block, nonce=0):

View file

@ -17,9 +17,7 @@ from .messages import (
CTxOut, CTxOut,
hash256, hash256,
ser_string, ser_string,
ser_uint256,
sha256, sha256,
uint256_from_str,
) )
from .crypto.ripemd160 import ripemd160 from .crypto.ripemd160 import ripemd160
@ -711,41 +709,42 @@ def sign_input_segwitv0(tx, input_index, input_scriptpubkey, input_amount, privk
# Note that this corresponds to sigversion == 1 in EvalScript, which is used # Note that this corresponds to sigversion == 1 in EvalScript, which is used
# for version 0 witnesses. # for version 0 witnesses.
def SegwitV0SignatureMsg(script, txTo, inIdx, hashtype, amount): def SegwitV0SignatureMsg(script, txTo, inIdx, hashtype, amount):
ZERO_HASH = bytes([0]*32)
hashPrevouts = 0 hashPrevouts = ZERO_HASH
hashSequence = 0 hashSequence = ZERO_HASH
hashOutputs = 0 hashOutputs = ZERO_HASH
if not (hashtype & SIGHASH_ANYONECANPAY): if not (hashtype & SIGHASH_ANYONECANPAY):
serialize_prevouts = bytes() serialize_prevouts = bytes()
for i in txTo.vin: for i in txTo.vin:
serialize_prevouts += i.prevout.serialize() serialize_prevouts += i.prevout.serialize()
hashPrevouts = uint256_from_str(hash256(serialize_prevouts)) hashPrevouts = hash256(serialize_prevouts)
if (not (hashtype & SIGHASH_ANYONECANPAY) and (hashtype & 0x1f) != SIGHASH_SINGLE and (hashtype & 0x1f) != SIGHASH_NONE): if (not (hashtype & SIGHASH_ANYONECANPAY) and (hashtype & 0x1f) != SIGHASH_SINGLE and (hashtype & 0x1f) != SIGHASH_NONE):
serialize_sequence = bytes() serialize_sequence = bytes()
for i in txTo.vin: for i in txTo.vin:
serialize_sequence += i.nSequence.to_bytes(4, "little") serialize_sequence += i.nSequence.to_bytes(4, "little")
hashSequence = uint256_from_str(hash256(serialize_sequence)) hashSequence = hash256(serialize_sequence)
if ((hashtype & 0x1f) != SIGHASH_SINGLE and (hashtype & 0x1f) != SIGHASH_NONE): if ((hashtype & 0x1f) != SIGHASH_SINGLE and (hashtype & 0x1f) != SIGHASH_NONE):
serialize_outputs = bytes() serialize_outputs = bytes()
for o in txTo.vout: for o in txTo.vout:
serialize_outputs += o.serialize() serialize_outputs += o.serialize()
hashOutputs = uint256_from_str(hash256(serialize_outputs)) hashOutputs = hash256(serialize_outputs)
elif ((hashtype & 0x1f) == SIGHASH_SINGLE and inIdx < len(txTo.vout)): elif ((hashtype & 0x1f) == SIGHASH_SINGLE and inIdx < len(txTo.vout)):
serialize_outputs = txTo.vout[inIdx].serialize() serialize_outputs = txTo.vout[inIdx].serialize()
hashOutputs = uint256_from_str(hash256(serialize_outputs)) hashOutputs = hash256(serialize_outputs)
ss = bytes() ss = bytes()
ss += txTo.version.to_bytes(4, "little") ss += txTo.version.to_bytes(4, "little")
ss += ser_uint256(hashPrevouts) ss += hashPrevouts
ss += ser_uint256(hashSequence) ss += hashSequence
ss += txTo.vin[inIdx].prevout.serialize() ss += txTo.vin[inIdx].prevout.serialize()
ss += ser_string(script) ss += ser_string(script)
ss += amount.to_bytes(8, "little", signed=True) ss += amount.to_bytes(8, "little", signed=True)
ss += txTo.vin[inIdx].nSequence.to_bytes(4, "little") ss += txTo.vin[inIdx].nSequence.to_bytes(4, "little")
ss += ser_uint256(hashOutputs) ss += hashOutputs
ss += txTo.nLockTime.to_bytes(4, "little") ss += txTo.nLockTime.to_bytes(4, "little")
ss += hashtype.to_bytes(4, "little") ss += hashtype.to_bytes(4, "little")
return ss return ss