From 3a7a8e4d7763bc015b64e676ed347cec58c47cb9 Mon Sep 17 00:00:00 2001 From: Rafael Korbas Date: Thu, 3 Dec 2020 22:53:30 +0100 Subject: [PATCH] Disable "at least one output" restriction for Cardano, warn instead --- common/tests/fixtures/cardano/sign_tx.json | 31 ++++++++++++++++++++++ core/src/apps/cardano/layout.py | 22 ++++++++++++--- core/src/apps/cardano/sign_tx.py | 29 +++++++++++++++++--- 3 files changed, 75 insertions(+), 7 deletions(-) diff --git a/common/tests/fixtures/cardano/sign_tx.json b/common/tests/fixtures/cardano/sign_tx.json index 6dc95436a1..552d290a1c 100644 --- a/common/tests/fixtures/cardano/sign_tx.json +++ b/common/tests/fixtures/cardano/sign_tx.json @@ -330,6 +330,37 @@ "serialized_tx": "83a500818258203b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b700018182583901eb0baa5e570cffbe2934db29df0b6a3d7c0430ee65d4c3a7ab2fefb91bc428e4720702ebd5dab4fb175324c192dc9bb76cc5da956e3c8dff0102182a030a048182008200581c122a946b9ad3d2ddf029d3a828f0468aece76895f15c9efbd69b4277a100818258205d010cf16fdeff40955633d6c565f3844a288a24967cf6b76acbeb271b4f13c15840a938b16bd81aea8d3aaf11e4d460dad1f36d34bf34ad066d0f5ce5d4137654145d998c3482aa823ff1acf021c6e2cd2774fff00361cbb9e72b98632307ee4000f6" } }, + { + "description": "transaction with stake registration certificate (no outputs)", + "parameters": { + "protocol_magic": 764824073, + "network_id": 1, + "fee": 42, + "ttl": 10, + "certificates": [ + { + "type": 0, + "path": "m/1852'/1815'/0'/2/0" + } + ], + "withdrawals": [], + "metadata": "", + "input_flow": [["YES"], ["SWIPE", "YES"], ["SWIPE", "YES"]], + "inputs": [ + { + "path": "m/1852'/1815'/0'/0/0", + "prev_hash": "3b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b7", + "prev_index": 0 + } + ], + "outputs": [ + ] + }, + "result": { + "tx_hash": "03535791d04fc1b4457fada025f1c1f7778b5c2d7fa580bbac8abd53b85d3255", + "serialized_tx": "83a500818258203b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b700018002182a030a048182008200581c122a946b9ad3d2ddf029d3a828f0468aece76895f15c9efbd69b4277a100818258205d010cf16fdeff40955633d6c565f3844a288a24967cf6b76acbeb271b4f13c1584047e6e902e81bbba5596cfabaa4f9a70f36b367e28ee81181771ccd32d38b19c1d8ae9b0afb2a79057b87f8de7862e8d2317d86246909aaa66e54445d47aa990bf6" + } + }, { "description": "transaction with stake registration and stake delegation certificates", "parameters": { diff --git a/core/src/apps/cardano/layout.py b/core/src/apps/cardano/layout.py index a8975725ea..5933884e30 100644 --- a/core/src/apps/cardano/layout.py +++ b/core/src/apps/cardano/layout.py @@ -152,7 +152,13 @@ async def show_warning_tx_staking_key_hash( async def confirm_transaction( - ctx, amount: int, fee: int, protocol_magic: int, ttl: int, has_metadata: bool + ctx, + amount: int, + fee: int, + protocol_magic: int, + ttl: int, + has_metadata: bool, + is_network_id_verifiable: bool, ) -> None: pages = [] @@ -164,8 +170,9 @@ async def confirm_transaction( pages.append(page1) page2 = Text("Confirm transaction", ui.ICON_SEND, ui.GREEN) - page2.normal("Network:") - page2.bold(protocol_magics.to_ui_string(protocol_magic)) + if is_network_id_verifiable: + page2.normal("Network:") + page2.bold(protocol_magics.to_ui_string(protocol_magic)) page2.normal("Transaction TTL:") page2.bold(str(ttl)) pages.append(page2) @@ -421,6 +428,15 @@ async def show_warning_address_foreign_staking_key( ) +async def show_warning_tx_network_unverifiable(ctx: wire.Context) -> None: + page1 = Text("Warning", ui.ICON_SEND, ui.GREEN) + page1.normal("Transaction has no outputs, network cannot be verified.") + page1.br_half() + page1.normal("Continue?") + + await require_confirm(ctx, page1) + + async def show_warning_address_pointer( ctx: wire.Context, pointer: CardanoBlockchainPointerType ) -> None: diff --git a/core/src/apps/cardano/sign_tx.py b/core/src/apps/cardano/sign_tx.py index a666bed192..1ec741fff1 100644 --- a/core/src/apps/cardano/sign_tx.py +++ b/core/src/apps/cardano/sign_tx.py @@ -43,6 +43,7 @@ from .layout import ( confirm_transaction_network_ttl, confirm_withdrawal, show_warning_tx_different_staking_account, + show_warning_tx_network_unverifiable, show_warning_tx_no_staking_info, show_warning_tx_pointer_address, show_warning_tx_staking_key_hash, @@ -183,9 +184,6 @@ def _validate_outputs( protocol_magic: int, network_id: int, ) -> None: - if not outputs: - raise wire.ProcessError("Transaction has no outputs!") - total_amount = 0 for output in outputs: total_amount += output.amount @@ -466,6 +464,10 @@ def _cborize_byron_witnesses( async def _show_standard_tx( ctx: wire.Context, keychain: seed.Keychain, msg: CardanoSignTx ) -> None: + is_network_id_verifiable = _is_network_id_verifiable(msg) + + if not is_network_id_verifiable: + await show_warning_tx_network_unverifiable(ctx) total_amount = await _show_outputs(ctx, keychain, msg) for certificate in msg.certificates: @@ -476,7 +478,13 @@ async def _show_standard_tx( has_metadata = bool(msg.metadata) await confirm_transaction( - ctx, total_amount, msg.fee, msg.protocol_magic, msg.ttl, has_metadata + ctx=ctx, + amount=total_amount, + fee=msg.fee, + protocol_magic=msg.protocol_magic, + ttl=msg.ttl, + has_metadata=has_metadata, + is_network_id_verifiable=is_network_id_verifiable, ) @@ -569,3 +577,16 @@ def _should_hide_output(output: List[int], inputs: List[CardanoTxInputType]) -> ): return False return True + + +def _is_network_id_verifiable(msg: CardanoSignTx) -> bool: + """ + checks whether there is at least one element that contains + information about network ID, otherwise Trezor cannot + guarantee that the tx is actually meant for the given network + """ + return ( + len(msg.outputs) != 0 + or len(msg.withdrawals) != 0 + or _has_stake_pool_registration(msg) + )