From 66583f2ebfd3d60c952c57f8a13927103e9d678d Mon Sep 17 00:00:00 2001 From: tychovrahe Date: Tue, 19 Dec 2023 12:07:33 +0100 Subject: [PATCH] fix(core): fix missing refresh in progress layout [no changelog] --- .../rust/src/ui/model_tt/bootloader/mod.rs | 3 +- core/src/apps/bitcoin/sign_tx/approvers.py | 35 ++++++++++++++++--- core/src/apps/bitcoin/sign_tx/bitcoin.py | 34 ++++++++++++------ core/src/apps/bitcoin/sign_tx/progress.py | 3 -- core/src/trezor/ui/layouts/tr/progress.py | 1 + core/src/trezor/ui/layouts/tt/progress.py | 1 + core/tests/test_apps.bitcoin.approver.py | 2 +- 7 files changed, 57 insertions(+), 22 deletions(-) diff --git a/core/embed/rust/src/ui/model_tt/bootloader/mod.rs b/core/embed/rust/src/ui/model_tt/bootloader/mod.rs index af5422bc8..805d5be3b 100644 --- a/core/embed/rust/src/ui/model_tt/bootloader/mod.rs +++ b/core/embed/rust/src/ui/model_tt/bootloader/mod.rs @@ -261,11 +261,10 @@ fn screen_progress( bg_color, ); display::loader(progress, -20, fg_color, bg_color, icon); + display::refresh(); if initialize { fadein(); } - - display::refresh(); } #[no_mangle] diff --git a/core/src/apps/bitcoin/sign_tx/approvers.py b/core/src/apps/bitcoin/sign_tx/approvers.py index b6656f70d..dece0a572 100644 --- a/core/src/apps/bitcoin/sign_tx/approvers.py +++ b/core/src/apps/bitcoin/sign_tx/approvers.py @@ -16,6 +16,8 @@ from .sig_hasher import BitcoinSigHasher from .tx_info import OriginalTxInfo if TYPE_CHECKING: + from typing import Optional + from trezor.crypto import bip32 from trezor.messages import SignTx, TxAckPaymentRequest, TxInput, TxOutput @@ -23,6 +25,7 @@ if TYPE_CHECKING: from apps.common.keychain import Keychain from ..authorization import CoinJoinAuthorization + from .bitcoin import Bitcoin from .payment_request import PaymentRequestVerifier from .tx_info import TxInfo @@ -132,7 +135,12 @@ class Approver: ) -> None: raise NotImplementedError - async def approve_tx(self, tx_info: TxInfo, orig_txs: list[OriginalTxInfo]) -> None: + async def approve_tx( + self, + tx_info: TxInfo, + orig_txs: list[OriginalTxInfo], + signer: Optional[Bitcoin], + ) -> None: self.finish_payment_request() @@ -270,13 +278,18 @@ class BasicApprover(Approver): else: return TR.bitcoin__title_update_transaction - async def approve_tx(self, tx_info: TxInfo, orig_txs: list[OriginalTxInfo]) -> None: + async def approve_tx( + self, + tx_info: TxInfo, + orig_txs: list[OriginalTxInfo], + signer: Optional[Bitcoin], + ) -> None: from trezor.wire import NotEnoughFunds coin = self.coin # local_cache_attribute amount_unit = self.amount_unit # local_cache_attribute - await super().approve_tx(tx_info, orig_txs) + await super().approve_tx(tx_info, orig_txs, signer) if self.has_unverified_external_input: await helpers.confirm_unverified_external_input() @@ -336,6 +349,8 @@ class BasicApprover(Approver): ) if not self.is_payjoin(): + if signer is not None: + signer.init_signing() title = self._replacement_title(tx_info, orig_txs) # Not a PayJoin: Show the actual fee difference, since any difference in the fee is # coming entirely from the user's own funds and from decreases of external outputs. @@ -344,6 +359,8 @@ class BasicApprover(Approver): title, fee - orig_fee, fee, fee_rate, coin, amount_unit ) elif spending > orig_spending: + if signer is not None: + signer.init_signing() title = self._replacement_title(tx_info, orig_txs) # PayJoin and user is spending more: Show the increase in the user's contribution # to the fee, ignoring any contribution from external inputs. Decreasing of @@ -363,6 +380,9 @@ class BasicApprover(Approver): tx_info.tx.lock_time, tx_info.lock_time_disabled() ) + if signer is not None: + signer.init_signing() + if not self.external_in: await helpers.confirm_total( total, @@ -511,10 +531,15 @@ class CoinJoinApprover(Approver): self.h_request.get_digest(), ) - async def approve_tx(self, tx_info: TxInfo, orig_txs: list[OriginalTxInfo]) -> None: + async def approve_tx( + self, + tx_info: TxInfo, + orig_txs: list[OriginalTxInfo], + signer: Optional[Bitcoin], + ) -> None: from ..authorization import FEE_RATE_DECIMALS - await super().approve_tx(tx_info, orig_txs) + await super().approve_tx(tx_info, orig_txs, signer) if not self._verify_coinjoin_request(tx_info): raise DataError("Invalid signature in coinjoin request.") diff --git a/core/src/apps/bitcoin/sign_tx/bitcoin.py b/core/src/apps/bitcoin/sign_tx/bitcoin.py index 10267415e..ec31da941 100644 --- a/core/src/apps/bitcoin/sign_tx/bitcoin.py +++ b/core/src/apps/bitcoin/sign_tx/bitcoin.py @@ -40,6 +40,20 @@ _SERIALIZED_TX_BUFFER = empty_bytearray(_MAX_SERIALIZED_CHUNK_SIZE) class Bitcoin: + def init_signing(self) -> None: + # Next shown progress bar is already signing progress, but it isn't shown until approval from next dialog + progress.init_signing( + len(self.external), + len(self.segwit), + len(self.presigned), + self.taproot_only, + self.serialize, + self.coin, + self.tx_info.tx, + self.orig_txs, + ) + self.signing = True + async def signer(self) -> None: progress.init( self.tx_info.tx, is_coinjoin=isinstance(self.approver, CoinJoinApprover) @@ -56,18 +70,13 @@ class Bitcoin: await self.step2_approve_outputs() # Check fee, approve lock_time and total. - await self.approver.approve_tx(self.tx_info, self.orig_txs) + await self.approver.approve_tx(self.tx_info, self.orig_txs, self) - progress.init_signing( - len(self.external), - len(self.segwit), - len(self.presigned), - self.taproot_only, - self.serialize, - self.coin, - self.tx_info.tx, - self.orig_txs, - ) + # Make sure proper progress is shown, in case dialog was not required + if not self.signing: + self.init_signing() + progress.report_init() + progress.report() # Following steps can take a long time, make sure autolock doesn't kick in. # This is set to True again after workflow is finished in start_default(). @@ -129,6 +138,9 @@ class Bitcoin: # indicates whether all internal inputs are Taproot self.taproot_only = True + # indicates whether the transaction is being signed + self.signing = False + # transaction and signature serialization _SERIALIZED_TX_BUFFER[:] = bytes() self.serialized_tx = _SERIALIZED_TX_BUFFER diff --git a/core/src/apps/bitcoin/sign_tx/progress.py b/core/src/apps/bitcoin/sign_tx/progress.py index e94e3a136..c375240c2 100644 --- a/core/src/apps/bitcoin/sign_tx/progress.py +++ b/core/src/apps/bitcoin/sign_tx/progress.py @@ -97,9 +97,6 @@ class Progress: if serialize and not coin.decred: self.steps += tx.outputs_count - self.report_init() - self.report() - def init_prev_tx(self, inputs: int, outputs: int) -> None: self.prev_tx_step = _PREV_TX_MULTIPLIER / (inputs + outputs) diff --git a/core/src/trezor/ui/layouts/tr/progress.py b/core/src/trezor/ui/layouts/tr/progress.py index 0171eca46..36ac9ced4 100644 --- a/core/src/trezor/ui/layouts/tr/progress.py +++ b/core/src/trezor/ui/layouts/tr/progress.py @@ -17,6 +17,7 @@ class RustProgress: self.layout = layout self.layout.attach_timer_fn(self.set_timer) self.layout.paint() + ui.refresh() def set_timer(self, token: int, deadline: int) -> None: raise RuntimeError # progress layouts should not set timers diff --git a/core/src/trezor/ui/layouts/tt/progress.py b/core/src/trezor/ui/layouts/tt/progress.py index 15c933821..5997d247f 100644 --- a/core/src/trezor/ui/layouts/tt/progress.py +++ b/core/src/trezor/ui/layouts/tt/progress.py @@ -18,6 +18,7 @@ class RustProgress: ui.backlight_fade(ui.style.BACKLIGHT_DIM) self.layout.attach_timer_fn(self.set_timer) self.layout.paint() + ui.refresh() ui.backlight_fade(ui.style.BACKLIGHT_NORMAL) def set_timer(self, token: int, deadline: int) -> None: diff --git a/core/tests/test_apps.bitcoin.approver.py b/core/tests/test_apps.bitcoin.approver.py index 92d142de4..fbbee64d6 100644 --- a/core/tests/test_apps.bitcoin.approver.py +++ b/core/tests/test_apps.bitcoin.approver.py @@ -188,7 +188,7 @@ class TestApprover(unittest.TestCase): else: await_result(approver.add_external_output(txo, script_pubkey=bytes(22))) - await_result(approver.approve_tx(TxInfo(signer, tx), [])) + await_result(approver.approve_tx(TxInfo(signer, tx), [], None)) def test_coinjoin_input_account_depth_mismatch(self): txi = TxInput(