From 2227fc60b8d5c043d73b006e2cfd6d3c713e9b9e Mon Sep 17 00:00:00 2001 From: Ciny Date: Wed, 10 Apr 2019 16:22:04 +0200 Subject: [PATCH] src/apps/wallet: display custom locktime confirmation (#540) --- src/apps/wallet/sign_tx/__init__.py | 3 +++ src/apps/wallet/sign_tx/helpers.py | 11 +++++++++++ src/apps/wallet/sign_tx/layout.py | 16 ++++++++++++++++ src/apps/wallet/sign_tx/signing.py | 4 ++++ ...pps.wallet.segwit.signtx.native_p2wpkh_grs.py | 6 ++++++ ...ps.wallet.segwit.signtx.p2wpkh_in_p2sh_grs.py | 6 ++++++ 6 files changed, 46 insertions(+) diff --git a/src/apps/wallet/sign_tx/__init__.py b/src/apps/wallet/sign_tx/__init__.py index 3c6fd7bc2..5e468298d 100644 --- a/src/apps/wallet/sign_tx/__init__.py +++ b/src/apps/wallet/sign_tx/__init__.py @@ -46,6 +46,9 @@ async def sign_tx(ctx, msg, keychain): elif isinstance(req, helpers.UiConfirmFeeOverThreshold): res = await layout.confirm_feeoverthreshold(ctx, req.fee, req.coin) progress.report_init() + elif isinstance(req, helpers.UiConfirmNonDefaultLocktime): + res = await layout.confirm_nondefault_locktime(ctx, req.lock_time) + progress.report_init() elif isinstance(req, helpers.UiConfirmForeignAddress): res = await paths.show_path_warning(ctx, req.address_n) progress.report_init() diff --git a/src/apps/wallet/sign_tx/helpers.py b/src/apps/wallet/sign_tx/helpers.py index 6d1f5143e..07b9da300 100644 --- a/src/apps/wallet/sign_tx/helpers.py +++ b/src/apps/wallet/sign_tx/helpers.py @@ -52,6 +52,13 @@ class UiConfirmForeignAddress: __eq__ = obj_eq +class UiConfirmNonDefaultLocktime: + def __init__(self, lock_time: int): + self.lock_time = lock_time + + __eq__ = obj_eq + + def confirm_output(output: TxOutputType, coin: CoinInfo): return (yield UiConfirmOutput(output, coin)) @@ -68,6 +75,10 @@ def confirm_foreign_address(address_n: list): return (yield UiConfirmForeignAddress(address_n)) +def confirm_nondefault_locktime(lock_time: int): + return (yield UiConfirmNonDefaultLocktime(lock_time)) + + def request_tx_meta(tx_req: TxRequest, tx_hash: bytes = None): tx_req.request_type = TXMETA tx_req.details.tx_hash = tx_hash diff --git a/src/apps/wallet/sign_tx/layout.py b/src/apps/wallet/sign_tx/layout.py index 217b4057c..dd6831e3c 100644 --- a/src/apps/wallet/sign_tx/layout.py +++ b/src/apps/wallet/sign_tx/layout.py @@ -1,3 +1,4 @@ +from micropython import const from ubinascii import hexlify from trezor import ui @@ -9,6 +10,9 @@ from apps.common.confirm import confirm, hold_to_confirm from apps.wallet.sign_tx import addresses, omni +_LOCKTIME_TIMESTAMP_MIN_VALUE = const(500000000) + + def format_coin_amount(amount, coin): return "%s %s" % (format_amount(amount, 8), coin.coin_shortcut) @@ -65,3 +69,15 @@ async def confirm_foreign_address(ctx, address_n, coin): text = Text("Confirm sending", ui.ICON_SEND, icon_color=ui.RED) text.normal("Trying to spend", "coins from another chain.", "Continue?") return await confirm(ctx, text, ButtonRequestType.SignTx) + + +async def confirm_nondefault_locktime(ctx, lock_time): + text = Text("Confirm locktime", ui.ICON_SEND, icon_color=ui.GREEN) + text.normal("Locktime for this transaction is set to") + if lock_time < _LOCKTIME_TIMESTAMP_MIN_VALUE: + text.normal("blockheight:") + else: + text.normal("timestamp:") + text.bold(str(lock_time)) + text.normal("Continue?") + return await confirm(ctx, text, ButtonRequestType.SignTx) diff --git a/src/apps/wallet/sign_tx/signing.py b/src/apps/wallet/sign_tx/signing.py index b7d09e354..526d67bbd 100644 --- a/src/apps/wallet/sign_tx/signing.py +++ b/src/apps/wallet/sign_tx/signing.py @@ -200,6 +200,10 @@ async def check_tx_fee(tx: SignTx, keychain: seed.Keychain): if not await helpers.confirm_feeoverthreshold(fee, coin): raise SigningError(FailureType.ActionCancelled, "Signing cancelled") + if tx.lock_time > 0: + if not await helpers.confirm_nondefault_locktime(tx.lock_time): + raise SigningError(FailureType.ActionCancelled, "Locktime cancelled") + if not await helpers.confirm_total(total_in - change_out, fee, coin): raise SigningError(FailureType.ActionCancelled, "Total cancelled") diff --git a/tests/test_apps.wallet.segwit.signtx.native_p2wpkh_grs.py b/tests/test_apps.wallet.segwit.signtx.native_p2wpkh_grs.py index 9ad58c17b..ec963f822 100644 --- a/tests/test_apps.wallet.segwit.signtx.native_p2wpkh_grs.py +++ b/tests/test_apps.wallet.segwit.signtx.native_p2wpkh_grs.py @@ -72,6 +72,9 @@ class TestSignSegwitTxNativeP2WPKH_GRS(unittest.TestCase): helpers.UiConfirmOutput(out2, coin), True, + helpers.UiConfirmNonDefaultLocktime(tx.lock_time), + True, + helpers.UiConfirmTotal(12300000, 11000, coin), True, @@ -163,6 +166,9 @@ class TestSignSegwitTxNativeP2WPKH_GRS(unittest.TestCase): TxRequest(request_type=TXOUTPUT, details=TxRequestDetailsType(request_index=1, tx_hash=None), serialized=None), TxAck(tx=TransactionType(outputs=[out2])), + helpers.UiConfirmNonDefaultLocktime(tx.lock_time), + True, + helpers.UiConfirmTotal(5000000 + 11000, 11000, coin), True, diff --git a/tests/test_apps.wallet.segwit.signtx.p2wpkh_in_p2sh_grs.py b/tests/test_apps.wallet.segwit.signtx.p2wpkh_in_p2sh_grs.py index 152142c2b..4ab2d29ef 100644 --- a/tests/test_apps.wallet.segwit.signtx.p2wpkh_in_p2sh_grs.py +++ b/tests/test_apps.wallet.segwit.signtx.p2wpkh_in_p2sh_grs.py @@ -72,6 +72,9 @@ class TestSignSegwitTxP2WPKHInP2SH_GRS(unittest.TestCase): helpers.UiConfirmOutput(out2, coin), True, + helpers.UiConfirmNonDefaultLocktime(tx.lock_time), + True, + helpers.UiConfirmTotal(123445789 + 11000, 11000, coin), True, @@ -165,6 +168,9 @@ class TestSignSegwitTxP2WPKHInP2SH_GRS(unittest.TestCase): serialized=None), TxAck(tx=TransactionType(outputs=[out2])), + helpers.UiConfirmNonDefaultLocktime(tx.lock_time), + True, + helpers.UiConfirmTotal(12300000 + 11000, 11000, coin), True,