@ -1,8 +1,9 @@
import gc
from micropython import const
from trezor import wire
from trezor . crypto . hashlib import sha256
from trezor . messages import FailureType, InputScriptType
from trezor . messages import InputScriptType
from trezor . messages . SignTx import SignTx
from trezor . messages . TransactionType import TransactionType
from trezor . messages . TxInputType import TxInputType
@ -14,17 +15,12 @@ from trezor.messages.TxRequestSerializedType import TxRequestSerializedType
from trezor . utils import HashWriter , ensure
from apps . common import coininfo , seed
from apps . wallet . sign_tx import (
addresses ,
helpers ,
multisig ,
progress ,
scripts ,
tx_weight ,
writers ,
)
from apps . wallet . sign_tx . common import SigningError , ecdsa_sign
from apps . wallet . sign_tx . matchcheck import MultisigFingerprintChecker , WalletPathChecker
from apps . common . writers import write_bitcoin_varint
from . . import addresses , multisig , scripts , writers
from . . common import ecdsa_hash_pubkey , ecdsa_sign
from . import helpers , progress , tx_weight
from . matchcheck import MultisigFingerprintChecker , WalletPathChecker
if False :
from typing import Set , Tuple , Union
@ -136,17 +132,10 @@ class Bitcoin:
# fee > (coin.maxfee per byte * tx size)
if fee > ( self . coin . maxfee_kb / 1000 ) * ( self . weight . get_total ( ) / 4 ) :
if not await helpers . confirm_feeoverthreshold ( fee , self . coin ) :
raise SigningError ( FailureType . ActionCancelled , " Signing cancelled " )
await helpers . confirm_feeoverthreshold ( fee , self . coin )
if self . tx . lock_time > 0 :
if not await helpers . confirm_nondefault_locktime ( self . tx . lock_time ) :
raise SigningError ( FailureType . ActionCancelled , " Locktime cancelled " )
if not await helpers . confirm_total (
self . total_in - self . change_out , fee , self . coin
) :
raise SigningError ( FailureType . ActionCancelled , " Total cancelled " )
await helpers . confirm_nondefault_locktime ( self . tx . lock_time )
await helpers . confirm_total ( self . total_in - self . change_out , fee , self . coin )
async def step4_serialize_inputs ( self ) - > None :
self . write_tx_header ( self . serialized_tx , self . tx , bool ( self . segwit ) )
@ -193,7 +182,7 @@ class Bitcoin:
elif input_is_nonsegwit ( txi ) :
await self . process_nonsegwit_input ( txi )
else :
raise SigningError( FailureType . DataError , " Wrong input script type " )
raise wire. DataError ( " Wrong input script type " )
async def process_segwit_input ( self , txi : TxInputType ) - > None :
await self . process_bip143_input ( txi )
@ -205,7 +194,7 @@ class Bitcoin:
async def process_bip143_input ( self , txi : TxInputType ) - > None :
if not txi . amount :
raise SigningError( FailureType . DataError , " Expected input with amount " )
raise wire. DataError ( " Expected input with amount " )
self . bip143_in + = txi . amount
self . total_in + = txi . amount
@ -213,24 +202,22 @@ class Bitcoin:
if self . change_out == 0 and self . output_is_change ( txo ) :
# output is change and does not need confirmation
self . change_out = txo . amount
el if not await helpers . confirm_output ( txo , self. coin ) :
raise SigningError ( FailureType . ActionCancelled , " Output cancelled " )
el se:
await helpers . confirm_output ( txo , self . coin )
self . write_tx_output ( self . h_confirmed , txo , script_pubkey )
self . hash143_add_output ( txo , script_pubkey )
self . total_out + = txo . amount
def on_negative_fee ( self ) - > None :
raise SigningError( FailureType . NotEnoughFunds , " Not enough funds " )
raise wire. NotEnoughFunds ( " Not enough funds " )
async def serialize_segwit_input ( self , i : int ) - > None :
# STAGE_REQUEST_SEGWIT_INPUT in legacy
txi = await helpers . request_tx_input ( self . tx_req , i , self . coin )
if not input_is_segwit ( txi ) :
raise SigningError (
FailureType . ProcessError , " Transaction has changed during signing "
)
raise wire . ProcessError ( " Transaction has changed during signing " )
self . wallet_path . check_input ( txi )
# NOTE: No need to check the multisig fingerprint, because we won't be signing
# the script here. Signatures are produced in STAGE_REQUEST_SEGWIT_WITNESS.
@ -245,15 +232,13 @@ class Bitcoin:
self . multisig_fingerprint . check_input ( txi )
if txi . amount > self . bip143_in :
raise SigningError (
FailureType . ProcessError , " Transaction has changed during signing "
)
raise wire . ProcessError ( " Transaction has changed during signing " )
self . bip143_in - = txi . amount
node = self . keychain . derive ( txi . address_n )
public_key = node . public_key ( )
hash143_hash = self . hash143_preimage_hash (
txi , addresses. ecdsa_hash_pubkey( public_key , self . coin )
txi , ecdsa_hash_pubkey( public_key , self . coin )
)
signature = ecdsa_sign ( node , hash143_hash )
@ -265,9 +250,7 @@ class Bitcoin:
txi = await helpers . request_tx_input ( self . tx_req , i , self . coin )
if not input_is_segwit ( txi ) :
raise SigningError (
FailureType . ProcessError , " Transaction has changed during signing "
)
raise wire . ProcessError ( " Transaction has changed during signing " )
public_key , signature = self . sign_bip143_input ( txi )
@ -318,9 +301,7 @@ class Bitcoin:
addresses . ecdsa_hash_pubkey ( key_sign_pub , self . coin )
)
else :
raise SigningError (
FailureType . ProcessError , " Unknown transaction type "
)
raise wire . ProcessError ( " Unknown transaction type " )
txi_sign = txi
else :
script_pubkey = bytes ( )
@ -340,9 +321,7 @@ class Bitcoin:
# check the control digests
if self . h_confirmed . get_digest ( ) != h_check . get_digest ( ) :
raise SigningError (
FailureType . ProcessError , " Transaction has changed during signing "
)
raise wire . ProcessError ( " Transaction has changed during signing " )
# compute the signature from the tx digest
signature = ecdsa_sign (
@ -368,9 +347,7 @@ class Bitcoin:
tx = await helpers . request_tx_meta ( self . tx_req , self . coin , prev_hash )
if tx . outputs_cnt < = prev_index :
raise SigningError (
FailureType . ProcessError , " Not enough outputs in previous transaction. "
)
raise wire . ProcessError ( " Not enough outputs in previous transaction. " )
txh = self . create_hash_writer ( )
@ -401,9 +378,7 @@ class Bitcoin:
writers . get_tx_hash ( txh , double = self . coin . sign_hash_double , reverse = True )
!= prev_hash
) :
raise SigningError (
FailureType . ProcessError , " Encountered invalid prev_hash "
)
raise wire . ProcessError ( " Encountered invalid prev_hash " )
return amount_out
@ -469,7 +444,7 @@ class Bitcoin:
txo . script_type
]
except KeyError :
raise SigningError( FailureType . DataError , " Invalid script type " )
raise wire. DataError ( " Invalid script type " )
node = self . keychain . derive ( txo . address_n )
txo . address = addresses . get_address (
input_script_type , self . coin , node , txo . multisig