Skip to content

Commit 8a04a38

Browse files
committed
tests: Calculate input weight more accurately
The external input test with specifying input weight would make a pessimistic estimate of the input weight. However this would result in a test failure as it is sometimes too pessimistic when an ECDSA signature ends up being smaller than usual. To correct this, we can calculate the input weight more accurately.
1 parent 2529007 commit 8a04a38

File tree

2 files changed

+16
-6
lines changed

2 files changed

+16
-6
lines changed

test/functional/rpc_psbt.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@
1010

1111
from test_framework.descriptors import descsum_create
1212
from test_framework.key import ECKey
13+
from test_framework.messages import (
14+
ser_compact_size,
15+
WITNESS_SCALE_FACTOR,
16+
)
1317
from test_framework.test_framework import BitcoinTestFramework
1418
from test_framework.util import (
1519
assert_approx,
@@ -655,10 +659,11 @@ def test_psbt_input_keys(psbt_input, keys):
655659
break
656660
psbt_in = dec["inputs"][input_idx]
657661
# Calculate the input weight
658-
# (prevout + sequence + length of scriptSig + 2 bytes buffer) * 4 + len of scriptwitness
662+
# (prevout + sequence + length of scriptSig + scriptsig + 1 byte buffer) * WITNESS_SCALE_FACTOR + num scriptWitness stack items + (length of stack item + stack item) * N stack items + 1 byte buffer
659663
len_scriptsig = len(psbt_in["final_scriptSig"]["hex"]) // 2 if "final_scriptSig" in psbt_in else 0
660-
len_scriptwitness = len(psbt_in["final_scriptwitness"]["hex"]) // 2 if "final_scriptwitness" in psbt_in else 0
661-
input_weight = ((41 + len_scriptsig + 2) * 4) + len_scriptwitness
664+
len_scriptsig += len(ser_compact_size(len_scriptsig)) + 1
665+
len_scriptwitness = (sum([(len(x) // 2) + len(ser_compact_size(len(x) // 2)) for x in psbt_in["final_scriptwitness"]]) + len(psbt_in["final_scriptwitness"]) + 1) if "final_scriptwitness" in psbt_in else 0
666+
input_weight = ((40 + len_scriptsig) * WITNESS_SCALE_FACTOR) + len_scriptwitness
662667
low_input_weight = input_weight // 2
663668
high_input_weight = input_weight * 2
664669

test/functional/wallet_send.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@
1010
from test_framework.authproxy import JSONRPCException
1111
from test_framework.descriptors import descsum_create
1212
from test_framework.key import ECKey
13+
from test_framework.messages import (
14+
ser_compact_size,
15+
WITNESS_SCALE_FACTOR,
16+
)
1317
from test_framework.test_framework import BitcoinTestFramework
1418
from test_framework.util import (
1519
assert_equal,
@@ -526,10 +530,11 @@ def run_test(self):
526530
break
527531
psbt_in = dec["inputs"][input_idx]
528532
# Calculate the input weight
529-
# (prevout + sequence + length of scriptSig + 2 bytes buffer) * 4 + len of scriptwitness
533+
# (prevout + sequence + length of scriptSig + scriptsig + 1 byte buffer) * WITNESS_SCALE_FACTOR + num scriptWitness stack items + (length of stack item + stack item) * N stack items + 1 byte buffer
530534
len_scriptsig = len(psbt_in["final_scriptSig"]["hex"]) // 2 if "final_scriptSig" in psbt_in else 0
531-
len_scriptwitness = len(psbt_in["final_scriptwitness"]["hex"]) // 2 if "final_scriptwitness" in psbt_in else 0
532-
input_weight = ((41 + len_scriptsig + 2) * 4) + len_scriptwitness
535+
len_scriptsig += len(ser_compact_size(len_scriptsig)) + 1
536+
len_scriptwitness = (sum([(len(x) // 2) + len(ser_compact_size(len(x) // 2)) for x in psbt_in["final_scriptwitness"]]) + len(psbt_in["final_scriptwitness"]) + 1) if "final_scriptwitness" in psbt_in else 0
537+
input_weight = ((40 + len_scriptsig) * WITNESS_SCALE_FACTOR) + len_scriptwitness
533538

534539
# Input weight error conditions
535540
assert_raises_rpc_error(

0 commit comments

Comments
 (0)