diff --git a/test/functional/mempool_accept.py b/test/functional/mempool_accept.py index ee9ca9204..57a059b7f 100755 --- a/test/functional/mempool_accept.py +++ b/test/functional/mempool_accept.py @@ -92,7 +92,7 @@ class MempoolAcceptanceTest(BitcoinTestFramework): tx.deserialize(BytesIO(hex_str_to_bytes(raw_tx_0))) txid_0 = tx.rehash() self.check_mempool_result( - result_expected=[{'txid': txid_0, 'allowed': True, 'vsize': 110, 'fees': {'base': Decimal(str(fee))}}], + result_expected=[{'txid': txid_0, 'allowed': True, 'vsize': tx.get_vsize(), 'fees': {'base': Decimal(str(fee))}}], rawtxs=[raw_tx_0], ) @@ -107,7 +107,7 @@ class MempoolAcceptanceTest(BitcoinTestFramework): tx.deserialize(BytesIO(hex_str_to_bytes(raw_tx_final))) fee_expected = int(coin['amount']) - output_amount self.check_mempool_result( - result_expected=[{'txid': tx.rehash(), 'allowed': True, 'vsize': 188, 'fees': {'base': Decimal(str(fee_expected))}}], + result_expected=[{'txid': tx.rehash(), 'allowed': True, 'vsize': tx.get_vsize(), 'fees': {'base': Decimal(str(fee_expected))}}], rawtxs=[tx.serialize().hex()], maxfeerate=0, ) @@ -130,7 +130,7 @@ class MempoolAcceptanceTest(BitcoinTestFramework): tx.deserialize(BytesIO(hex_str_to_bytes(raw_tx_0))) txid_0 = tx.rehash() self.check_mempool_result( - result_expected=[{'txid': txid_0, 'allowed': True, 'vsize': 110, 'fees': {'base': Decimal(str(2 * fee))}}], + result_expected=[{'txid': txid_0, 'allowed': True, 'vsize': tx.get_vsize(), 'fees': {'base': Decimal(str(2 * fee))}}], rawtxs=[raw_tx_0], ) @@ -190,7 +190,7 @@ class MempoolAcceptanceTest(BitcoinTestFramework): tx.deserialize(BytesIO(hex_str_to_bytes(raw_tx_reference))) # Reference tx should be valid on itself self.check_mempool_result( - result_expected=[{'txid': tx.rehash(), 'allowed': True, 'vsize': 110, 'fees': { 'base': Decimal(str(0.1 - 0.05))}}], + result_expected=[{'txid': tx.rehash(), 'allowed': True, 'vsize': tx.get_vsize(), 'fees': { 'base': Decimal(str(0.1 - 0.05))}}], rawtxs=[tx.serialize().hex()], maxfeerate=0, ) diff --git a/test/functional/p2p_segwit.py b/test/functional/p2p_segwit.py index 1d99761e1..dfbf5d52f 100755 --- a/test/functional/p2p_segwit.py +++ b/test/functional/p2p_segwit.py @@ -696,13 +696,13 @@ class SegWitTest(BitcoinTestFramework): if not self.segwit_active: # Just check mempool acceptance, but don't add the transaction to the mempool, since witness is disallowed # in blocks and the tx is impossible to mine right now. - assert_equal(self.nodes[0].testmempoolaccept([tx3.serialize_with_witness().hex()]), [{'txid': tx3.hash, 'allowed': True, 'vsize': 93, 'fees': { 'base': Decimal('0.00001000')}}]) + assert_equal(self.nodes[0].testmempoolaccept([tx3.serialize_with_witness().hex()]), [{'txid': tx3.hash, 'allowed': True, 'vsize': tx3.get_vsize(), 'fees': { 'base': Decimal('0.00001000')}}]) # Create the same output as tx3, but by replacing tx tx3_out = tx3.vout[0] tx3 = tx tx3.vout = [tx3_out] tx3.rehash() - assert_equal(self.nodes[0].testmempoolaccept([tx3.serialize_with_witness().hex()]), [{'txid': tx3.hash, 'allowed': True, 'vsize': 93, 'fees': { 'base': Decimal('0.00011000')}}]) + assert_equal(self.nodes[0].testmempoolaccept([tx3.serialize_with_witness().hex()]), [{'txid': tx3.hash, 'allowed': True, 'vsize': tx3.get_vsize(), 'fees': { 'base': Decimal('0.00011000')}}]) test_transaction_acceptance(self.nodes[0], self.test_node, tx3, with_witness=True, accepted=True) self.nodes[0].generate(1) diff --git a/test/functional/test_framework/messages.py b/test/functional/test_framework/messages.py index b4e609df3..1e062ab9a 100755 --- a/test/functional/test_framework/messages.py +++ b/test/functional/test_framework/messages.py @@ -22,6 +22,7 @@ from codecs import encode import copy import hashlib from io import BytesIO +import math import random import socket import struct @@ -67,6 +68,8 @@ MSG_WITNESS_TX = MSG_TX | MSG_WITNESS_FLAG FILTER_TYPE_BASIC = 0 +WITNESS_SCALE_FACTOR = 4 + # Serialization/deserialization tools def sha256(s): return hashlib.new('sha256', s).digest() @@ -537,6 +540,13 @@ class CTransaction: return False return True + # Calculate the virtual transaction size using witness and non-witness + # serialization size (does NOT use sigops). + def get_vsize(self): + with_witness_size = len(self.serialize_with_witness()) + without_witness_size = len(self.serialize_without_witness()) + return math.ceil(((WITNESS_SCALE_FACTOR - 1) * without_witness_size + with_witness_size) / WITNESS_SCALE_FACTOR) + def __repr__(self): return "CTransaction(nVersion=%i vin=%s vout=%s wit=%s nLockTime=%i)" \ % (self.nVersion, repr(self.vin), repr(self.vout), repr(self.wit), self.nLockTime)