Skip to content

Commit ce024b1

Browse files
committed
test: MiniWallet: force P2PK signature to have fixed size (71 bytes)
In order to enable exact fee calculation for transactions that spend P2PK outputs in the MiniWallet, we enforce the created signatures to have a fixed length (>49.89% probability) by default. With that it is easier to check the created transactions vsize and avoid flaky tests that would appear whenever the signatures R- or S-values are smaller (due to leading zero bytes). Note that to get the total scriptSig size one has to add another 2 bytes, as there is also the OP_PUSHx instruction on the front and the sighash type byte on the back, leading to a final scriptSig size of 73 bytes.
1 parent 82bc7fa commit ce024b1

File tree

1 file changed

+10
-2
lines changed

1 file changed

+10
-2
lines changed

test/functional/test_framework/wallet.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,12 +88,20 @@ def scan_tx(self, tx):
8888
if out['scriptPubKey']['hex'] == self._scriptPubKey.hex():
8989
self._utxos.append({'txid': tx['txid'], 'vout': out['n'], 'value': out['value']})
9090

91-
def sign_tx(self, tx):
91+
def sign_tx(self, tx, fixed_length=True):
9292
"""Sign tx that has been created by MiniWallet in P2PK mode"""
9393
assert self._priv_key is not None
9494
(sighash, err) = LegacySignatureHash(CScript(self._scriptPubKey), tx, 0, SIGHASH_ALL)
9595
assert err is None
96-
tx.vin[0].scriptSig = CScript([self._priv_key.sign_ecdsa(sighash) + bytes(bytearray([SIGHASH_ALL]))])
96+
# for exact fee calculation, create only signatures with fixed size by default (>49.89% probability):
97+
# 65 bytes: high-R val (33 bytes) + low-S val (32 bytes)
98+
# with the DER header/skeleton data of 6 bytes added, this leads to a target size of 71 bytes
99+
der_sig = b''
100+
while not len(der_sig) == 71:
101+
der_sig = self._priv_key.sign_ecdsa(sighash)
102+
if not fixed_length:
103+
break
104+
tx.vin[0].scriptSig = CScript([der_sig + bytes(bytearray([SIGHASH_ALL]))])
97105

98106
def generate(self, num_blocks):
99107
"""Generate blocks with coinbase outputs to the internal address, and append the outputs to the internal list"""

0 commit comments

Comments
 (0)