Ragger tests

This commit is contained in:
Alexandre Paillier
2024-01-29 18:16:15 +01:00
parent c8c6b9a2d1
commit faa2d3aabf
63 changed files with 149 additions and 27 deletions

View File

@@ -337,12 +337,11 @@ def next_timeout(_signum: int, _frame):
def enable_autonext(): def enable_autonext():
seconds = 1/4
if app_client._client.firmware.device == 'stax': # Stax Speculos is slow if app_client._client.firmware.device == 'stax': # Stax Speculos is slow
interval = seconds * 3 delay = 1.5
else: else:
interval = seconds delay = 1/4
signal.setitimer(signal.ITIMER_REAL, seconds, interval) signal.setitimer(signal.ITIMER_REAL, delay, delay)
def disable_autonext(): def disable_autonext():

View File

@@ -0,0 +1,29 @@
{
"domain": {
"chainId": 1,
"name": "Token test",
"verifyingContract": "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC",
"version": "1"
},
"message": {
"from": "0xaAaAaAaaAaAaAaaAaAAAAAAAAaaaAaAaAaaAaaAa",
"to": "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045",
"amount": "117",
"token": "0x6B175474E89094C44Da98b954EedeAC495271d0F"
},
"primaryType": "Transfer",
"types": {
"EIP712Domain": [
{ "name": "name", "type": "string" },
{ "name": "version", "type": "string" },
{ "name": "chainId", "type": "uint256" },
{ "name": "verifyingContract", "type": "address" }
],
"Transfer": [
{ "name": "from", "type": "address" },
{ "name": "to", "type": "address" },
{ "name": "amount", "type": "uint256" },
{ "name": "token", "type": "address" }
]
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 472 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 414 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 338 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 336 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 324 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 364 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 381 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 472 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 463 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 371 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 298 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 285 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 655 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 433 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 555 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 709 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 321 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 774 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 364 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 381 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 472 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 414 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 338 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 336 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 324 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 364 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 381 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 472 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 463 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 371 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 298 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 285 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 655 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 433 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 555 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 709 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 321 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 774 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 364 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 381 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

View File

@@ -9,6 +9,8 @@ from ragger.backend import BackendInterface
from ragger.firmware import Firmware from ragger.firmware import Firmware
from ragger.navigator import Navigator, NavInsID from ragger.navigator import Navigator, NavInsID
import json import json
from typing import Optional
from constants import ROOT_SNAPSHOT_PATH
import ledger_app_clients.ethereum.response_parser as ResponseParser import ledger_app_clients.ethereum.response_parser as ResponseParser
from ledger_app_clients.ethereum.client import EthAppClient from ledger_app_clients.ethereum.client import EthAppClient
@@ -29,9 +31,13 @@ BIP32_PATH = "m/44'/60'/0'/0/0"
snaps_config: Optional[SnapshotsConfig] = None snaps_config: Optional[SnapshotsConfig] = None
def eip712_json_path() -> str:
return "%s/eip712_input_files" % (os.path.dirname(__file__))
def input_files() -> list[str]: def input_files() -> list[str]:
files = [] files = []
for file in os.scandir("%s/eip712_input_files" % (os.path.dirname(__file__))): for file in os.scandir(eip712_json_path()):
if fnmatch.fnmatch(file, "*-data.json"): if fnmatch.fnmatch(file, "*-data.json"):
files.append(file.path) files.append(file.path)
return sorted(files) return sorted(files)
@@ -87,7 +93,52 @@ def autonext(fw: Firmware, nav: Navigator):
moves = [NavInsID.RIGHT_CLICK] moves = [NavInsID.RIGHT_CLICK]
else: else:
moves = [NavInsID.USE_CASE_REVIEW_TAP] moves = [NavInsID.USE_CASE_REVIEW_TAP]
nav.navigate(moves, screen_change_before_first_instruction=False, screen_change_after_last_instruction=False) if snaps_config is not None:
nav.navigate_and_compare(ROOT_SNAPSHOT_PATH,
snaps_config.test_name,
moves,
screen_change_before_first_instruction=False,
screen_change_after_last_instruction=False,
snap_start_idx=snaps_config.idx)
snaps_config.idx += 1
else:
nav.navigate(moves,
screen_change_before_first_instruction=False,
screen_change_after_last_instruction=False)
def eip712_new_common(fw: Firmware,
nav: Navigator,
app_client: EthAppClient,
json_data: dict,
filters: Optional[dict],
verbose: bool):
assert InputData.process_data(app_client,
json_data,
filters,
partial(autonext, fw, nav))
with app_client.eip712_sign_new(BIP32_PATH):
moves = list()
if fw.device.startswith("nano"):
# need to skip the message hash
if not verbose and filters is None:
moves = [NavInsID.RIGHT_CLICK] * 2
moves += [NavInsID.BOTH_CLICK]
else:
time.sleep(1.5)
# need to skip the message hash
if not verbose and filters is None:
moves += [NavInsID.USE_CASE_REVIEW_TAP]
moves += [NavInsID.USE_CASE_REVIEW_CONFIRM]
if snaps_config is not None:
nav.navigate_and_compare(ROOT_SNAPSHOT_PATH,
snaps_config.test_name,
moves,
snap_start_idx=snaps_config.idx)
snaps_config.idx += 1
else:
nav.navigate(moves)
return ResponseParser.signature(app_client.response().data)
def test_eip712_new(firmware: Firmware, def test_eip712_new(firmware: Firmware,
@@ -124,26 +175,69 @@ def test_eip712_new(firmware: Firmware,
settings_toggle(firmware, navigator, [SettingID.VERBOSE_EIP712]) settings_toggle(firmware, navigator, [SettingID.VERBOSE_EIP712])
with open(input_file) as file: with open(input_file) as file:
assert InputData.process_data(app_client, v, r, s = eip712_new_common(firmware,
json.load(file), navigator,
filters, app_client,
partial(autonext, firmware, navigator)) json.load(file),
with app_client.eip712_sign_new(BIP32_PATH): filters,
# tight on timing, needed by the CI otherwise might fail sometimes verbose)
time.sleep(0.5)
moves = list() assert v == bytes.fromhex(config["signature"]["v"])
if firmware.device.startswith("nano"): assert r == bytes.fromhex(config["signature"]["r"])
if not verbose and not filtering: # need to skip the message hash assert s == bytes.fromhex(config["signature"]["s"])
moves = [NavInsID.RIGHT_CLICK] * 2
moves += [NavInsID.BOTH_CLICK]
else:
if not verbose and not filtering: # need to skip the message hash
moves += [NavInsID.USE_CASE_REVIEW_TAP]
moves += [NavInsID.USE_CASE_REVIEW_CONFIRM]
navigator.navigate(moves)
v, r, s = ResponseParser.signature(app_client.response().data)
assert v == bytes.fromhex(config["signature"]["v"])
assert r == bytes.fromhex(config["signature"]["r"]) def test_eip712_address_substitution(firmware: Firmware,
assert s == bytes.fromhex(config["signature"]["s"]) backend: BackendInterface,
navigator: Navigator,
verbose: bool):
global snaps_config
app_client = EthAppClient(backend)
if firmware.device == "nanos":
pytest.skip("Not supported on LNS")
else:
test_name = "eip712_address_substitution"
if verbose:
test_name += "_verbose"
snaps_config = SnapshotsConfig(test_name)
with open("%s/address_substitution.json" % (eip712_json_path())) as file:
data = json.load(file)
with app_client.provide_token_metadata("DAI",
bytes.fromhex(data["message"]["token"][2:]),
18,
1):
pass
with app_client.get_challenge():
pass
challenge = ResponseParser.challenge(app_client.response().data)
with app_client.provide_domain_name(challenge,
"vitalik.eth",
bytes.fromhex(data["message"]["to"][2:])):
pass
if verbose:
settings_toggle(firmware, navigator, [SettingID.VERBOSE_EIP712])
filters = None
else:
filters = {
"name": "Token test",
"fields": {
"amount": "Amount",
"token": "Token",
"to": "To",
}
}
v, r, s = eip712_new_common(firmware,
navigator,
app_client,
data,
filters,
verbose)
assert v == bytes.fromhex("1b")
assert r == bytes.fromhex("d4a0e058251cdc3845aaa5eb8409d8a189ac668db7c55a64eb3121b0db7fd8c0")
assert s == bytes.fromhex("3221800e4f45272c6fa8fafda5e94c848d1a4b90c442aa62afa8e8d6a9af0f00")