test: introduce and use CTransaction .wtxid_int property

This commits removes the `.calc_sha256` method from the CTransaction
and introduces a property `.wtxid_int` property as replacement.
This commit is contained in:
Sebastian Falbesoner
2025-05-04 23:30:41 +02:00
parent 9b3dce24a3
commit e9cdaefb0a
5 changed files with 14 additions and 14 deletions

View File

@@ -365,7 +365,7 @@ class CompactBlocksTest(BitcoinTestFramework):
# Already checked prefilled transactions above
header_and_shortids.prefilled_txn.pop(0)
else:
tx_hash = block.vtx[index].calc_sha256(True)
tx_hash = block.vtx[index].wtxid_int
shortid = calculate_shortid(k0, k1, tx_hash)
assert_equal(shortid, header_and_shortids.shortids[0])
header_and_shortids.shortids.pop(0)
@@ -395,7 +395,7 @@ class CompactBlocksTest(BitcoinTestFramework):
comp_block.header = CBlockHeader(block)
comp_block.nonce = 0
[k0, k1] = comp_block.get_siphash_keys()
coinbase_hash = block.vtx[0].calc_sha256(True)
coinbase_hash = block.vtx[0].wtxid_int
comp_block.shortids = [calculate_shortid(k0, k1, coinbase_hash)]
test_node.send_and_ping(msg_cmpctblock(comp_block.to_p2p()))
assert_equal(int(node.getbestblockhash(), 16), block.hashPrevBlock)

View File

@@ -174,7 +174,7 @@ class TestP2PConn(P2PInterface):
with p2p_lock:
self.last_message.pop("getdata", None)
if use_wtxid:
wtxid = tx.calc_sha256(True)
wtxid = tx.wtxid_int
self.send_without_ping(msg_inv(inv=[CInv(MSG_WTX, wtxid)]))
else:
self.send_without_ping(msg_inv(inv=[CInv(MSG_TX, tx.sha256)]))
@@ -1979,7 +1979,7 @@ class SegWitTest(BitcoinTestFramework):
self.wtx_node.announce_tx_and_wait_for_getdata(tx2, use_wtxid=True)
with p2p_lock:
lgd = self.wtx_node.lastgetdata[:]
assert_equal(lgd, [CInv(MSG_WTX, tx2.calc_sha256(True))])
assert_equal(lgd, [CInv(MSG_WTX, tx2.wtxid_int)])
# Announce Segwit transaction from non wtxidrelay peer
# and wait for getdata

View File

@@ -71,7 +71,7 @@ class TxPrivacyTest(BitcoinTestFramework):
# Spy should only get an inv for the second transaction as the first
# one was received pre-verack with the spy
spy.wait_for_inv_match(CInv(MSG_WTX, tx2.calc_sha256(True)))
spy.wait_for_inv_match(CInv(MSG_WTX, tx2.wtxid_int))
if __name__ == '__main__':
TxPrivacyTest(__file__).main()

View File

@@ -107,7 +107,7 @@ def create_block(hashprev=None, coinbase=None, ntime=None, *, version=None, tmpl
block.vtx.append(coinbase)
if txlist:
for tx in txlist:
if not hasattr(tx, 'calc_sha256'):
if type(tx) is str:
tx = tx_from_hex(tx)
block.vtx.append(tx)
block.hashMerkleRoot = block.calc_merkle_root()

View File

@@ -658,8 +658,14 @@ class CTransaction:
return self.serialize_with_witness()
def getwtxid(self):
"""Return wtxid (transaction hash with witness) as hex string."""
return hash256(self.serialize())[::-1].hex()
@property
def wtxid_int(self):
"""Return wtxid (transaction hash with witness) as integer."""
return uint256_from_str(hash256(self.serialize_with_witness()))
@property
def hash(self):
"""Return txid (transaction hash without witness) as hex string."""
@@ -675,12 +681,6 @@ class CTransaction:
def rehash(self):
return self.hash
# TODO: get rid of this method, replace call-sites by .wtxid_int access (not introduced yet)
def calc_sha256(self, with_witness=False):
if with_witness:
# Don't cache the result, just return it
return uint256_from_str(hash256(self.serialize_with_witness()))
def is_valid(self):
for tout in self.vout:
if tout.nValue < 0 or tout.nValue > 21000000 * COIN:
@@ -819,7 +819,7 @@ class CBlock(CBlockHeader):
for tx in self.vtx[1:]:
# Calculate the hashes with witness data
hashes.append(ser_uint256(tx.calc_sha256(True)))
hashes.append(ser_uint256(tx.wtxid_int))
return self.get_merkle_root(hashes)
@@ -1003,7 +1003,7 @@ class HeaderAndShortIDs:
if i not in prefill_list:
tx_hash = block.vtx[i].sha256
if use_witness:
tx_hash = block.vtx[i].calc_sha256(with_witness=True)
tx_hash = block.vtx[i].wtxid_int
self.shortids.append(calculate_shortid(k0, k1, tx_hash))
def __repr__(self):