0
0
Fork 0
mirror of https://github.com/bitcoin/bitcoin.git synced 2025-02-02 09:46:52 -05:00

test: refactor: deduplicate segwitv0 ECDSA signing for tx inputs

Follow-up for #28025.
This commit is contained in:
Sebastian Falbesoner 2023-07-25 22:15:56 +02:00
parent e35fb7bc48
commit 83d7cfd542
2 changed files with 18 additions and 11 deletions

View file

@ -70,9 +70,9 @@ from test_framework.script import (
SIGHASH_ANYONECANPAY, SIGHASH_ANYONECANPAY,
SIGHASH_NONE, SIGHASH_NONE,
SIGHASH_SINGLE, SIGHASH_SINGLE,
SegwitV0SignatureHash,
hash160, hash160,
sign_input_legacy, sign_input_legacy,
sign_input_segwitv0,
) )
from test_framework.script_util import ( from test_framework.script_util import (
key_to_p2pk_script, key_to_p2pk_script,
@ -121,10 +121,8 @@ def subtest(func):
def sign_p2pk_witness_input(script, tx_to, in_idx, hashtype, value, key): def sign_p2pk_witness_input(script, tx_to, in_idx, hashtype, value, key):
"""Add signature for a P2PK witness script.""" """Add signature for a P2PK witness script."""
tx_hash = SegwitV0SignatureHash(script, tx_to, in_idx, hashtype, value) tx_to.wit.vtxinwit[in_idx].scriptWitness.stack = [script]
signature = key.sign_ecdsa(tx_hash) + chr(hashtype).encode('latin-1') sign_input_segwitv0(tx_to, in_idx, script, value, key, hashtype)
tx_to.wit.vtxinwit[in_idx].scriptWitness.stack = [signature, script]
tx_to.rehash()
def test_transaction_acceptance(node, p2p, tx, with_witness, accepted, reason=None): def test_transaction_acceptance(node, p2p, tx, with_witness, accepted, reason=None):
"""Send a transaction to the node and check that it's accepted to the mempool """Send a transaction to the node and check that it's accepted to the mempool
@ -1476,11 +1474,9 @@ class SegWitTest(BitcoinTestFramework):
tx2.vin.append(CTxIn(COutPoint(tx.sha256, 0), b"")) tx2.vin.append(CTxIn(COutPoint(tx.sha256, 0), b""))
tx2.vout.append(CTxOut(tx.vout[0].nValue - 1000, script_wsh)) tx2.vout.append(CTxOut(tx.vout[0].nValue - 1000, script_wsh))
script = keyhash_to_p2pkh_script(pubkeyhash) script = keyhash_to_p2pkh_script(pubkeyhash)
sig_hash = SegwitV0SignatureHash(script, tx2, 0, SIGHASH_ALL, tx.vout[0].nValue)
signature = key.sign_ecdsa(sig_hash) + b'\x01' # 0x1 is SIGHASH_ALL
tx2.wit.vtxinwit.append(CTxInWitness()) tx2.wit.vtxinwit.append(CTxInWitness())
tx2.wit.vtxinwit[0].scriptWitness.stack = [signature, pubkey] tx2.wit.vtxinwit[0].scriptWitness.stack = [pubkey]
tx2.rehash() sign_input_segwitv0(tx2, 0, script, tx.vout[0].nValue, key)
# Should fail policy test. # Should fail policy test.
test_transaction_acceptance(self.nodes[0], self.test_node, tx2, True, False, 'non-mandatory-script-verify-flag (Using non-compressed keys in segwit)') test_transaction_acceptance(self.nodes[0], self.test_node, tx2, True, False, 'non-mandatory-script-verify-flag (Using non-compressed keys in segwit)')
@ -1676,11 +1672,13 @@ class SegWitTest(BitcoinTestFramework):
tx2.vout.append(CTxOut(tx.vout[0].nValue, CScript([OP_TRUE]))) tx2.vout.append(CTxOut(tx.vout[0].nValue, CScript([OP_TRUE])))
script = keyhash_to_p2pkh_script(pubkeyhash) script = keyhash_to_p2pkh_script(pubkeyhash)
sig_hash = SegwitV0SignatureHash(script, tx2, 0, SIGHASH_ALL, tx.vout[0].nValue) tx2.wit.vtxinwit.append(CTxInWitness())
signature = key.sign_ecdsa(sig_hash) + b'\x01' # 0x1 is SIGHASH_ALL sign_input_segwitv0(tx2, 0, script, tx.vout[0].nValue, key)
signature = tx2.wit.vtxinwit[0].scriptWitness.stack.pop()
# Check that we can't have a scriptSig # Check that we can't have a scriptSig
tx2.vin[0].scriptSig = CScript([signature, pubkey]) tx2.vin[0].scriptSig = CScript([signature, pubkey])
tx2.rehash()
block = self.build_next_block() block = self.build_next_block()
self.update_witness_block_with_transactions(block, [tx, tx2]) self.update_witness_block_with_transactions(block, [tx, tx2])
test_witness_block(self.nodes[0], self.test_node, block, accepted=False, test_witness_block(self.nodes[0], self.test_node, block, accepted=False,

View file

@ -699,6 +699,15 @@ def sign_input_legacy(tx, input_index, input_scriptpubkey, privkey, sighash_type
tx.vin[input_index].scriptSig = bytes(CScript([der_sig + bytes([sighash_type])])) + tx.vin[input_index].scriptSig tx.vin[input_index].scriptSig = bytes(CScript([der_sig + bytes([sighash_type])])) + tx.vin[input_index].scriptSig
tx.rehash() tx.rehash()
def sign_input_segwitv0(tx, input_index, input_scriptpubkey, input_amount, privkey, sighash_type=SIGHASH_ALL):
"""Add segwitv0 ECDSA signature for a given transaction input. Note that the signature
is inserted at the bottom of the witness stack, i.e. additional witness data
needed (e.g. pubkey for P2WPKH) can already be set before."""
sighash = SegwitV0SignatureHash(input_scriptpubkey, tx, input_index, sighash_type, input_amount)
der_sig = privkey.sign_ecdsa(sighash)
tx.wit.vtxinwit[input_index].scriptWitness.stack.insert(0, der_sig + bytes([sighash_type]))
tx.rehash()
# TODO: Allow cached hashPrevouts/hashSequence/hashOutputs to be provided. # TODO: Allow cached hashPrevouts/hashSequence/hashOutputs to be provided.
# Performance optimization probably not necessary for python tests, however. # Performance optimization probably not necessary for python tests, however.
# Note that this corresponds to sigversion == 1 in EvalScript, which is used # Note that this corresponds to sigversion == 1 in EvalScript, which is used