diff --git a/core/src/apps/bitcoin/sign_tx/layout.py b/core/src/apps/bitcoin/sign_tx/layout.py index 2b35669b33..ded51da58a 100644 --- a/core/src/apps/bitcoin/sign_tx/layout.py +++ b/core/src/apps/bitcoin/sign_tx/layout.py @@ -3,7 +3,7 @@ from ubinascii import hexlify from trezor import utils from trezor.enums import AmountUnit, ButtonRequestType, OutputScriptType -from trezor.strings import format_amount +from trezor.strings import format_amount, format_timestamp from trezor.ui import layouts from .. import addresses @@ -193,8 +193,8 @@ async def confirm_nondefault_locktime( param = str(lock_time) else: title = "Confirm locktime" - text = "Locktime for this\ntransaction is set to\ntimestamp:\n{}" - param = str(lock_time) + text = "Locktime for this\ntransaction is set to:\n{}" + param = format_timestamp(lock_time) await layouts.confirm_metadata( ctx, diff --git a/tests/device_tests/test_msg_signtx.py b/tests/device_tests/test_msg_signtx.py index 592f0abc13..561b7b1914 100644 --- a/tests/device_tests/test_msg_signtx.py +++ b/tests/device_tests/test_msg_signtx.py @@ -14,6 +14,8 @@ # You should have received a copy of the License along with this library. # If not, see . +from datetime import datetime, timezone + import pytest from trezorlib import btc, device, messages @@ -1389,3 +1391,102 @@ class TestMsgSigntx: lock_time=lock_time, prev_txes=TX_CACHE_MAINNET, ) + + @pytest.mark.skip_t1(reason="Cannot test layouts on T1") + def test_lock_time_blockheight(self, client): + # tx: d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882 + # input 0: 0.0039 BTC + + inp1 = messages.TxInputType( + address_n=parse_path("44h/0h/0h/0/0"), + amount=390000, + prev_hash=TXHASH_d5f65e, + prev_index=0, + sequence=0xFFFF_FFFE, + ) + + out1 = messages.TxOutputType( + address="1MJ2tj2ThBE62zXbBYA5ZaN3fdve5CPAz1", + amount=390000 - 10000, + script_type=messages.OutputScriptType.PAYTOADDRESS, + ) + + def input_flow(): + yield # confirm output + client.debug.wait_layout() + client.debug.press_yes() + + yield # confirm locktime + layout = client.debug.wait_layout() + assert "blockheight" in layout.text + assert "499999999" in layout.text + client.debug.press_yes() + + yield # confirm transaction + client.debug.press_yes() + + with client: + client.set_input_flow(input_flow) + client.watch_layout(True) + + btc.sign_tx( + client, + "Bitcoin", + [inp1], + [out1], + lock_time=499999999, + prev_txes=TX_CACHE_MAINNET, + ) + + @pytest.mark.skip_t1(reason="Cannot test layouts on T1") + @pytest.mark.parametrize( + "lock_time_str", ("1985-11-05 00:53:20", "2048-08-16 22:14:00") + ) + def test_lock_time_datetime(self, client, lock_time_str): + # tx: d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882 + # input 0: 0.0039 BTC + + inp1 = messages.TxInputType( + address_n=parse_path("44h/0h/0h/0/0"), + amount=390000, + prev_hash=TXHASH_d5f65e, + prev_index=0, + sequence=0xFFFF_FFFE, + ) + + out1 = messages.TxOutputType( + address="1MJ2tj2ThBE62zXbBYA5ZaN3fdve5CPAz1", + amount=390000 - 10000, + script_type=messages.OutputScriptType.PAYTOADDRESS, + ) + + def input_flow(): + yield # confirm output + client.debug.wait_layout() + client.debug.press_yes() + + yield # confirm locktime + layout = client.debug.wait_layout() + assert lock_time_str in layout.text + + client.debug.press_yes() + + yield # confirm transaction + client.debug.press_yes() + + lock_time_naive = datetime.strptime(lock_time_str, "%Y-%m-%d %H:%M:%S") + lock_time_utc = lock_time_naive.replace(tzinfo=timezone.utc) + lock_time_timestamp = int(lock_time_utc.timestamp()) + + with client: + client.set_input_flow(input_flow) + client.watch_layout(True) + + btc.sign_tx( + client, + "Bitcoin", + [inp1], + [out1], + lock_time=lock_time_timestamp, + prev_txes=TX_CACHE_MAINNET, + ) diff --git a/tests/ui_tests/fixtures.json b/tests/ui_tests/fixtures.json index 23c66b859c..33834cf1fb 100644 --- a/tests/ui_tests/fixtures.json +++ b/tests/ui_tests/fixtures.json @@ -557,7 +557,10 @@ "test_msg_signtx.py-test_incorrect_output_script_type[OutputScriptType.PAYTOSCRIPTHASH]": "1c100ce4b7c1e47e72428f390de0846c1ff933e9f07894872644a369a9422738", "test_msg_signtx.py-test_lock_time[1-4294967295]": "25c535e867f8ed508c5aab8e8f6f67ed603d7c1166ad401b4cbe12e02f95fa6c", "test_msg_signtx.py-test_lock_time[499999999-4294967294]": "535f0fb6e8804cc450b68b7407f8fe59cd12f316951379b9ebf3ba18a88b2170", -"test_msg_signtx.py-test_lock_time[500000000-4294967294]": "b777e079b440d7174d13437e0a71428c482ae16bbbbe766eff71eca127a6f2e4", +"test_msg_signtx.py-test_lock_time[500000000-4294967294]": "be7ef95ed73748467f97931b35cba9f864472448f16ff9c204550f06823bc7a5", +"test_msg_signtx.py-test_lock_time_blockheight": "535f0fb6e8804cc450b68b7407f8fe59cd12f316951379b9ebf3ba18a88b2170", +"test_msg_signtx.py-test_lock_time_datetime[1985-11-05 00:53:20]": "be7ef95ed73748467f97931b35cba9f864472448f16ff9c204550f06823bc7a5", +"test_msg_signtx.py-test_lock_time_datetime[2048-08-16 22:14:00]": "8af5a4ab4daa8299a08fc293b64843c8607eb38f9a52d67bd9f9c6540974334b", "test_msg_signtx.py-test_lots_of_change": "fdcfedc0aa6186adbcf28d1bdde7daba617e7415dc1b0f8df43baf238fb29bf6", "test_msg_signtx.py-test_lots_of_inputs": "b7e38a8cb104b2658c93c16ef82ad6dc0629cfbce6f7b574147662537376ac9c", "test_msg_signtx.py-test_lots_of_outputs": "d142f73b67902ea463a129eb5dc91ba033feaf987a6ee02eecd170836b8988ef",