Files
app-ethereum/tests/ragger/test_sign.py

294 lines
9.7 KiB
Python
Raw Normal View History

from pathlib import Path
2024-03-26 09:43:26 +01:00
from web3 import Web3
2024-04-16 23:45:17 +02:00
from ragger.error import ExceptionRAPDU
from ragger.backend import BackendInterface
from ragger.firmware import Firmware
from ragger.navigator import Navigator, NavInsID
2024-04-16 23:45:17 +02:00
from ragger.navigator.navigation_scenario import NavigateWithScenario
from client.client import EthAppClient, StatusWord
import client.response_parser as ResponseParser
from client.settings import SettingID, settings_toggle
from client.utils import recover_transaction
2024-03-26 09:43:26 +01:00
# Values used across all tests
CHAIN_ID = 1
ADDR = bytes.fromhex("0011223344556677889900112233445566778899")
ADDR2 = bytes.fromhex("5a321744667052affa8386ed49e00ef223cbffc3")
ADDR3 = bytes.fromhex("dac17f958d2ee523a2206206994597c13d831ec7")
2024-04-10 12:21:23 +02:00
ADDR4 = bytes.fromhex("b2bb2b958afa2e96dab3f3ce7162b87daea39017")
BIP32_PATH = "m/44'/60'/0'/0/0"
BIP32_PATH2 = "m/44'/60'/1'/0/0"
NONCE = 21
NONCE2 = 68
GAS_PRICE = 13
2024-04-10 12:21:23 +02:00
GAS_PRICE2 = 5
GAS_LIMIT = 21000
AMOUNT = 1.22
AMOUNT2 = 0.31415
2024-03-26 09:43:26 +01:00
def common(firmware: Firmware,
backend: BackendInterface,
navigator: Navigator,
2024-04-16 23:45:17 +02:00
scenario_navigator: NavigateWithScenario,
default_screenshot_path: Path,
tx_params: dict,
test_name: str = "",
path: str = BIP32_PATH,
confirm: bool = False):
2024-03-26 09:43:26 +01:00
app_client = EthAppClient(backend)
with app_client.get_public_addr(bip32_path=path, display=False):
pass
_, DEVICE_ADDR, _ = ResponseParser.pk_addr(app_client.response().data)
with app_client.sign(path, tx_params):
if not firmware.is_nano and confirm:
navigator.navigate_and_compare(default_screenshot_path,
f"{test_name}/confirm",
[NavInsID.USE_CASE_CHOICE_CONFIRM],
screen_change_after_last_instruction=False)
if firmware.is_nano:
end_text = "Accept"
else:
end_text = "Sign"
scenario_navigator.review_approve(custom_screen_text=end_text, do_comparison=test_name!="")
# verify signature
vrs = ResponseParser.signature(app_client.response().data)
addr = recover_transaction(tx_params, vrs)
assert addr == DEVICE_ADDR
2024-04-16 23:45:17 +02:00
def common_reject(backend: BackendInterface,
scenario_navigator: NavigateWithScenario,
tx_params: dict,
path: str = BIP32_PATH):
app_client = EthAppClient(backend)
try:
with app_client.sign(path, tx_params):
scenario_navigator.review_reject()
except ExceptionRAPDU as e:
assert e.status == StatusWord.CONDITION_NOT_SATISFIED
else:
assert False # An exception should have been raised
def common_fail(backend: BackendInterface,
tx_params: dict,
expected: StatusWord,
path: str = BIP32_PATH):
app_client = EthAppClient(backend)
try:
with app_client.sign(path, tx_params):
pass
except ExceptionRAPDU as e:
assert e.status == expected
else:
assert False # An exception should have been raised
def test_legacy(firmware: Firmware,
backend: BackendInterface,
navigator: Navigator,
2024-04-16 23:45:17 +02:00
scenario_navigator: NavigateWithScenario,
default_screenshot_path: Path):
tx_params: dict = {
"nonce": NONCE,
"gasPrice": Web3.to_wei(GAS_PRICE, "gwei"),
"gas": GAS_LIMIT,
"to": ADDR,
"value": Web3.to_wei(AMOUNT, "ether"),
"chainId": CHAIN_ID
}
common(firmware, backend, navigator, scenario_navigator, default_screenshot_path, tx_params)
# Transfer amount >= 2^87 Eth on Ethereum app should fail
def test_legacy_send_error(backend: BackendInterface):
tx_params: dict = {
"nonce": 38,
"gasPrice": 56775612312210000000001234554332,
"gas": GAS_LIMIT,
"to": ADDR3,
"value": 12345678912345678912345678000000000000000000,
"chainId": CHAIN_ID
}
common_fail(backend, tx_params, StatusWord.EXCEPTION_OVERFLOW, path=BIP32_PATH2)
# Transfer bsc
def test_legacy_send_bsc(firmware: Firmware,
backend: BackendInterface,
navigator: Navigator,
2024-04-16 23:45:17 +02:00
scenario_navigator: NavigateWithScenario,
test_name: str,
default_screenshot_path: Path):
tx_params: dict = {
"nonce": 1,
2024-04-10 12:21:23 +02:00
"gasPrice": Web3.to_wei(GAS_PRICE2, 'gwei'),
"gas": GAS_LIMIT,
"to": ADDR2,
"value": Web3.to_wei(AMOUNT2, "ether"),
"chainId": 56
}
common(firmware, backend, navigator, scenario_navigator, default_screenshot_path, tx_params, test_name, BIP32_PATH2)
# Transfer on network 112233445566 on Ethereum
2024-04-10 12:12:44 +02:00
def test_legacy_chainid(firmware: Firmware,
2024-04-16 23:45:17 +02:00
backend: BackendInterface,
navigator: Navigator,
2024-04-16 23:45:17 +02:00
scenario_navigator: NavigateWithScenario,
test_name: str,
default_screenshot_path: Path):
tx_params: dict = {
"nonce": NONCE2,
"gasPrice": Web3.to_wei(GAS_PRICE, 'gwei'),
"gas": GAS_LIMIT,
"to": ADDR2,
"value": Web3.to_wei(AMOUNT2, "ether"),
"chainId": 112233445566
}
common(firmware, backend, navigator, scenario_navigator, default_screenshot_path, tx_params, test_name, BIP32_PATH2)
def test_1559(firmware: Firmware,
backend: BackendInterface,
navigator: Navigator,
2024-04-16 23:45:17 +02:00
scenario_navigator: NavigateWithScenario,
default_screenshot_path: Path):
tx_params: dict = {
"nonce": NONCE,
"maxFeePerGas": Web3.to_wei(145, "gwei"),
"maxPriorityFeePerGas": Web3.to_wei(1.5, "gwei"),
"gas": GAS_LIMIT,
"to": ADDR,
"value": Web3.to_wei(AMOUNT, "ether"),
"chainId": CHAIN_ID
}
common(firmware, backend, navigator, scenario_navigator, default_screenshot_path, tx_params)
def test_sign_simple(firmware: Firmware,
backend: BackendInterface,
navigator: Navigator,
2024-04-16 23:45:17 +02:00
scenario_navigator: NavigateWithScenario,
test_name: str,
default_screenshot_path: Path):
tx_params: dict = {
"nonce": NONCE2,
"gasPrice": Web3.to_wei(GAS_PRICE, 'gwei'),
"gas": GAS_LIMIT,
"to": ADDR2,
"value": Web3.to_wei(AMOUNT2, "ether"),
"chainId": CHAIN_ID
}
common(firmware, backend, navigator, scenario_navigator, default_screenshot_path, tx_params, test_name, "m/44'/60'/1'/0/0")
def test_sign_limit_nonce(firmware: Firmware,
backend: BackendInterface,
navigator: Navigator,
2024-04-16 23:45:17 +02:00
scenario_navigator: NavigateWithScenario,
test_name: str,
default_screenshot_path: Path):
tx_params: dict = {
"nonce": 2**64-1,
"gasPrice": 10,
"gas": 50000,
"to": ADDR2,
"value": 0x08762,
"chainId": CHAIN_ID
}
common(firmware, backend, navigator, scenario_navigator, default_screenshot_path, tx_params, test_name, "m/44'/60'/1'/0/0")
def test_sign_nonce_display(firmware: Firmware,
backend: BackendInterface,
navigator: Navigator,
2024-04-16 23:45:17 +02:00
scenario_navigator: NavigateWithScenario,
test_name: str,
default_screenshot_path: Path):
settings_toggle(firmware, navigator, [SettingID.NONCE])
tx_params: dict = {
"nonce": NONCE2,
"gasPrice": Web3.to_wei(GAS_PRICE, 'gwei'),
"gas": GAS_LIMIT,
"to": ADDR2,
"value": Web3.to_wei(AMOUNT2, "ether"),
"chainId": CHAIN_ID
}
common(firmware, backend, navigator, scenario_navigator, default_screenshot_path, tx_params, test_name, "m/44'/60'/1'/0/0")
def test_sign_reject(backend: BackendInterface, scenario_navigator: NavigateWithScenario):
tx_params: dict = {
"nonce": NONCE2,
"gasPrice": Web3.to_wei(GAS_PRICE, 'gwei'),
"gas": GAS_LIMIT,
"to": ADDR2,
"value": Web3.to_wei(AMOUNT2, "ether"),
"chainId": CHAIN_ID
}
common_reject(backend, scenario_navigator, tx_params, "m/44'/60'/1'/0/0")
def test_sign_error_transaction_type(backend: BackendInterface):
tx_params: dict = {
"type": 0,
"nonce": 0,
"gasPrice": 10,
"gas": 50000,
"to": ADDR2,
"value": 0x19,
"chainId": CHAIN_ID
}
app_client = EthAppClient(backend)
try:
with app_client.sign(BIP32_PATH2, tx_params):
pass
except TypeError:
pass
else:
assert False # An exception should have been raised
2024-04-10 12:21:23 +02:00
def test_sign_eip_2930(firmware: Firmware,
backend: BackendInterface,
navigator: Navigator,
2024-04-16 23:45:17 +02:00
scenario_navigator: NavigateWithScenario,
test_name: str,
default_screenshot_path: Path):
2024-04-10 12:21:23 +02:00
tx_params = {
"nonce": NONCE,
"gasPrice": Web3.to_wei(GAS_PRICE2, "gwei"),
"gas": GAS_LIMIT,
"to": ADDR4,
"value": Web3.to_wei(0.01, "ether"),
"chainId": 3,
"accessList": [
{
"address": "0x0000000000000000000000000000000000000001",
"storageKeys": [
"0x0100000000000000000000000000000000000000000000000000000000000000"
]
}
],
}
common(firmware, backend, navigator, scenario_navigator, default_screenshot_path, tx_params, test_name)