mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-11-26 14:00:29 +01:00
test: refactor: deduplicate legacy ECDSA signing for tx inputs
There are several instances in functional tests and the framework
(MiniWallet, feature_block.py, p2p_segwit.py) where we create a legacy
ECDSA signature for a certain transaction's input by doing the following
steps:
1) calculate the `LegacySignatureHash` with the desired sighash type
2) create the actual digital signature by calling `ECKey.sign_ecdsa`
on the signature message hash calculated above
3) put the DER-encoded result as CScript data push into
tx input's scriptSig
Create a new helper `sign_input_legacy` which hides those details and
takes only the necessary parameters (tx, input index, relevant
scriptPubKey, private key, sighash type [SIGHASH_ALL by default]). For
further convenience, the signature is prepended to already existing
data-pushes in scriptSig, in order to avoid rehashing the transaction
after calling the new signing function.
This commit is contained in:
@@ -36,12 +36,11 @@ from test_framework.messages import (
|
||||
)
|
||||
from test_framework.script import (
|
||||
CScript,
|
||||
LegacySignatureHash,
|
||||
LEAF_VERSION_TAPSCRIPT,
|
||||
OP_NOP,
|
||||
OP_RETURN,
|
||||
OP_TRUE,
|
||||
SIGHASH_ALL,
|
||||
sign_input_legacy,
|
||||
taproot_construct,
|
||||
)
|
||||
from test_framework.script_util import (
|
||||
@@ -166,18 +165,16 @@ class MiniWallet:
|
||||
|
||||
def sign_tx(self, tx, fixed_length=True):
|
||||
if self._mode == MiniWalletMode.RAW_P2PK:
|
||||
(sighash, err) = LegacySignatureHash(CScript(self._scriptPubKey), tx, 0, SIGHASH_ALL)
|
||||
assert err is None
|
||||
# for exact fee calculation, create only signatures with fixed size by default (>49.89% probability):
|
||||
# 65 bytes: high-R val (33 bytes) + low-S val (32 bytes)
|
||||
# with the DER header/skeleton data of 6 bytes added, this leads to a target size of 71 bytes
|
||||
der_sig = b''
|
||||
while not len(der_sig) == 71:
|
||||
der_sig = self._priv_key.sign_ecdsa(sighash)
|
||||
# with the DER header/skeleton data of 6 bytes added, plus 2 bytes scriptSig overhead
|
||||
# (OP_PUSHn and SIGHASH_ALL), this leads to a scriptSig target size of 73 bytes
|
||||
tx.vin[0].scriptSig = b''
|
||||
while not len(tx.vin[0].scriptSig) == 73:
|
||||
tx.vin[0].scriptSig = b''
|
||||
sign_input_legacy(tx, 0, self._scriptPubKey, self._priv_key)
|
||||
if not fixed_length:
|
||||
break
|
||||
tx.vin[0].scriptSig = CScript([der_sig + bytes(bytearray([SIGHASH_ALL]))])
|
||||
tx.rehash()
|
||||
elif self._mode == MiniWalletMode.RAW_OP_TRUE:
|
||||
for i in tx.vin:
|
||||
i.scriptSig = CScript([OP_NOP] * 43) # pad to identical size
|
||||
|
||||
Reference in New Issue
Block a user