test: introduce and use calculate_input_weight helper

Rather than manually estimating an input's weight by adding up all the
involved components (fixed-size skeleton, compact-serialized lengths,
and the actual scriptSig / witness stack items) we can simply take use
of the serialization classes `CTxIn` / `CTxInWitness` instead, to
achieve the same with significantly less code.

The new helper is used in the functional tests rpc_psbt.py and
wallet_send.py, where the previous manual estimation code was
duplicated.
This commit is contained in:
Sebastian Falbesoner
2024-04-01 14:03:35 +02:00
parent 61de64df67
commit f81fad5e0f
3 changed files with 29 additions and 29 deletions

View File

@@ -9,10 +9,6 @@ from itertools import product
from test_framework.authproxy import JSONRPCException
from test_framework.descriptors import descsum_create
from test_framework.messages import (
ser_compact_size,
WITNESS_SCALE_FACTOR,
)
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import (
assert_equal,
@@ -21,7 +17,10 @@ from test_framework.util import (
assert_raises_rpc_error,
count_bytes,
)
from test_framework.wallet_util import generate_keypair
from test_framework.wallet_util import (
calculate_input_weight,
generate_keypair,
)
class WalletSendTest(BitcoinTestFramework):
@@ -543,17 +542,9 @@ class WalletSendTest(BitcoinTestFramework):
input_idx = i
break
psbt_in = dec["inputs"][input_idx]
# Calculate the input weight
# (prevout + sequence + length of scriptSig + scriptsig) * WITNESS_SCALE_FACTOR + len of num scriptWitness stack items + (length of stack item + stack item) * N stack items
# Note that occasionally this weight estimate may be slightly larger or smaller than the real weight
# as sometimes ECDSA signatures are one byte shorter than expected with a probability of 1/128
len_scriptsig = len(psbt_in["final_scriptSig"]["hex"]) // 2 if "final_scriptSig" in psbt_in else 0
len_scriptsig += len(ser_compact_size(len_scriptsig))
len_scriptwitness = (sum([(len(x) // 2) + len(ser_compact_size(len(x) // 2)) for x in psbt_in["final_scriptwitness"]]) + len(ser_compact_size(len(psbt_in["final_scriptwitness"])))) if "final_scriptwitness" in psbt_in else 0
len_prevout_txid = 32
len_prevout_index = 4
len_sequence = 4
input_weight = ((len_prevout_txid + len_prevout_index + len_sequence + len_scriptsig) * WITNESS_SCALE_FACTOR) + len_scriptwitness
scriptsig_hex = psbt_in["final_scriptSig"]["hex"] if "final_scriptSig" in psbt_in else ""
witness_stack_hex = psbt_in["final_scriptwitness"] if "final_scriptwitness" in psbt_in else None
input_weight = calculate_input_weight(scriptsig_hex, witness_stack_hex)
# Input weight error conditions
assert_raises_rpc_error(