From 9113daa3a939ee0f72d1772f707120842fde99ec Mon Sep 17 00:00:00 2001 From: Francois Beutin Date: Thu, 18 Apr 2024 14:10:54 +0200 Subject: [PATCH] Tests: have a proper structure in the CAL to manage coin configuration --- test/python/apps/cal.py | 83 +++++++------------ test/python/apps/exchange_test_runner.py | 41 +++++---- .../apps/exchange_transaction_builder.py | 25 ------ test/python/test_bitcoin.py | 3 +- test/python/test_bsc.py | 15 ++-- test/python/test_ethereum.py | 4 +- test/python/test_extension.py | 11 ++- test/python/test_fake_signer.py | 28 +++---- test/python/test_flow_order.py | 24 +++--- test/python/test_input_robustness.py | 36 ++++---- test/python/test_polkadot.py | 3 +- test/python/test_ripple.py | 3 +- test/python/test_solana.py | 3 +- test/python/test_stellar.py | 3 +- test/python/test_tezos.py | 3 +- test/python/test_tron.py | 13 +-- 16 files changed, 128 insertions(+), 170 deletions(-) diff --git a/test/python/apps/cal.py b/test/python/apps/cal.py index 7f6ac738..d2165772 100644 --- a/test/python/apps/cal.py +++ b/test/python/apps/cal.py @@ -1,4 +1,5 @@ from typing import Optional +from dataclasses import dataclass from ragger.utils import prefix_with_len @@ -7,7 +8,7 @@ # Eth family from .ethereum import ETH_PACKED_DERIVATION_PATH, ETH_CONF from .ethereum import ETC_PACKED_DERIVATION_PATH, ETC_CONF -from .ethereum import BSC_PACKED_DERIVATION_PATH, BSC_CONF +from .ethereum import BSC_PACKED_DERIVATION_PATH, BSC_CONF, BSC_CONF_LEGACY from .litecoin import LTC_PACKED_DERIVATION_PATH, LTC_CONF from .bitcoin import BTC_PACKED_DERIVATION_PATH, BTC_CONF @@ -19,64 +20,44 @@ from .tron import TRX_PACKED_DERIVATION_PATH, TRX_CONF from .tron import TRX_USDT_CONF, TRX_USDC_CONF, TRX_TUSD_CONF, TRX_USDD_CONF -TICKER_ID_TO_CONF = { - "ETC": ETC_CONF, - "ETH": ETH_CONF, - "BTC": BTC_CONF, - "LTC": LTC_CONF, - "XLM": XLM_CONF, - "SOL": SOL_CONF, - "XRP": XRP_CONF, - "XTZ": XTZ_CONF, - "BNB": BSC_CONF, - "DOT": DOT_CONF, - "TRX": TRX_CONF, - "USDT": TRX_USDT_CONF, - "USDC": TRX_USDC_CONF, - "TUSD": TRX_TUSD_CONF, - "USDD": TRX_USDD_CONF, -} +@dataclass +class CurrencyConfiguration: + ticker: str + conf: bytes + packed_derivation_path: bytes + + # Get the correct coin configuration, can specify a signer to use instead of the correct ledger test one + def get_conf_for_ticker(self, overload_signer: Optional[SigningAuthority]=None) -> bytes: + currency_conf = self.conf + signed_conf = sign_currency_conf(currency_conf, overload_signer) + derivation_path = self.packed_derivation_path + return prefix_with_len(currency_conf) + signed_conf + prefix_with_len(derivation_path) + +ETC_CURRENCY_CONFIGURATION = CurrencyConfiguration(ticker="ETC", conf=ETC_CONF, packed_derivation_path=ETC_PACKED_DERIVATION_PATH) +ETH_CURRENCY_CONFIGURATION = CurrencyConfiguration(ticker="ETH", conf=ETH_CONF, packed_derivation_path=ETH_PACKED_DERIVATION_PATH) +BTC_CURRENCY_CONFIGURATION = CurrencyConfiguration(ticker="BTC", conf=BTC_CONF, packed_derivation_path=BTC_PACKED_DERIVATION_PATH) +LTC_CURRENCY_CONFIGURATION = CurrencyConfiguration(ticker="LTC", conf=LTC_CONF, packed_derivation_path=LTC_PACKED_DERIVATION_PATH) +XLM_CURRENCY_CONFIGURATION = CurrencyConfiguration(ticker="XLM", conf=XLM_CONF, packed_derivation_path=XLM_PACKED_DERIVATION_PATH) +SOL_CURRENCY_CONFIGURATION = CurrencyConfiguration(ticker="SOL", conf=SOL_CONF, packed_derivation_path=SOL_PACKED_DERIVATION_PATH) +XRP_CURRENCY_CONFIGURATION = CurrencyConfiguration(ticker="XRP", conf=XRP_CONF, packed_derivation_path=XRP_PACKED_DERIVATION_PATH) +XTZ_CURRENCY_CONFIGURATION = CurrencyConfiguration(ticker="XTZ", conf=XTZ_CONF, packed_derivation_path=XTZ_PACKED_DERIVATION_PATH) +BNB_CURRENCY_CONFIGURATION = CurrencyConfiguration(ticker="BNB", conf=BSC_CONF, packed_derivation_path=BSC_PACKED_DERIVATION_PATH) +BNB_LEGACY_CURRENCY_CONFIGURATION = CurrencyConfiguration(ticker="BNB", conf=BSC_CONF_LEGACY, packed_derivation_path=BSC_PACKED_DERIVATION_PATH) +DOT_CURRENCY_CONFIGURATION = CurrencyConfiguration(ticker="DOT", conf=DOT_CONF, packed_derivation_path=DOT_PACKED_DERIVATION_PATH) +TRX_CURRENCY_CONFIGURATION = CurrencyConfiguration(ticker="TRX", conf=TRX_CONF, packed_derivation_path=TRX_PACKED_DERIVATION_PATH) +USDT_CURRENCY_CONFIGURATION = CurrencyConfiguration(ticker="USDT", conf=TRX_USDT_CONF, packed_derivation_path=TRX_PACKED_DERIVATION_PATH) +USDC_CURRENCY_CONFIGURATION = CurrencyConfiguration(ticker="USDC", conf=TRX_USDC_CONF, packed_derivation_path=TRX_PACKED_DERIVATION_PATH) +TUSD_CURRENCY_CONFIGURATION = CurrencyConfiguration(ticker="TUSD", conf=TRX_TUSD_CONF, packed_derivation_path=TRX_PACKED_DERIVATION_PATH) +USDD_CURRENCY_CONFIGURATION = CurrencyConfiguration(ticker="USDD", conf=TRX_USDD_CONF, packed_derivation_path=TRX_PACKED_DERIVATION_PATH) -TICKER_ID_TO_PACKED_DERIVATION_PATH = { - "ETC": ETC_PACKED_DERIVATION_PATH, - "ETH": ETH_PACKED_DERIVATION_PATH, - "BTC": BTC_PACKED_DERIVATION_PATH, - "LTC": LTC_PACKED_DERIVATION_PATH, - "XLM": XLM_PACKED_DERIVATION_PATH, - "SOL": SOL_PACKED_DERIVATION_PATH, - "XRP": XRP_PACKED_DERIVATION_PATH, - "XTZ": XTZ_PACKED_DERIVATION_PATH, - "BNB": BSC_PACKED_DERIVATION_PATH, - "DOT": DOT_PACKED_DERIVATION_PATH, - "TRX": TRX_PACKED_DERIVATION_PATH, - "USDT": TRX_PACKED_DERIVATION_PATH, - "USDC": TRX_PACKED_DERIVATION_PATH, - "TUSD": TRX_PACKED_DERIVATION_PATH, - "USDD": TRX_PACKED_DERIVATION_PATH, -} - -# Helper that can be called from outside if we want to generate errors easily -def get_currency_conf(ticker_id: str) -> bytes: - return TICKER_ID_TO_CONF[ticker_id] # Helper that can be called from outside if we want to generate errors easily def sign_currency_conf(currency_conf: bytes, overload_signer: Optional[SigningAuthority]=None) -> bytes: - if overload_signer: + if overload_signer is not None: signer = overload_signer else: signer = LEDGER_SIGNER return signer.sign(currency_conf) -# Helper that can be called from outside if we want to generate errors easily -def get_derivation_path(ticker_id: str) -> bytes: - return TICKER_ID_TO_PACKED_DERIVATION_PATH[ticker_id] -# Get the correct coin configuration, can specify a signer to use instead of the correct ledger test one -def get_conf_for_ticker(ticker_id: str, overload_signer: Optional[SigningAuthority]=None) -> bytes: - if ticker_id is None: - return None - currency_conf = get_currency_conf(ticker_id) - signed_conf = sign_currency_conf(currency_conf, overload_signer) - derivation_path = get_derivation_path(ticker_id) - return prefix_with_len(currency_conf) + signed_conf + prefix_with_len(derivation_path) diff --git a/test/python/apps/exchange_test_runner.py b/test/python/apps/exchange_test_runner.py index 417438e5..0b49e6b2 100644 --- a/test/python/apps/exchange_test_runner.py +++ b/test/python/apps/exchange_test_runner.py @@ -6,7 +6,7 @@ from ragger.error import ExceptionRAPDU from .exchange import ExchangeClient, Rate, SubCommand, Errors -from .exchange_transaction_builder import get_partner_curve, extract_payout_ticker, extract_refund_ticker, get_credentials, craft_and_sign_tx +from .exchange_transaction_builder import get_partner_curve, get_credentials, craft_and_sign_tx from . import cal as cal from .signing_authority import SigningAuthority, LEDGER_SIGNER @@ -21,7 +21,7 @@ class ExchangeTestRunner: # You will need to define the following elements in the child application: - # currency_ticker: str + # currency_configuration: CurrencyConfiguration # valid_destination_1: str # valid_destination_memo_1: str # valid_destination_2: str @@ -87,7 +87,7 @@ def run_test(self, function_to_test: str): self.exchange_navigation_helper.set_test_name_suffix("_" + function_to_test) getattr(self, TEST_METHOD_PREFIX + function_to_test)(use_legacy_flow) - def _perform_valid_exchange(self, subcommand, tx_infos, fees, ui_validation): + def _perform_valid_exchange(self, subcommand, tx_infos, from_currency_configuration, to_currency_configuration, fees, ui_validation): # Initialize the exchange client plugin that will format and send the APDUs to the device ex = ExchangeClient(self.backend, Rate.FIXED, subcommand) @@ -109,18 +109,15 @@ def _perform_valid_exchange(self, subcommand, tx_infos, fees, ui_validation): ex.process_transaction(tx) ex.check_transaction_signature(tx_signature) - # Ask our fake CAL the coin configuration for both payout and refund tickers (None for refund in case of FUND or SELL) - payout_ticker = extract_payout_ticker(subcommand, tx_infos) - payout_configuration = cal.get_conf_for_ticker(payout_ticker) + # Ask our fake CAL the coin configuration for both FROM and TO currencies (None for TO in case of FUND or SELL) + from_configuration = cal.get_conf_for_ticker(from_currency_configuration) + to_configuration = cal.get_conf_for_ticker(to_currency_configuration) if subcommand == SubCommand.SWAP or subcommand == SubCommand.SWAP_NG: - ex.check_payout_address(payout_configuration) - - refund_ticker = extract_refund_ticker(subcommand, tx_infos) - refund_configuration = cal.get_conf_for_ticker(refund_ticker) + ex.check_payout_address(to_configuration) # Request the final address check and UI approval request on the device - with ex.check_refund_address(refund_configuration): + with ex.check_refund_address(from_configuration): if ui_validation: self.exchange_navigation_helper.simple_accept() else: @@ -129,7 +126,7 @@ def _perform_valid_exchange(self, subcommand, tx_infos, fees, ui_validation): # As a workaround, we avoid calling the navigation if we want the function to raise pass else: - with ex.check_asset_in(payout_configuration): + with ex.check_asset_in(from_configuration): if ui_validation: self.exchange_navigation_helper.simple_accept() else: @@ -152,13 +149,13 @@ def perform_valid_swap_from_custom(self, destination, send_amount, fees, memo, r "refund_extra_id": refund_memo.encode(), "payout_address": b"0xDad77910DbDFdE764fC21FCD4E74D71bBACA6D8D", # Default "payout_extra_id": b"", # Default - "currency_from": self.currency_ticker, - "currency_to": "ETH", # Default + "currency_from": self.currency_configuration.ticker, + "currency_to": cal.ETH_CURRENCY_CONFIGURATION.ticker, "amount_to_provider": int_to_minimally_sized_bytes(send_amount), "amount_to_wallet": b"\246\333t\233+\330\000", # Default } subcommand = SubCommand.SWAP if legacy else SubCommand.SWAP_NG - self._perform_valid_exchange(subcommand, tx_infos, fees, ui_validation=ui_validation) + self._perform_valid_exchange(subcommand, tx_infos, self.currency_configuration, cal.ETH_CURRENCY_CONFIGURATION, fees, ui_validation=ui_validation) def perform_valid_swap_to_custom(self, destination, send_amount, fees, memo, ui_validation=True, legacy=False): tx_infos = { @@ -168,36 +165,36 @@ def perform_valid_swap_to_custom(self, destination, send_amount, fees, memo, ui_ "refund_extra_id": "", # Default "payout_address": destination, "payout_extra_id": memo.encode(), - "currency_from": "ETH", # Default - "currency_to": self.currency_ticker, + "currency_from": cal.ETH_CURRENCY_CONFIGURATION.ticker, + "currency_to": self.currency_configuration.ticker, "amount_to_provider": int_to_minimally_sized_bytes(send_amount), "amount_to_wallet": b"\246\333t\233+\330\000", # Default } subcommand = SubCommand.SWAP if legacy else SubCommand.SWAP_NG - self._perform_valid_exchange(subcommand, tx_infos, fees, ui_validation=ui_validation) + self._perform_valid_exchange(subcommand, tx_infos, cal.ETH_CURRENCY_CONFIGURATION, self.currency_configuration, fees, ui_validation=ui_validation) def perform_valid_fund_from_custom(self, destination, send_amount, fees, legacy=False): tx_infos = { "user_id": self.fund_user_id, "account_name": self.fund_account_name, - "in_currency": self.currency_ticker, + "in_currency": self.currency_configuration.ticker, "in_amount": int_to_minimally_sized_bytes(send_amount), "in_address": destination, } subcommand = SubCommand.FUND if legacy else SubCommand.FUND_NG - self._perform_valid_exchange(subcommand, tx_infos, fees, ui_validation=True) + self._perform_valid_exchange(subcommand, tx_infos, self.currency_configuration, None, fees, ui_validation=True) def perform_valid_sell_from_custom(self, destination, send_amount, fees, legacy=False): tx_infos = { "trader_email": self.sell_trader_email, "out_currency": self.sell_out_currency, "out_amount": self.sell_out_amount, - "in_currency": self.currency_ticker, + "in_currency": self.currency_configuration.ticker, "in_amount": int_to_minimally_sized_bytes(send_amount), "in_address": destination, } subcommand = SubCommand.SELL if legacy else SubCommand.SELL_NG - self._perform_valid_exchange(subcommand, tx_infos, fees, ui_validation=True) + self._perform_valid_exchange(subcommand, tx_infos, self.currency_configuration, None, fees, ui_validation=True) # Implement this function for each tested coin def perform_final_tx(self, destination, send_amount, fees, memo): diff --git a/test/python/apps/exchange_transaction_builder.py b/test/python/apps/exchange_transaction_builder.py index eee09d2a..954508d1 100644 --- a/test/python/apps/exchange_transaction_builder.py +++ b/test/python/apps/exchange_transaction_builder.py @@ -54,8 +54,6 @@ class SubCommandSpecs: transaction_type: Callable required_fields: Iterable[str] transaction_id_field: str - payout_field: str - refund_field: Optional[str] @property def dot_prefix(self): @@ -133,8 +131,6 @@ def encode_transaction_signature(self, signer: SigningAuthority, tx: bytes) -> b "payout_address", "payout_extra_id", "currency_from", "currency_to", "amount_to_provider", "amount_to_wallet"], transaction_id_field = "device_transaction_id_ng", - payout_field = "currency_to", - refund_field = "currency_from", ) SWAP_SPECS = SubCommandSpecs( @@ -148,8 +144,6 @@ def encode_transaction_signature(self, signer: SigningAuthority, tx: bytes) -> b "payout_address", "payout_extra_id", "currency_from", "currency_to", "amount_to_provider", "amount_to_wallet"], transaction_id_field = "device_transaction_id", - payout_field = "currency_to", - refund_field = "currency_from", ) SELL_NG_SPECS = SubCommandSpecs( @@ -161,8 +155,6 @@ def encode_transaction_signature(self, signer: SigningAuthority, tx: bytes) -> b transaction_type = NewSellResponse, transaction_id_field = "device_transaction_id", required_fields = ["trader_email", "in_currency", "in_amount", "in_address", "out_currency", "out_amount"], - payout_field = "in_currency", - refund_field = None, ) SELL_SPECS = SubCommandSpecs( @@ -174,8 +166,6 @@ def encode_transaction_signature(self, signer: SigningAuthority, tx: bytes) -> b transaction_type = NewSellResponse, transaction_id_field = "device_transaction_id", required_fields = ["trader_email", "in_currency", "in_amount", "in_address", "out_currency", "out_amount"], - payout_field = "in_currency", - refund_field = None, ) FUND_NG_SPECS = SubCommandSpecs( @@ -187,8 +177,6 @@ def encode_transaction_signature(self, signer: SigningAuthority, tx: bytes) -> b transaction_type = NewFundResponse, required_fields = ["user_id", "account_name", "in_currency", "in_amount", "in_address"], transaction_id_field = "device_transaction_id", - payout_field = "in_currency", - refund_field = None, ) FUND_SPECS = SubCommandSpecs( @@ -200,8 +188,6 @@ def encode_transaction_signature(self, signer: SigningAuthority, tx: bytes) -> b transaction_type = NewFundResponse, required_fields = ["user_id", "account_name", "in_currency", "in_amount", "in_address"], transaction_id_field = "device_transaction_id", - payout_field = "in_currency", - refund_field = None, ) SUBCOMMAND_TO_SPECS = { @@ -223,17 +209,6 @@ def craft_and_sign_tx(subcommand: Union[SubCommand, SubCommandSpecs], tx_infos: signed_tx = subcommand_specs.encode_transaction_signature(signer, pb) return tx, signed_tx -def extract_payout_ticker(subcommand: SubCommand, tx_infos: Dict) -> str: - subcommand_specs = SUBCOMMAND_TO_SPECS[subcommand] - return tx_infos[subcommand_specs.payout_field] - -def extract_refund_ticker(subcommand: SubCommand, tx_infos: Dict) -> Optional[str]: - subcommand_specs = SUBCOMMAND_TO_SPECS[subcommand] - if subcommand_specs.refund_field: - return tx_infos[subcommand_specs.refund_field] - else: - return None - def get_partner_curve(subcommand: SubCommand) -> ec.EllipticCurve: return SUBCOMMAND_TO_SPECS[subcommand].partner_curve diff --git a/test/python/test_bitcoin.py b/test/python/test_bitcoin.py index 956c129a..111cc01b 100644 --- a/test/python/test_bitcoin.py +++ b/test/python/test_bitcoin.py @@ -2,6 +2,7 @@ from .apps.exchange_test_runner import ExchangeTestRunner, ALL_TESTS_EXCEPT_MEMO from .apps.bitcoin import BitcoinClient, BitcoinErrors +from .apps import cal as cal from ledger_bitcoin import WalletPolicy in_wallet = WalletPolicy( @@ -31,7 +32,7 @@ # ExchangeTestRunner implementation for Bitcoin class BitcoinTests(ExchangeTestRunner): - currency_ticker = "BTC" + currency_configuration = cal.BTC_CURRENCY_CONFIGURATION valid_destination_1 = BitcoinClient.get_address_from_wallet(out_wallet) valid_destination_memo_1 = "" valid_destination_2 = BitcoinClient.get_address_from_wallet(out_wallet_2) diff --git a/test/python/test_bsc.py b/test/python/test_bsc.py index 6f643f73..eb711520 100644 --- a/test/python/test_bsc.py +++ b/test/python/test_bsc.py @@ -1,14 +1,14 @@ import pytest from .apps.exchange_test_runner import ExchangeTestRunner, ALL_TESTS_EXCEPT_MEMO -from .apps.ethereum import ETH_PATH, BSC_CONF_LEGACY +from .apps.ethereum import ETH_PATH from ledger_app_clients.ethereum.client import EthAppClient -from .apps.cal import TICKER_ID_TO_CONF +from .apps import cal as cal # ExchangeTestRunner implementation for BSC class BSCTests(ExchangeTestRunner): - currency_ticker = "BNB" + currency_configuration = cal.BNB_CURRENCY_CONFIGURATION valid_destination_1 = "0xd692Cb1346262F584D17B4B470954501f6715a82" valid_destination_memo_1 = "" valid_destination_2 = "0x999999cf1046e68e36E1aA2E0E07105eDDD1f08E" @@ -42,7 +42,10 @@ def perform_final_tx(self, destination, send_amount, fees, memo): # TODO : assert signature validity -# Use a class to reuse the same Speculos instance +class BSCLegacyTests(BSCTests): + currency_configuration = cal.BNB_LEGACY_CURRENCY_CONFIGURATION + + class TestsBSC: @pytest.mark.parametrize('test_to_run', ALL_TESTS_EXCEPT_MEMO) def test_bsc(self, backend, exchange_navigation_helper, test_to_run): @@ -52,6 +55,4 @@ def test_bsc(self, backend, exchange_navigation_helper, test_to_run): class TestsBSCLegacy: @pytest.mark.parametrize('test_to_run', ALL_TESTS_EXCEPT_MEMO) def test_bsc_legacy(self, backend, exchange_navigation_helper, test_to_run): - # Override CAL to emulate legacy behaviour (use clone instead of Ethereum app) - TICKER_ID_TO_CONF["BNB"] = BSC_CONF_LEGACY - BSCTests(backend, exchange_navigation_helper).run_test(test_to_run) + BSCLegacyTests(backend, exchange_navigation_helper).run_test(test_to_run) diff --git a/test/python/test_ethereum.py b/test/python/test_ethereum.py index 95397eaf..d5eba3bc 100644 --- a/test/python/test_ethereum.py +++ b/test/python/test_ethereum.py @@ -3,12 +3,12 @@ from .apps.exchange_test_runner import ExchangeTestRunner, ALL_TESTS_EXCEPT_MEMO from .apps.ethereum import ETH_PATH from ledger_app_clients.ethereum.client import EthAppClient -from web3 import Web3 +from .apps import cal as cal # ExchangeTestRunner implementation for Ethereum class EthereumTests(ExchangeTestRunner): - currency_ticker = "ETH" + currency_configuration = cal.ETH_CURRENCY_CONFIGURATION valid_destination_1 = "0xd692Cb1346262F584D17B4B470954501f6715a82" valid_destination_memo_1 = "" valid_destination_2 = "0x999999cf1046e68e36E1aA2E0E07105eDDD1f08E" diff --git a/test/python/test_extension.py b/test/python/test_extension.py index c07e1b4e..16ae68cc 100644 --- a/test/python/test_extension.py +++ b/test/python/test_extension.py @@ -8,6 +8,9 @@ from .apps.signing_authority import SigningAuthority, LEDGER_SIGNER from .apps import cal as cal +CURRENCY_FROM = cal.ETH_CURRENCY_CONFIGURATION +CURRENCY_TO = cal.BTC_CURRENCY_CONFIGURATION + # Some valid infos for TX. Content is irrelevant for the test SWAP_TX_INFOS = { @@ -17,15 +20,15 @@ "refund_extra_id": b"", "payout_address": b"bc1qqtl9jlrwcr3fsfcjj2du7pu6fcgaxl5dsw2vyg", "payout_extra_id": b"", - "currency_from": "ETH", - "currency_to": "BTC", + "currency_from": CURRENCY_FROM.ticker, + "currency_to": CURRENCY_TO.ticker, "amount_to_provider": bytes.fromhex("013fc3a717fb5000"), "amount_to_wallet": b"\x0b\xeb\xc2\x00", } FUND_TX_INFOS = { "user_id": "John Wick", "account_name": "Remember Daisy", - "in_currency": "ETH", + "in_currency": CURRENCY_FROM.ticker, "in_amount": b"\032\200\250]$T\000", "in_address": "0x252fb4acbe0de4f0bd2409a5ed59a71e4ef1d2bc" } @@ -33,7 +36,7 @@ "trader_email": "john@doe.lost", "out_currency": "USD", "out_amount": {"coefficient": b"\x01", "exponent": 3}, - "in_currency": "ETH", + "in_currency": CURRENCY_FROM.ticker, "in_amount": b"\032\200\250]$T\000", "in_address": "0x252fb4acbe0de4f0bd2409a5ed59a71e4ef1d2bc" } diff --git a/test/python/test_fake_signer.py b/test/python/test_fake_signer.py index 355dd43f..8762673f 100644 --- a/test/python/test_fake_signer.py +++ b/test/python/test_fake_signer.py @@ -4,11 +4,13 @@ from ragger.error import ExceptionRAPDU from .apps.exchange import ExchangeClient, Rate, SubCommand, Errors -from .apps.exchange_transaction_builder import get_partner_curve, extract_payout_ticker, extract_refund_ticker, ALL_SUBCOMMANDS, SWAP_SUBCOMMANDS, get_credentials, craft_and_sign_tx +from .apps.exchange_transaction_builder import get_partner_curve, ALL_SUBCOMMANDS, SWAP_SUBCOMMANDS, get_credentials, craft_and_sign_tx from .apps import cal as cal from .apps.signing_authority import SigningAuthority, LEDGER_SIGNER +CURRENCY_FROM = cal.ETH_CURRENCY_CONFIGURATION +CURRENCY_TO = cal.BTC_CURRENCY_CONFIGURATION SWAP_TX_INFOS = { "payin_address": b"0xd692Cb1346262F584D17B4B470954501f6715a82", @@ -17,8 +19,8 @@ "refund_extra_id": b"", "payout_address": b"bc1qqtl9jlrwcr3fsfcjj2du7pu6fcgaxl5dsw2vyg", "payout_extra_id": b"", - "currency_from": "ETH", - "currency_to": "BTC", + "currency_from": CURRENCY_FROM.ticker, + "currency_to": CURRENCY_TO.ticker, "amount_to_provider": bytes.fromhex("013fc3a717fb5000"), "amount_to_wallet": b"\x0b\xeb\xc2\x00", } @@ -26,7 +28,7 @@ FUND_TX_INFOS = { "user_id": "John Wick", "account_name": "Remember Daisy", - "in_currency": "ETH", + "in_currency": CURRENCY_FROM.ticker, "in_amount": b"\032\200\250]$T\000", "in_address": "0x252fb4acbe0de4f0bd2409a5ed59a71e4ef1d2bc" } @@ -35,7 +37,7 @@ "trader_email": "john@doe.lost", "out_currency": "USD", "out_amount": {"coefficient": b"\x01", "exponent": 3}, - "in_currency": "ETH", + "in_currency": CURRENCY_FROM.ticker, "in_amount": b"\032\200\250]$T\000", "in_address": "0x252fb4acbe0de4f0bd2409a5ed59a71e4ef1d2bc" } @@ -126,14 +128,11 @@ def test_fake_payout_coin_configuration(self, backend, subcommand): ex.process_transaction(tx) ex.check_transaction_signature(tx_signature) - payout_ticker = extract_payout_ticker(subcommand, TX_INFOS[subcommand]) - payout_conf = cal.get_conf_for_ticker(payout_ticker, overload_signer=ledger_fake_signer) - with pytest.raises(ExceptionRAPDU) as e: if subcommand == SubCommand.SWAP or subcommand == SubCommand.SWAP_NG: - ex.check_payout_address(payout_conf) + ex.check_payout_address(cal.get_conf_for_ticker(CURRENCY_TO, overload_signer=ledger_fake_signer)) else: - with ex.check_asset_in(payout_conf): + with ex.check_asset_in(cal.get_conf_for_ticker(CURRENCY_FROM, overload_signer=ledger_fake_signer)): pass assert e.value.status == Errors.SIGN_VERIFICATION_FAIL @@ -151,14 +150,9 @@ def test_fake_refund_coin_configuration_swap(self, backend, subcommand): ex.process_transaction(tx) ex.check_transaction_signature(tx_signature) - payout_ticker = extract_payout_ticker(subcommand, TX_INFOS[subcommand]) - payout_conf = cal.get_conf_for_ticker(payout_ticker) - ex.check_payout_address(payout_conf) - - refund_ticker = extract_refund_ticker(subcommand, TX_INFOS[subcommand]) - refund_conf = cal.get_conf_for_ticker(refund_ticker, overload_signer=ledger_fake_signer) + ex.check_payout_address(cal.get_conf_for_ticker(CURRENCY_TO)) with pytest.raises(ExceptionRAPDU) as e: - with ex.check_refund_address(refund_conf): + with ex.check_refund_address(cal.get_conf_for_ticker(CURRENCY_FROM, overload_signer=ledger_fake_signer)): pass assert e.value.status == Errors.SIGN_VERIFICATION_FAIL diff --git a/test/python/test_flow_order.py b/test/python/test_flow_order.py index a90edcb9..1aeb1bed 100644 --- a/test/python/test_flow_order.py +++ b/test/python/test_flow_order.py @@ -5,10 +5,13 @@ from ragger.error import ExceptionRAPDU from .apps.exchange import ExchangeClient, Rate, SubCommand, Errors, Command, P2_EXTEND, P2_MORE, EXCHANGE_CLASS -from .apps.exchange_transaction_builder import get_partner_curve, extract_payout_ticker, extract_refund_ticker, LEGACY_SUBCOMMANDS, ALL_SUBCOMMANDS, NEW_SUBCOMMANDS, get_credentials, craft_and_sign_tx +from .apps.exchange_transaction_builder import get_partner_curve, LEGACY_SUBCOMMANDS, ALL_SUBCOMMANDS, NEW_SUBCOMMANDS, get_credentials, craft_and_sign_tx from .apps.signing_authority import SigningAuthority, LEDGER_SIGNER from .apps import cal as cal +CURRENCY_FROM = cal.ETH_CURRENCY_CONFIGURATION +CURRENCY_TO = cal.BTC_CURRENCY_CONFIGURATION + # Some valid infos for TX. Content is irrelevant for the test SWAP_TX_INFOS = { @@ -18,15 +21,15 @@ "refund_extra_id": b"", "payout_address": b"bc1qqtl9jlrwcr3fsfcjj2du7pu6fcgaxl5dsw2vyg", "payout_extra_id": b"", - "currency_from": "ETH", - "currency_to": "BTC", + "currency_from": CURRENCY_FROM.ticker, + "currency_to": CURRENCY_TO.ticker, "amount_to_provider": bytes.fromhex("013fc3a717fb5000"), "amount_to_wallet": b"\x0b\xeb\xc2\x00", } FUND_TX_INFOS = { "user_id": "John Wick", "account_name": "Remember Daisy", - "in_currency": "ETH", + "in_currency": CURRENCY_FROM.ticker, "in_amount": b"\032\200\250]$T\000", "in_address": "0x252fb4acbe0de4f0bd2409a5ed59a71e4ef1d2bc" } @@ -34,7 +37,7 @@ "trader_email": "john@doe.lost", "out_currency": "USD", "out_amount": {"coefficient": b"\x01", "exponent": 3}, - "in_currency": "ETH", + "in_currency": CURRENCY_FROM.ticker, "in_amount": b"\032\200\250]$T\000", "in_address": "0x252fb4acbe0de4f0bd2409a5ed59a71e4ef1d2bc" } @@ -101,24 +104,19 @@ def test_wrong_flow_order(backend, subcommand, exchange_navigation_helper): try_all_commands_for_subcommand_except(ex, subcommand, Command.CHECK_TRANSACTION_SIGNATURE) ex.check_transaction_signature(tx_signature) - payout_ticker = extract_payout_ticker(subcommand, tx_infos) - payout_configuration = cal.get_conf_for_ticker(payout_ticker) - if subcommand == SubCommand.SWAP or subcommand == SubCommand.SWAP_NG: try_all_commands_for_subcommand_except(ex, subcommand, Command.CHECK_PAYOUT_ADDRESS) - ex.check_payout_address(payout_configuration) + ex.check_payout_address(cal.get_conf_for_ticker(CURRENCY_TO)) try_all_commands_for_subcommand_except(ex, subcommand, Command.CHECK_REFUND_ADDRESS) - refund_ticker = extract_refund_ticker(subcommand, tx_infos) - refund_configuration = cal.get_conf_for_ticker(refund_ticker) - with ex.check_refund_address(refund_configuration): + with ex.check_refund_address(cal.get_conf_for_ticker(CURRENCY_FROM)): exchange_navigation_helper.simple_accept() else: if subcommand == SubCommand.FUND or subcommand == SubCommand.SELL: try_all_commands_for_subcommand_except(ex, subcommand, Command.CHECK_ASSET_IN_LEGACY) else: try_all_commands_for_subcommand_except(ex, subcommand, Command.CHECK_ASSET_IN) - with ex.check_asset_in(payout_configuration): + with ex.check_asset_in(cal.get_conf_for_ticker(CURRENCY_FROM)): exchange_navigation_helper.simple_accept() try_all_commands_for_subcommand_except(ex, subcommand, Command.START_SIGNING_TRANSACTION) diff --git a/test/python/test_input_robustness.py b/test/python/test_input_robustness.py index 09c8069c..8e0f0bfd 100644 --- a/test/python/test_input_robustness.py +++ b/test/python/test_input_robustness.py @@ -6,6 +6,8 @@ from .apps.signing_authority import SigningAuthority, LEDGER_SIGNER from .apps import cal as cal +CURRENCY_FROM = cal.XLM_CURRENCY_CONFIGURATION +CURRENCY_TO = cal.ETH_CURRENCY_CONFIGURATION class TestRobustnessSET_PARTNER_KEY: @@ -48,8 +50,8 @@ class TestRobustnessCHECK_ADDRESS: "refund_extra_id": b"", "payout_address": b"0xDad77910DbDFdE764fC21FCD4E74D71bBACA6D8D", "payout_extra_id": b"", - "currency_from": "XLM", - "currency_to": "ETH", + "currency_from": CURRENCY_FROM.ticker, + "currency_to": CURRENCY_TO.ticker, "amount_to_provider": int.to_bytes(1000, length=8, byteorder='big'), "amount_to_wallet": b"\246\333t\233+\330\000", } @@ -67,12 +69,12 @@ def _restart_test(self, backend, ex): def test_robustness_check_payout_address(self, backend): ex = ExchangeClient(backend, Rate.FIXED, SubCommand.SWAP) - payout_currency_conf = cal.get_currency_conf(self.tx_infos["currency_to"]) + payout_currency_conf = CURRENCY_TO.conf signed_payout_conf = cal.sign_currency_conf(payout_currency_conf) - payout_currency_derivation_path = cal.get_derivation_path(self.tx_infos["currency_to"]) - refund_currency_conf = cal.get_currency_conf(self.tx_infos["currency_from"]) + payout_currency_derivation_path = CURRENCY_TO.packed_derivation_path + refund_currency_conf = CURRENCY_FROM.conf signed_refund_conf = cal.sign_currency_conf(refund_currency_conf) - refund_currency_derivation_path = cal.get_derivation_path(self.tx_infos["currency_from"]) + refund_currency_derivation_path = CURRENCY_FROM.packed_derivation_path payloads_to_test = ( # Nothing @@ -97,12 +99,12 @@ def test_robustness_check_payout_address(self, backend): def test_robustness_check_refund_address(self, backend): ex = ExchangeClient(backend, Rate.FIXED, SubCommand.SWAP) - payout_currency_conf = cal.get_currency_conf(self.tx_infos["currency_to"]) + payout_currency_conf = CURRENCY_TO.conf signed_payout_conf = cal.sign_currency_conf(payout_currency_conf) - payout_currency_derivation_path = cal.get_derivation_path(self.tx_infos["currency_to"]) - refund_currency_conf = cal.get_currency_conf(self.tx_infos["currency_from"]) + payout_currency_derivation_path = CURRENCY_TO.packed_derivation_path + refund_currency_conf = CURRENCY_FROM.conf signed_refund_conf = cal.sign_currency_conf(refund_currency_conf) - refund_currency_derivation_path = cal.get_derivation_path(self.tx_infos["currency_from"]) + refund_currency_derivation_path = CURRENCY_FROM.packed_derivation_path payloads_to_test = ( # Nothing @@ -149,7 +151,7 @@ def test_robustness_coin_configuration(self, backend): for conf in currency_conf_to_test: backend.raise_policy = RaisePolicy.RAISE_ALL_BUT_0x9000 self._restart_test(backend, ex) - payload = prefix_with_len(conf) + cal.sign_currency_conf(conf) + prefix_with_len(cal.get_derivation_path(self.tx_infos["currency_to"])) + payload = prefix_with_len(conf) + cal.sign_currency_conf(conf) + prefix_with_len(CURRENCY_TO.packed_derivation_path) backend.raise_policy = RaisePolicy.RAISE_NOTHING rapdu = ex._exchange(Command.CHECK_PAYOUT_ADDRESS, payload=payload) assert rapdu.status == Errors.INCORRECT_COMMAND_DATA @@ -169,8 +171,8 @@ def test_currency_normalization_correct(self, backend): for payout_conf in payout_currency_conf_to_test: for refund_conf in refund_currency_conf_to_test: - payout_payload = prefix_with_len(payout_conf) + cal.sign_currency_conf(payout_conf) + prefix_with_len(cal.get_derivation_path(self.tx_infos["currency_to"])) - refund_payload = prefix_with_len(refund_conf) + cal.sign_currency_conf(refund_conf) + prefix_with_len(cal.get_derivation_path(self.tx_infos["currency_from"])) + payout_payload = prefix_with_len(payout_conf) + cal.sign_currency_conf(payout_conf) + prefix_with_len(CURRENCY_TO.packed_derivation_path) + refund_payload = prefix_with_len(refund_conf) + cal.sign_currency_conf(refund_conf) + prefix_with_len(CURRENCY_FROM.packed_derivation_path) backend.raise_policy = RaisePolicy.RAISE_ALL_BUT_0x9000 self._restart_test(backend, ex) @@ -193,7 +195,7 @@ def test_currency_normalization_incorrect(self, backend): for conf in currency_conf_to_test: backend.raise_policy = RaisePolicy.RAISE_ALL_BUT_0x9000 self._restart_test(backend, ex) - payout_payload = prefix_with_len(conf) + cal.sign_currency_conf(conf) + prefix_with_len(cal.get_derivation_path(self.tx_infos["currency_to"])) + payout_payload = prefix_with_len(conf) + cal.sign_currency_conf(conf) + prefix_with_len(CURRENCY_TO.packed_derivation_path) backend.raise_policy = RaisePolicy.RAISE_NOTHING rapdu = ex._exchange(Command.CHECK_PAYOUT_ADDRESS, payload=payout_payload) assert rapdu.status == Errors.INCORRECT_COMMAND_DATA @@ -224,7 +226,7 @@ def test_currency_normalization_fund(backend, exchange_navigation_helper): ex.process_transaction(tx) ex.check_transaction_signature(tx_signature) - payload = prefix_with_len(conf) + cal.sign_currency_conf(conf) + prefix_with_len(cal.get_derivation_path(tx_infos["in_currency"])) + payload = prefix_with_len(conf) + cal.sign_currency_conf(conf) + prefix_with_len(CURRENCY_TO.packed_derivation_path) backend.raise_policy = RaisePolicy.RAISE_NOTHING with ex._exchange_async(Command.CHECK_PAYOUT_ADDRESS, payload=payload): exchange_navigation_helper.simple_accept() @@ -248,7 +250,7 @@ def test_currency_alias(self, backend): } fees = 100 - bsc_conf = cal.get_currency_conf(tx_infos["currency_to"]) # "Binance Smart Chain" + bsc_conf = cal.BNB_CURRENCY_CONFIGURATION.conf # "Binance Smart Chain" bsc_conf_alias_1 = create_currency_config("BNB", "bsc", ("BNB", 18)) bsc_conf_alias_2 = create_currency_config("BNB", "Bsc", ("BNB", 18)) for conf in bsc_conf, bsc_conf_alias_1, bsc_conf_alias_2: @@ -262,5 +264,5 @@ def test_currency_alias(self, backend): ex.check_transaction_signature(tx_signature) # If the alias does not work, CHECK_PAYOUT_ADDRESS will crash - payload = prefix_with_len(conf) + LEDGER_SIGNER.sign(conf) + prefix_with_len(cal.get_derivation_path(tx_infos["currency_to"])) + payload = prefix_with_len(conf) + LEDGER_SIGNER.sign(conf) + prefix_with_len(CURRENCY_TO.packed_derivation_path) ex._exchange(Command.CHECK_PAYOUT_ADDRESS, payload=payload) diff --git a/test/python/test_polkadot.py b/test/python/test_polkadot.py index b8385c73..df63e9b3 100644 --- a/test/python/test_polkadot.py +++ b/test/python/test_polkadot.py @@ -2,10 +2,11 @@ from .apps.exchange_test_runner import ExchangeTestRunner, ALL_TESTS_EXCEPT_MEMO_AND_FEES from .apps.polkadot import PolkadotClient, ERR_SWAP_CHECK_WRONG_METHOD, ERR_SWAP_CHECK_WRONG_DEST_ADDR, ERR_SWAP_CHECK_WRONG_AMOUNT +from .apps import cal as cal # ExchangeTestRunner implementation for Polkadot class PolkadotTests(ExchangeTestRunner): - currency_ticker = "DOT" + currency_configuration = cal.DOT_CURRENCY_CONFIGURATION valid_destination_1 = "14ypt3a2m9yiq4ZQDcJFrkD99C3ZoUjLCDz1gBpCDwJPqVDY" valid_destination_memo_1 = "" valid_destination_2 = "13zAiMiN2HdJfEXn4NkVCWxuemScdaXGYKJrbJr1Nt6kjBRD" diff --git a/test/python/test_ripple.py b/test/python/test_ripple.py index 517eeb31..e9e8cfde 100644 --- a/test/python/test_ripple.py +++ b/test/python/test_ripple.py @@ -2,10 +2,11 @@ from .apps.exchange_test_runner import ExchangeTestRunner, SWAP_TESTS from .apps.xrp import XRPClient, DEFAULT_PATH, XRP_PACKED_DERIVATION_PATH, RippleErrors +from .apps import cal as cal # ExchangeTestRunner implementation for Stellar class RippleTests(ExchangeTestRunner): - currency_ticker = "XRP" + currency_configuration = cal.XRP_CURRENCY_CONFIGURATION valid_destination_1 = "ra7Zr8ddy9tB88RaXL8B87YkqhEJG2vkAJ" valid_destination_memo_1 = "0" valid_destination_2 = "rhBuYom8agWA4s7DFoM7AvsDA9XGkVCJz4" diff --git a/test/python/test_solana.py b/test/python/test_solana.py index 75c13f58..3f78907e 100644 --- a/test/python/test_solana.py +++ b/test/python/test_solana.py @@ -5,6 +5,7 @@ from .apps.solana_utils import SOL_PACKED_DERIVATION_PATH from .apps.solana_cmd_builder import SystemInstructionTransfer, Message, verify_signature from .apps import solana_utils as SOL +from .apps import cal as cal # A bit hacky but way less hassle than actually writing an actual address decoder SOLANA_ADDRESS_DECODER = { @@ -14,7 +15,7 @@ # ExchangeTestRunner implementation for Stellar class SolanaTests(ExchangeTestRunner): - currency_ticker = "SOL" + currency_configuration = cal.SOL_CURRENCY_CONFIGURATION valid_destination_1 = SOL.FOREIGN_ADDRESS valid_destination_memo_1 = "" valid_destination_2 = SOL.FOREIGN_ADDRESS_2 diff --git a/test/python/test_stellar.py b/test/python/test_stellar.py index 7180925d..40efa9f0 100644 --- a/test/python/test_stellar.py +++ b/test/python/test_stellar.py @@ -2,10 +2,11 @@ from .apps.exchange_test_runner import ExchangeTestRunner, ALL_TESTS from .apps.stellar import Network, StellarClient, StellarErrors +from .apps import cal as cal # ExchangeTestRunner implementation for Stellar class StellarTests(ExchangeTestRunner): - currency_ticker = "XLM" + currency_configuration = cal.XLM_CURRENCY_CONFIGURATION valid_destination_1 = "GCKUD4BHIYSAYHU7HBB5FDSW6CSYH3GSOUBPWD2KE7KNBERP4BSKEJDV" valid_destination_memo_1 = "" valid_destination_2 = "GB5ZQJYKSZP3JOMOCWCBI7SPQUBW6ZL3642FUB7IYNAOC2EQMAFXI3P2" diff --git a/test/python/test_tezos.py b/test/python/test_tezos.py index 0cf5349d..356b1ed4 100644 --- a/test/python/test_tezos.py +++ b/test/python/test_tezos.py @@ -2,6 +2,7 @@ from .apps.exchange_test_runner import ExchangeTestRunner, ALL_TESTS_EXCEPT_MEMO from .apps.tezos import TezosClient, encode_address, XTZ_PACKED_DERIVATION_PATH, StatusCode +from .apps import cal as cal from requests.exceptions import ChunkedEncodingError, ConnectionError from urllib3.exceptions import ProtocolError @@ -15,7 +16,7 @@ # ExchangeTestRunner implementation for Stellar class TezosTests(ExchangeTestRunner): - currency_ticker = "XTZ" + currency_configuration = cal.XTZ_CURRENCY_CONFIGURATION valid_destination_1 = encode_address("e6330795ffe18f873b83cb13662442b87bd98c22") valid_destination_memo_1 = "" valid_destination_2 = encode_address("e6330795ffe18f873b83cb13662442b87bd98c40") diff --git a/test/python/test_tron.py b/test/python/test_tron.py index 348e54fa..bc78d4a3 100644 --- a/test/python/test_tron.py +++ b/test/python/test_tron.py @@ -5,6 +5,7 @@ from .apps.exchange_test_runner import ExchangeTestRunner from .apps.exchange_test_runner import VALID_TESTS, ALL_TESTS_EXCEPT_FEES from .apps.tron import TronClient, TronErrors +from .apps import cal as cal # ExchangeTestRunner implementation for Tron @@ -30,7 +31,7 @@ class TronTests(ExchangeTestRunner): # ExchangeTestRunner implementation for Tron TRX # ################################################## class TronTrxTests(TronTests): - currency_ticker = "TRX" + currency_configuration = cal.TRX_CURRENCY_CONFIGURATION def perform_final_tx(self, destination, send_amount, fees, memo): TronClient(self.backend).send_tx(path="m/44'/148'/0'", @@ -51,7 +52,7 @@ def test_tron_trx(self, backend, exchange_navigation_helper, test_to_run): # ExchangeTestRunner implementation for Tron USDT # ################################################### class TronUsdtTests(TronTests): - currency_ticker = "USDT" + currency_configuration = cal.USDT_CURRENCY_CONFIGURATION def perform_final_tx(self, destination, send_amount, fees, memo): TronClient(self.backend).send_tx(path="m/44'/148'/0'", @@ -72,7 +73,7 @@ def test_tron_usdt(self, backend, exchange_navigation_helper, test_to_run): # ExchangeTestRunner implementation for Tron USDC # ################################################### class TronUsdcTests(TronTests): - currency_ticker = "USDC" + currency_configuration = cal.USDC_CURRENCY_CONFIGURATION def perform_final_tx(self, destination, send_amount, fees, memo): TronClient(self.backend).send_tx(path="m/44'/148'/0'", @@ -93,7 +94,7 @@ def test_tron_usdc(self, backend, exchange_navigation_helper, test_to_run): # ExchangeTestRunner implementation for Tron TRX but wrong tx token # ##################################################################### class TronTrxToUsdtTests(TronTests): - currency_ticker = "TRX" + currency_configuration = cal.TRX_CURRENCY_CONFIGURATION def perform_final_tx(self, destination, send_amount, fees, memo): with pytest.raises(ExceptionRAPDU) as e: @@ -115,7 +116,7 @@ def test_tron_trx_to_usdt(self, backend, exchange_navigation_helper, test_to_run # ExchangeTestRunner implementation for Tron USDT but wrong tx token (TRX) # ############################################################################ class TronUsdttoTrxTests(TronTests): - currency_ticker = "USDT" + currency_configuration = cal.USDT_CURRENCY_CONFIGURATION def perform_final_tx(self, destination, send_amount, fees, memo): with pytest.raises(ExceptionRAPDU) as e: @@ -137,7 +138,7 @@ def test_tron_usdt_to_trx(self, backend, exchange_navigation_helper, test_to_run # ExchangeTestRunner implementation for Tron USDT but wrong tx token (USDC) # ############################################################################# class TronUsdtoUsdcTests(TronTests): - currency_ticker = "USDT" + currency_configuration = cal.USDT_CURRENCY_CONFIGURATION def perform_final_tx(self, destination, send_amount, fees, memo): with pytest.raises(ExceptionRAPDU) as e: