Merge 357e3f6aa4 into merged_master (Bitcoin PR bitcoin/bitcoin#28025)

This commit is contained in:
Byron Hambly 2025-07-01 12:06:50 +02:00
commit 36e84e800e
4 changed files with 24 additions and 25 deletions

View file

@ -43,8 +43,7 @@ from test_framework.script import (
OP_INVALIDOPCODE,
OP_RETURN,
OP_TRUE,
SIGHASH_ALL,
LegacySignatureHash,
sign_input_legacy,
)
from test_framework.script_util import (
script_to_p2sh_script,
@ -548,12 +547,8 @@ class FullBlockTest(BitcoinTestFramework):
tx.vin.append(CTxIn(COutPoint(b39.vtx[i].sha256, 0), b''))
tx.vout.append(CTxOut(b39.vtx[i].vout[0].nValue.getAmount())) # fee
# Note: must pass the redeem_script (not p2sh_script) to the signature hash function
(sighash, err) = LegacySignatureHash(redeem_script, tx, 1, SIGHASH_ALL)
sig = self.coinbase_key.sign_ecdsa(sighash) + bytes(bytearray([SIGHASH_ALL]))
scriptSig = CScript([sig, redeem_script])
tx.vin[1].scriptSig = scriptSig
tx.rehash()
tx.vin[1].scriptSig = CScript([redeem_script])
sign_input_legacy(tx, 1, redeem_script, self.coinbase_key)
new_txs.append(tx)
lastOutpoint = COutPoint(tx.sha256, 0)
@ -1377,8 +1372,7 @@ class FullBlockTest(BitcoinTestFramework):
if (scriptPubKey[0] == OP_TRUE): # an anyone-can-spend
tx.vin[0].scriptSig = CScript()
return
(sighash, err) = LegacySignatureHash(spend_tx.vout[0].scriptPubKey, tx, 0, SIGHASH_ALL)
tx.vin[0].scriptSig = CScript([self.coinbase_key.sign_ecdsa(sighash) + bytes(bytearray([SIGHASH_ALL]))])
sign_input_legacy(tx, 0, spend_tx.vout[0].scriptPubKey, self.coinbase_key)
def create_and_sign_transaction(self, spend_tx, value, script=CScript([OP_TRUE])):
tx = self.create_tx(spend_tx, 0, value, script)

View file

@ -74,8 +74,8 @@ from test_framework.script import (
SIGHASH_NONE,
SIGHASH_SINGLE,
SegwitV0SignatureHash,
LegacySignatureHash,
hash160,
sign_input_legacy,
)
from test_framework.script_util import (
key_to_p2pk_script,
@ -1576,10 +1576,8 @@ class SegWitTest(BitcoinTestFramework):
tx5.vin.append(CTxIn(COutPoint(tx4.sha256, 0), b""))
tx5.vout.append(CTxOut(tx4.vout[0].nValue.getAmount() - 1000, CScript([OP_TRUE])))
tx5.vout.append(CTxOut(1000)) # fee
(sig_hash, err) = LegacySignatureHash(script_pubkey, tx5, 0, SIGHASH_ALL)
signature = key.sign_ecdsa(sig_hash) + b'\x01' # 0x1 is SIGHASH_ALL
tx5.vin[0].scriptSig = CScript([signature, pubkey])
tx5.rehash()
tx5.vin[0].scriptSig = CScript([pubkey])
sign_input_legacy(tx5, 0, script_pubkey, key)
# Should pass policy and consensus.
test_transaction_acceptance(self.nodes[0], self.test_node, tx5, True, True)
block = self.build_next_block()

View file

@ -815,6 +815,16 @@ def LegacySignatureHash(*args, **kwargs):
else:
return (hash256(msg), err)
def sign_input_legacy(tx, input_index, input_scriptpubkey, privkey, sighash_type=SIGHASH_ALL):
"""Add legacy ECDSA signature for a given transaction input. Note that the signature
is prepended to the scriptSig field, i.e. additional data pushes necessary for more
complex spends than P2PK (e.g. pubkey for P2PKH) can be already set before."""
(sighash, err) = LegacySignatureHash(input_scriptpubkey, tx, input_index, sighash_type)
assert err is None
der_sig = privkey.sign_ecdsa(sighash)
tx.vin[input_index].scriptSig = bytes(CScript([der_sig + bytes([sighash_type])])) + tx.vin[input_index].scriptSig
tx.rehash()
# TODO: Allow cached hashPrevouts/hashSequence/hashOutputs to be provided.
# Performance optimization probably not necessary for python tests, however.
# Note that this corresponds to sigversion == 1 in EvalScript, which is used

View file

@ -37,12 +37,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 (
@ -168,18 +167,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