core/sign_tx: Explicitly pass script to write_tx_input() instead of setting it in txi.

pull/985/head
Andrew Kozlik 4 years ago committed by Andrew Kozlik
parent 04bdf1dc6c
commit 9f9618944a

@ -246,9 +246,8 @@ class Bitcoin:
node = self.keychain.derive(txi.address_n, self.coin.curve_name)
key_sign_pub = node.public_key()
txi.script_sig = self.input_derive_script(txi, key_sign_pub)
self.write_tx_input(self.serialized_tx, txi)
script_sig = self.input_derive_script(txi, key_sign_pub)
self.write_tx_input(self.serialized_tx, txi, script_sig)
def sign_bip143_input(self, txi: TxInputType) -> Tuple[bytes, bytes]:
self.wallet_path.check_input(txi)
@ -317,14 +316,14 @@ class Bitcoin:
# if multisig, do a sanity check to ensure we are signing with a key that is included in the multisig
if txi.multisig:
multisig.multisig_pubkey_index(txi.multisig, key_sign_pub)
# for the signing process the script_sig is equal
# to the previous tx's scriptPubKey (P2PKH) or a redeem script (P2SH)
# For the signing process the previous UTXO's scriptPubKey is included in h_sign.
if txi.script_type == InputScriptType.SPENDMULTISIG:
txi.script_sig = scripts.output_script_multisig(
script_pubkey = scripts.output_script_multisig(
multisig.multisig_get_pubkeys(txi.multisig), txi.multisig.m,
)
elif txi.script_type == InputScriptType.SPENDADDRESS:
txi.script_sig = scripts.output_script_p2pkh(
script_pubkey = scripts.output_script_p2pkh(
addresses.ecdsa_hash_pubkey(key_sign_pub, self.coin)
)
else:
@ -333,8 +332,8 @@ class Bitcoin:
)
txi_sign = txi
else:
txi.script_sig = bytes()
self.write_tx_input(h_sign, txi)
script_pubkey = bytes()
self.write_tx_input(h_sign, txi, script_pubkey)
writers.write_varint(h_sign, self.tx.outputs_count)
@ -363,10 +362,8 @@ class Bitcoin:
# serialize input with correct signature
gc.collect()
txi_sign.script_sig = self.input_derive_script(
txi_sign, key_sign_pub, signature
)
self.write_tx_input(self.serialized_tx, txi_sign)
script_sig = self.input_derive_script(txi_sign, key_sign_pub, signature)
self.write_tx_input(self.serialized_tx, txi_sign, script_sig)
self.set_serialized_signature(i_sign, signature)
async def serialize_output(self, i: int) -> None:
@ -397,7 +394,7 @@ class Bitcoin:
for i in range(tx.inputs_cnt):
# STAGE_REQUEST_2_PREV_INPUT
txi = await helpers.request_tx_input(self.tx_req, i, self.coin, prev_hash)
self.write_tx_input(txh, txi)
self.write_tx_input(txh, txi, txi.script_sig)
writers.write_varint(txh, tx.outputs_cnt)
@ -433,8 +430,10 @@ class Bitcoin:
def get_hash_type(self) -> int:
return _SIGHASH_ALL
def write_tx_input(self, w: writers.Writer, txi: TxInputType) -> None:
writers.write_tx_input(w, txi)
def write_tx_input(
self, w: writers.Writer, txi: TxInputType, script: bytes
) -> None:
writers.write_tx_input(w, txi, script)
def write_tx_output(self, w: writers.Writer, txo_bin: TxOutputBinType) -> None:
writers.write_tx_output(w, txo_bin)

@ -43,8 +43,8 @@ class Bitcoinlike(Bitcoin):
# serialize input with correct signature
gc.collect()
txi.script_sig = self.input_derive_script(txi, public_key, signature)
self.write_tx_input(self.serialized_tx, txi)
script_sig = self.input_derive_script(txi, public_key, signature)
self.write_tx_input(self.serialized_tx, txi, script_sig)
self.set_serialized_signature(i_sign, signature)
async def sign_nonsegwit_input(self, i_sign: int) -> None:

@ -56,7 +56,7 @@ class Decred(Bitcoin):
await super().process_input(txi)
# Decred serializes inputs early.
self.write_tx_input(self.serialized_tx, txi)
self.write_tx_input(self.serialized_tx, txi, bytes())
async def confirm_output(self, txo: TxOutputType, txo_bin: TxOutputBinType) -> None:
if txo.decred_script_version != 0:
@ -122,11 +122,10 @@ class Decred(Bitcoin):
# serialize input with correct signature
gc.collect()
txi_sign.script_sig = self.input_derive_script(
txi_sign, key_sign_pub, signature
script_sig = self.input_derive_script(txi_sign, key_sign_pub, signature)
writers.write_tx_input_decred_witness(
self.serialized_tx, txi_sign, script_sig
)
writers.write_tx_input_decred_witness(self.serialized_tx, txi_sign)
self.set_serialized_signature(i_sign, signature)
async def step5_serialize_outputs(self) -> None:
@ -151,7 +150,9 @@ class Decred(Bitcoin):
def hash143_add_output(self, txo_bin: TxOutputBinType) -> None:
writers.write_tx_output_decred(self.h_prefix, txo_bin)
def write_tx_input(self, w: writers.Writer, txi: TxInputType) -> None:
def write_tx_input(
self, w: writers.Writer, txi: TxInputType, script: bytes
) -> None:
writers.write_tx_input_decred(w, txi)
def write_tx_output(self, w: writers.Writer, txo_bin: TxOutputBinType) -> None:

@ -32,10 +32,10 @@ def write_bytes_prefixed(w: Writer, b: bytes) -> None:
write_bytes_unchecked(w, b)
def write_tx_input(w: Writer, i: TxInputType) -> None:
def write_tx_input(w: Writer, i: TxInputType, script: bytes) -> None:
write_bytes_reversed(w, i.prev_hash, TX_HASH_SIZE)
write_uint32(w, i.prev_index)
write_bytes_prefixed(w, i.script_sig)
write_bytes_prefixed(w, script)
write_uint32(w, i.sequence)
@ -57,11 +57,11 @@ def write_tx_input_decred(w: Writer, i: TxInputType) -> None:
write_uint32(w, i.sequence)
def write_tx_input_decred_witness(w: Writer, i: TxInputType) -> None:
def write_tx_input_decred_witness(w: Writer, i: TxInputType, script_sig: bytes) -> None:
write_uint64(w, i.amount or 0)
write_uint32(w, 0) # block height fraud proof
write_uint32(w, 0xFFFFFFFF) # block index fraud proof
write_bytes_prefixed(w, i.script_sig)
write_bytes_prefixed(w, script_sig)
def write_tx_output(w: Writer, o: TxOutputBinType) -> None:

@ -22,12 +22,12 @@ class TestWriters(unittest.TestCase):
)
b = bytearray()
writers.write_tx_input(b, inp)
writers.write_tx_input(b, inp, inp.script_sig)
self.assertEqual(len(b), 32 + 4 + 1 + 10 + 4)
for bad_prevhash in (b"", b"x", b"hello", b"x" * 33):
inp.prev_hash = bad_prevhash
self.assertRaises(AssertionError, writers.write_tx_input, b, inp)
self.assertRaises(AssertionError, writers.write_tx_input, b, inp, inp.script_sig)
def test_tx_input_check(self):
inp = TxInputType(

Loading…
Cancel
Save