1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-12-22 06:18:07 +00:00

core/sign_tx: Rework transaction footer writing.

This commit is contained in:
Andrew Kozlik 2020-04-24 16:09:41 +02:00 committed by Andrew Kozlik
parent b60f267da9
commit be39f271b0
3 changed files with 36 additions and 32 deletions

View File

@ -187,7 +187,7 @@ class Bitcoin:
self.serialized_tx.append(0) self.serialized_tx.append(0)
async def step7_finish(self) -> None: async def step7_finish(self) -> None:
self.write_sign_tx_footer(self.serialized_tx) self.write_tx_footer(self.serialized_tx, self.tx)
await helpers.request_tx_finish(self.tx_req) await helpers.request_tx_finish(self.tx_req)
async def process_input(self, i: int, txi: TxInputType) -> None: async def process_input(self, i: int, txi: TxInputType) -> None:
@ -433,9 +433,6 @@ class Bitcoin:
def write_tx_input(self, w: writers.Writer, txi: TxInputType) -> None: def write_tx_input(self, w: writers.Writer, txi: TxInputType) -> None:
writers.write_tx_input(w, txi) writers.write_tx_input(w, txi)
def write_sign_tx_footer(self, w: writers.Writer) -> None:
writers.write_uint32(w, self.tx.lock_time)
def write_tx_header( def write_tx_header(
self, w: writers.Writer, tx: Union[SignTx, TransactionType], has_segwit: bool self, w: writers.Writer, tx: Union[SignTx, TransactionType], has_segwit: bool
) -> None: ) -> None:
@ -444,10 +441,15 @@ class Bitcoin:
writers.write_varint(w, 0x00) # segwit witness marker writers.write_varint(w, 0x00) # segwit witness marker
writers.write_varint(w, 0x01) # segwit witness flag writers.write_varint(w, 0x01) # segwit witness flag
def write_tx_footer(
self, w: writers.Writer, tx: Union[SignTx, TransactionType]
) -> None:
writers.write_uint32(w, tx.lock_time)
async def write_prev_tx_footer( async def write_prev_tx_footer(
self, w: writers.Writer, tx: TransactionType, prev_hash: bytes self, w: writers.Writer, tx: TransactionType, prev_hash: bytes
) -> None: ) -> None:
writers.write_uint32(w, tx.lock_time) self.write_tx_footer(w, tx)
def set_serialized_signature(self, index: int, signature: bytes) -> None: def set_serialized_signature(self, index: int, signature: bytes) -> None:
# Only one signature per TxRequest can be serialized. # Only one signature per TxRequest can be serialized.

View File

