mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-12-22 06:18:07 +00:00
refactor(core): Replace Bitcoin signing progress functions with a class.
This commit is contained in:
parent
a1a34774b8
commit
5dddb06e2b
@ -91,6 +91,6 @@ async def sign_tx(
|
||||
res = await ctx.call(req, request_class)
|
||||
elif isinstance(req, helpers.UiConfirm):
|
||||
res = await req.confirm_dialog(ctx)
|
||||
progress.report_init()
|
||||
progress.progress.report_init()
|
||||
else:
|
||||
raise TypeError("Invalid signing instruction")
|
||||
|
@ -19,7 +19,8 @@ from ..common import (
|
||||
)
|
||||
from ..ownership import verify_nonownership
|
||||
from ..verification import SignatureVerifier
|
||||
from . import approvers, helpers, progress
|
||||
from . import approvers, helpers
|
||||
from .progress import progress
|
||||
from .sig_hasher import BitcoinSigHasher
|
||||
from .tx_info import OriginalTxInfo, TxInfo
|
||||
|
||||
|
@ -12,9 +12,10 @@ from apps.common.writers import write_compact_size
|
||||
|
||||
from .. import multisig, scripts_decred, writers
|
||||
from ..common import SigHashType, ecdsa_hash_pubkey, ecdsa_sign
|
||||
from . import approvers, helpers, progress
|
||||
from . import approvers, helpers
|
||||
from .approvers import BasicApprover
|
||||
from .bitcoin import Bitcoin
|
||||
from .progress import progress
|
||||
|
||||
DECRED_SERIALIZE_FULL = const(0 << 16)
|
||||
DECRED_SERIALIZE_NO_WITNESS = const(1 << 16)
|
||||
|
@ -12,123 +12,126 @@ if TYPE_CHECKING:
|
||||
# the input, prevtx metadata, prevtx input, prevtx output, prevtx change-output
|
||||
_PREV_TX_MULTIPLIER = 5
|
||||
|
||||
_progress = 0
|
||||
_steps = 0
|
||||
_signing = False
|
||||
_prev_tx_step = 0
|
||||
|
||||
class Progress:
|
||||
def __init__(self):
|
||||
self.progress = 0
|
||||
self.steps = 0
|
||||
self.signing = False
|
||||
|
||||
def init(tx: SignTx) -> None:
|
||||
global _progress, _steps, _signing
|
||||
_progress = 0
|
||||
_signing = False
|
||||
# We don't know how long it will take to fetch the previous transactions,
|
||||
# so for each one we reserve _PREV_TX_MULTIPLIER steps in the signing
|
||||
# progress. Once we fetch a prev_tx's metadata, we subdivide the reserved
|
||||
# space and then prev_tx_step represents the progress of fetching one
|
||||
# prev_tx input or output in the overall signing progress.
|
||||
self.prev_tx_step = 0
|
||||
|
||||
# Step 1 and 2 - load inputs and outputs
|
||||
_steps = tx.inputs_count + tx.outputs_count
|
||||
def init(self, tx: SignTx) -> None:
|
||||
self.progress = 0
|
||||
self.signing = False
|
||||
|
||||
report_init()
|
||||
report()
|
||||
# Step 1 and 2 - load inputs and outputs
|
||||
self.steps = tx.inputs_count + tx.outputs_count
|
||||
|
||||
self.report_init()
|
||||
self.report()
|
||||
|
||||
def init_signing(
|
||||
self,
|
||||
external: int,
|
||||
segwit: int,
|
||||
taproot_only: bool,
|
||||
has_presigned: bool,
|
||||
serialize: bool,
|
||||
coin: CoinInfo,
|
||||
tx: SignTx,
|
||||
orig_txs: list[OriginalTxInfo],
|
||||
) -> None:
|
||||
if __debug__:
|
||||
self.assert_finished()
|
||||
|
||||
self.progress = 0
|
||||
self.steps = 0
|
||||
self.signing = True
|
||||
|
||||
# Step 3 - verify inputs
|
||||
if taproot_only or (coin.overwintered and tx.version == 5):
|
||||
if has_presigned:
|
||||
self.steps += external
|
||||
else:
|
||||
self.steps = tx.inputs_count * _PREV_TX_MULTIPLIER
|
||||
|
||||
for orig in orig_txs:
|
||||
self.steps += orig.tx.inputs_count
|
||||
|
||||
# Steps 3 and 4 - get_legacy_tx_digest() for each legacy input.
|
||||
if not (coin.force_bip143 or coin.overwintered or coin.decred):
|
||||
self.steps += (tx.inputs_count - segwit) * (
|
||||
tx.inputs_count + tx.outputs_count
|
||||
)
|
||||
|
||||
if segwit != tx.inputs_count:
|
||||
# The transaction has a legacy input.
|
||||
|
||||
# Simplification: We assume that all original transaction inputs
|
||||
# are legacy, since mixed script types are not supported in Suite.
|
||||
for orig in orig_txs:
|
||||
self.steps += orig.tx.inputs_count * (
|
||||
orig.tx.inputs_count + orig.tx.outputs_count
|
||||
)
|
||||
|
||||
# Steps 4 and 6 - serialize and sign inputs
|
||||
if serialize:
|
||||
self.steps += tx.inputs_count + segwit
|
||||
else:
|
||||
self.steps += tx.inputs_count - external
|
||||
|
||||
# Step 5 - serialize outputs
|
||||
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)
|
||||
|
||||
def advance(self) -> None:
|
||||
self.progress += 1
|
||||
self.report()
|
||||
|
||||
def advance_prev_tx(self) -> None:
|
||||
self.progress += self.prev_tx_step
|
||||
self.report()
|
||||
|
||||
def report_init(self) -> None:
|
||||
from trezor import workflow
|
||||
|
||||
workflow.close_others()
|
||||
ui.display.clear()
|
||||
if self.signing:
|
||||
ui.header("Signing transaction")
|
||||
else:
|
||||
ui.header("Loading transaction")
|
||||
|
||||
def report(self) -> None:
|
||||
from trezor import utils
|
||||
|
||||
if utils.DISABLE_ANIMATION:
|
||||
return
|
||||
p = int(1000 * self.progress / self.steps)
|
||||
ui.display.loader(p, False, 18, ui.WHITE, ui.BG)
|
||||
|
||||
def init_signing(
|
||||
external: int,
|
||||
segwit: int,
|
||||
taproot_only: bool,
|
||||
has_presigned: bool,
|
||||
serialize: bool,
|
||||
coin: CoinInfo,
|
||||
tx: SignTx,
|
||||
orig_txs: list[OriginalTxInfo],
|
||||
) -> None:
|
||||
if __debug__:
|
||||
assert_finished()
|
||||
|
||||
global _progress, _steps, _signing
|
||||
_progress = 0
|
||||
_steps = 0
|
||||
_signing = True
|
||||
def assert_finished(self) -> None:
|
||||
if abs(self.progress - self.steps) > 0.5:
|
||||
from trezor import wire
|
||||
|
||||
# Step 3 - verify inputs
|
||||
if taproot_only or (coin.overwintered and tx.version == 5):
|
||||
if has_presigned:
|
||||
_steps += external
|
||||
else:
|
||||
_steps = tx.inputs_count * _PREV_TX_MULTIPLIER
|
||||
|
||||
for orig in orig_txs:
|
||||
_steps += orig.tx.inputs_count
|
||||
|
||||
# Steps 3 and 4 - get_legacy_tx_digest() for each legacy input.
|
||||
if not (coin.force_bip143 or coin.overwintered or coin.decred):
|
||||
_steps += (tx.inputs_count - segwit) * (tx.inputs_count + tx.outputs_count)
|
||||
|
||||
if segwit != tx.inputs_count:
|
||||
# The transaction has a legacy input.
|
||||
|
||||
# Simplification: We assume that all original transaction inputs
|
||||
# are legacy, since mixed script types are not supported in Suite.
|
||||
for orig in orig_txs:
|
||||
_steps += orig.tx.inputs_count * (
|
||||
orig.tx.inputs_count + orig.tx.outputs_count
|
||||
operation = "signing" if self.signing else "loading"
|
||||
raise wire.FirmwareError(
|
||||
f"Transaction {operation} progress finished at {self.progress}/{self.steps}."
|
||||
)
|
||||
|
||||
# Steps 4 and 6 - serialize and sign inputs
|
||||
if serialize:
|
||||
_steps += tx.inputs_count + segwit
|
||||
else:
|
||||
_steps += tx.inputs_count - external
|
||||
|
||||
# Step 5 - serialize outputs
|
||||
if serialize and not coin.decred:
|
||||
_steps += tx.outputs_count
|
||||
|
||||
report_init()
|
||||
report()
|
||||
|
||||
|
||||
def init_prev_tx(inputs: int, outputs: int) -> None:
|
||||
global _prev_tx_step
|
||||
_prev_tx_step = _PREV_TX_MULTIPLIER / (inputs + outputs)
|
||||
|
||||
|
||||
def advance() -> None:
|
||||
global _progress
|
||||
_progress += 1
|
||||
report()
|
||||
|
||||
|
||||
def advance_prev_tx() -> None:
|
||||
global _progress
|
||||
_progress += _prev_tx_step
|
||||
report()
|
||||
|
||||
|
||||
def report_init() -> None:
|
||||
from trezor import workflow
|
||||
|
||||
workflow.close_others()
|
||||
ui.display.clear()
|
||||
if _signing:
|
||||
ui.header("Signing transaction")
|
||||
else:
|
||||
ui.header("Loading transaction")
|
||||
|
||||
|
||||
def report() -> None:
|
||||
from trezor import utils
|
||||
|
||||
if utils.DISABLE_ANIMATION:
|
||||
return
|
||||
p = int(1000 * _progress / _steps)
|
||||
ui.display.loader(p, False, 18, ui.WHITE, ui.BG)
|
||||
|
||||
|
||||
if __debug__:
|
||||
|
||||
def assert_finished() -> None:
|
||||
if abs(_progress - _steps) > 0.5:
|
||||
operation = "signing" if _signing else "loading"
|
||||
from trezor import wire
|
||||
raise wire.FirmwareError(
|
||||
f"Transaction {operation} progress finished at {_progress}/{_steps}."
|
||||
)
|
||||
progress = Progress()
|
||||
|
Loading…
Reference in New Issue
Block a user