@ -20,7 +20,7 @@ DECRED_SERIALIZE_FULL = const(0 << 16)
DECRED_SERIALIZE_NO_WITNESS = const(1 << 16) DECRED_SERIALIZE_NO_WITNESS = const(1 << 16)
DECRED_SERIALIZE_WITNESS_SIGNING = const(3 << 16) DECRED_SERIALIZE_WITNESS_SIGNING = const(3 << 16)
DECRED_SIGHASHALL = const(1) DECRED_SIGHASH_ALL = const(1)
if False: if False:
from typing import Union from typing import Union
@ -78,6 +78,7 @@ class Decred(Bitcoin):
self.hash143.add_output_count(self.tx) self.hash143.add_output_count(self.tx)
await super().step2_confirm_outputs() await super().step2_confirm_outputs()
self.hash143.add_locktime_expiry(self.tx) self.hash143.add_locktime_expiry(self.tx)
self.write_tx_footer(self.serialized_tx, self.tx)
async def process_input(self, i: int, txi: TxInputType) -> None: async def process_input(self, i: int, txi: TxInputType) -> None:
await super().process_input(i, txi) await super().process_input(i, txi)
@ -99,8 +100,6 @@ class Decred(Bitcoin):
await super().confirm_output(i, txo, txo_bin) await super().confirm_output(i, txo, txo_bin)
async def step4_serialize_inputs(self) -> None: async def step4_serialize_inputs(self) -> None:
writers.write_uint32(self.serialized_tx, self.tx.lock_time)
writers.write_uint32(self.serialized_tx, self.tx.expiry)
writers.write_varint(self.serialized_tx, self.tx.inputs_count) writers.write_varint(self.serialized_tx, self.tx.inputs_count)
prefix_hash = self.hash143.get_prefix_hash() prefix_hash = self.hash143.get_prefix_hash()
@ -145,7 +144,7 @@ class Decred(Bitcoin):
) )
h_sign = self.create_hash_writer() h_sign = self.create_hash_writer()
writers.write_uint32(h_sign, DECRED_SIGHASHALL) writers.write_uint32(h_sign, DECRED_SIGHASH_ALL)
writers.write_bytes_fixed(h_sign, prefix_hash, writers.TX_HASH_SIZE) writers.write_bytes_fixed(h_sign, prefix_hash, writers.TX_HASH_SIZE)
writers.write_bytes_fixed(h_sign, witness_hash, writers.TX_HASH_SIZE) writers.write_bytes_fixed(h_sign, witness_hash, writers.TX_HASH_SIZE)
@ -167,6 +166,9 @@ class Decred(Bitcoin):
async def step6_sign_segwit_inputs(self) -> None: async def step6_sign_segwit_inputs(self) -> None:
pass pass
async def step7_finish(self) -> None:
await helpers.request_tx_finish(self.tx_req)
def check_prevtx_output(self, txo_bin: TxOutputBinType) -> None: def check_prevtx_output(self, txo_bin: TxOutputBinType) -> None:
if ( if (
txo_bin.decred_script_version is not None txo_bin.decred_script_version is not None
@ -190,11 +192,8 @@ class Decred(Bitcoin):
writers.write_uint32(w, version) writers.write_uint32(w, version)
def write_sign_tx_footer(self, w: writers.Writer) -> None: def write_tx_footer(
pass self, w: writers.Writer, tx: Union[SignTx, TransactionType]
async def write_prev_tx_footer(
self, w: writers.Writer, tx: TransactionType, prev_hash: bytes
) -> None: ) -> None:
writers.write_uint32(w, tx.lock_time) writers.write_uint32(w, tx.lock_time)
writers.write_uint32(w, tx.expiry) writers.write_uint32(w, tx.expiry)

View File

@ -10,6 +10,7 @@ from trezor.utils import HashWriter, ensure
from apps.common.coininfo import CoinInfo from apps.common.coininfo import CoinInfo
from apps.common.seed import Keychain from apps.common.seed import Keychain
from apps.wallet.sign_tx import helpers
from apps.wallet.sign_tx.bitcoinlike import Bitcoinlike from apps.wallet.sign_tx.bitcoinlike import Bitcoinlike
from apps.wallet.sign_tx.common import SigningError from apps.wallet.sign_tx.common import SigningError
from apps.wallet.sign_tx.multisig import multisig_get_pubkeys from apps.wallet.sign_tx.multisig import multisig_get_pubkeys
@ -197,6 +198,26 @@ class Overwintered(Bitcoinlike):
"Unsupported version for overwintered transaction", "Unsupported version for overwintered transaction",
) )
async def step7_finish(self) -> None:
self.write_tx_footer(self.serialized_tx, self.tx)
if self.tx.version == 3:
write_uint32(self.serialized_tx, self.tx.expiry) # expiryHeight
write_varint(self.serialized_tx, 0) # nJoinSplit
elif self.tx.version == 4:
write_uint32(self.serialized_tx, self.tx.expiry) # expiryHeight
write_uint64(self.serialized_tx, 0) # valueBalance
write_varint(self.serialized_tx, 0) # nShieldedSpend
write_varint(self.serialized_tx, 0) # nShieldedOutput
write_varint(self.serialized_tx, 0) # nJoinSplit
else:
raise SigningError(
FailureType.DataError,
"Unsupported version for overwintered transaction",
)
await helpers.request_tx_finish(self.tx_req)
async def process_nonsegwit_input(self, i: int, txi: TxInputType) -> None: async def process_nonsegwit_input(self, i: int, txi: TxInputType) -> None:
await self.process_bip143_input(i, txi) await self.process_bip143_input(i, txi)
@ -209,21 +230,3 @@ class Overwintered(Bitcoinlike):
# nVersion | fOverwintered # nVersion | fOverwintered
write_uint32(w, tx.version | OVERWINTERED) write_uint32(w, tx.version | OVERWINTERED)
write_uint32(w, tx.version_group_id) # nVersionGroupId write_uint32(w, tx.version_group_id) # nVersionGroupId
def write_sign_tx_footer(self, w: Writer) -> None:
write_uint32(w, self.tx.lock_time)
if self.tx.version == 3:
write_uint32(w, self.tx.expiry) # expiryHeight
write_varint(w, 0) # nJoinSplit
elif self.tx.version == 4:
write_uint32(w, self.tx.expiry) # expiryHeight
write_uint64(w, 0) # valueBalance
write_varint(w, 0) # nShieldedSpend
write_varint(w, 0) # nShieldedOutput
write_varint(w, 0) # nJoinSplit
else:
raise SigningError(
FailureType.DataError,
"Unsupported version for overwintered transaction",
)