Now properly handles UI clicks in EIP712 automated tests
This commit is contained in:
@@ -6,8 +6,8 @@ from ethereum_client import EthereumClient
|
||||
|
||||
ELFS_DIR = (Path(__file__).parent.parent / "elfs").resolve()
|
||||
FWS = [
|
||||
Firmware("nanox", "2.0.2"),
|
||||
Firmware("nanos", "2.1"),
|
||||
Firmware("nanox", "2.0.2"),
|
||||
Firmware("nanosp", "1.0.3")
|
||||
]
|
||||
|
||||
@@ -54,4 +54,4 @@ def backend_client(backend_name: str, firmware: Firmware) -> BackendInterface:
|
||||
# This final fixture will return the properly configured app client, to be used in tests
|
||||
@pytest.fixture
|
||||
def app_client(backend_client: BackendInterface) -> EthereumClient:
|
||||
yield EthereumClient(backend_client)
|
||||
return EthereumClient(backend_client)
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
from contextlib import contextmanager
|
||||
from typing import Generator
|
||||
from enum import IntEnum, auto
|
||||
from typing import Iterator
|
||||
from ragger.backend import BackendInterface
|
||||
from ragger.utils import RAPDU
|
||||
import signal
|
||||
|
||||
class InsType(IntEnum):
|
||||
EIP712_SEND_STRUCT_DEF = 0x1a,
|
||||
@@ -164,23 +167,38 @@ class EthereumResponseParser:
|
||||
|
||||
return v, r, s
|
||||
|
||||
|
||||
class EthereumClient:
|
||||
_verbose_eip712 = False
|
||||
|
||||
def __init__(self, client: BackendInterface, debug: bool = False):
|
||||
self._client = client
|
||||
self._debug = debug
|
||||
self._cmd_builder = EthereumClientCmdBuilder()
|
||||
self._resp_parser = EthereumResponseParser()
|
||||
self._click_delay = 1/4
|
||||
signal.signal(signal.SIGALRM, self._click_signal_timeout)
|
||||
|
||||
def _send(self, payload: bytearray) -> None:
|
||||
self._client.send_raw(payload)
|
||||
def _send(self, payload: bytearray):
|
||||
return self._client.exchange_async_raw(payload)
|
||||
|
||||
def _recv(self) -> RAPDU:
|
||||
return self._client.receive()
|
||||
return self._client._last_async_response
|
||||
|
||||
def _click_signal_timeout(self, signum: int, frame):
|
||||
self._client.right_click()
|
||||
|
||||
def _enable_click_until_response(self):
|
||||
signal.setitimer(signal.ITIMER_REAL,
|
||||
self._click_delay,
|
||||
self._click_delay)
|
||||
|
||||
def _disable_click_until_response(self):
|
||||
signal.setitimer(signal.ITIMER_REAL, 0, 0)
|
||||
|
||||
def eip712_send_struct_def_struct_name(self, name: str):
|
||||
self._send(self._cmd_builder.eip712_send_struct_def_struct_name(name))
|
||||
return self._recv()
|
||||
with self._send(self._cmd_builder.eip712_send_struct_def_struct_name(name)):
|
||||
pass
|
||||
return self._recv().status == 0x9000
|
||||
|
||||
def eip712_send_struct_def_struct_field(self,
|
||||
field_type: EIP712FieldType,
|
||||
@@ -188,52 +206,77 @@ class EthereumClient:
|
||||
type_size: int,
|
||||
array_levels: [],
|
||||
key_name: str):
|
||||
self._send(self._cmd_builder.eip712_send_struct_def_struct_field(
|
||||
with self._send(self._cmd_builder.eip712_send_struct_def_struct_field(
|
||||
field_type,
|
||||
type_name,
|
||||
type_size,
|
||||
array_levels,
|
||||
key_name))
|
||||
key_name)):
|
||||
pass
|
||||
return self._recv()
|
||||
|
||||
def eip712_send_struct_impl_root_struct(self, name: str):
|
||||
self._send(self._cmd_builder.eip712_send_struct_impl_root_struct(name))
|
||||
with self._send(self._cmd_builder.eip712_send_struct_impl_root_struct(name)):
|
||||
self._enable_click_until_response()
|
||||
self._disable_click_until_response()
|
||||
return self._recv()
|
||||
|
||||
def eip712_send_struct_impl_array(self, size: int):
|
||||
self._send(self._cmd_builder.eip712_send_struct_impl_array(size))
|
||||
with self._send(self._cmd_builder.eip712_send_struct_impl_array(size)):
|
||||
pass
|
||||
return self._recv()
|
||||
|
||||
def eip712_send_struct_impl_struct_field(self, raw_value: bytes):
|
||||
ret = None
|
||||
for apdu in self._cmd_builder.eip712_send_struct_impl_struct_field(raw_value):
|
||||
self._send(apdu)
|
||||
# TODO: Do clicks
|
||||
ret = self._recv()
|
||||
return ret
|
||||
with self._send(apdu):
|
||||
self._enable_click_until_response()
|
||||
self._disable_click_until_response()
|
||||
assert self._recv().status == 0x9000
|
||||
|
||||
def eip712_sign_new(self, bip32):
|
||||
self._send(self._cmd_builder.eip712_sign_new(bip32))
|
||||
return self._recv()
|
||||
with self._send(self._cmd_builder.eip712_sign_new(bip32)):
|
||||
if not self._verbose_eip712: # need to skip the message hash
|
||||
self._client.right_click()
|
||||
self._client.right_click()
|
||||
self._client.both_click() # approve signature
|
||||
resp = self._recv()
|
||||
assert resp.status == 0x9000
|
||||
return self._resp_parser.sign(resp.data)
|
||||
|
||||
def eip712_sign_legacy(self,
|
||||
bip32,
|
||||
domain_hash: bytes,
|
||||
message_hash: bytes):
|
||||
self._send(self._cmd_builder.eip712_sign_legacy(bip32,
|
||||
domain_hash,
|
||||
message_hash))
|
||||
self._client.right_click() # sign typed message screen
|
||||
for _ in range(2): # two hashes (domain + message)
|
||||
if self._client.firmware.device == "nanos":
|
||||
screens_per_hash = 4
|
||||
else:
|
||||
screens_per_hash = 2
|
||||
for _ in range(screens_per_hash):
|
||||
self._client.right_click()
|
||||
self._client.both_click() # approve signature
|
||||
with self._send(self._cmd_builder.eip712_sign_legacy(bip32,
|
||||
domain_hash,
|
||||
message_hash)):
|
||||
self._client.right_click() # sign typed message screen
|
||||
for _ in range(2): # two hashes (domain + message)
|
||||
if self._client.firmware.device == "nanos":
|
||||
screens_per_hash = 4
|
||||
else:
|
||||
screens_per_hash = 2
|
||||
for _ in range(screens_per_hash):
|
||||
self._client.right_click()
|
||||
self._client.both_click() # approve signature
|
||||
|
||||
resp = self._recv()
|
||||
|
||||
assert resp.status == 0x9000
|
||||
return self._resp_parser.sign(resp.data)
|
||||
|
||||
def setting_toggle_verbose_eip712(self):
|
||||
# Go to settings
|
||||
self._client.right_click()
|
||||
self._client.right_click()
|
||||
self._client.both_click()
|
||||
# Go to verbose eip712
|
||||
self._client.right_click()
|
||||
self._client.right_click()
|
||||
self._client.right_click()
|
||||
self._client.both_click()
|
||||
# Go back
|
||||
self._client.right_click()
|
||||
self._client.both_click()
|
||||
|
||||
self._verbose_eip712 = not self._verbose_eip712
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import pytest
|
||||
import os
|
||||
import fnmatch
|
||||
from typing import List
|
||||
from ethereum_client import EthereumClient
|
||||
from eip712 import InputData
|
||||
|
||||
@@ -12,6 +14,22 @@ bip32 = [
|
||||
]
|
||||
|
||||
|
||||
def input_files() -> List[str]:
|
||||
files = []
|
||||
for file in os.scandir("./eip712/input_files"):
|
||||
if fnmatch.fnmatch(file, "*-test.json"):
|
||||
files.append(file.path)
|
||||
return sorted(files)
|
||||
|
||||
@pytest.fixture(params=input_files())
|
||||
def input_file(request) -> str:
|
||||
return request.param
|
||||
|
||||
@pytest.fixture(params=[True, False])
|
||||
def verbose(request) -> bool:
|
||||
return request.param
|
||||
|
||||
|
||||
def test_eip712_legacy(app_client: EthereumClient):
|
||||
v, r, s = app_client.eip712_sign_legacy(
|
||||
bip32,
|
||||
@@ -24,14 +42,12 @@ def test_eip712_legacy(app_client: EthereumClient):
|
||||
assert s == bytes.fromhex("52d8ba9153de9255da220ffd36762c0b027701a3b5110f0a765f94b16a9dfb55")
|
||||
|
||||
|
||||
def test_eip712_new(app_client: EthereumClient):
|
||||
if app_client._client.firmware.device == "nanos": # not supported
|
||||
return
|
||||
def test_eip712_new(app_client: EthereumClient, input_file, verbose):
|
||||
if app_client._client.firmware.device != "nanos": # not supported
|
||||
print("=====> %s" % (input_file))
|
||||
|
||||
# Loop through JSON files
|
||||
for file in os.scandir("./eip712/input_files"):
|
||||
if fnmatch.fnmatch(file, "*-test.json"):
|
||||
print(file.path)
|
||||
InputData.process_file(app_client, file.path, False)
|
||||
app_client.eip712_sign_new(bip32)
|
||||
assert 1 == 1
|
||||
if verbose:
|
||||
app_client.setting_toggle_verbose_eip712()
|
||||
InputData.process_file(app_client, input_file, False)
|
||||
v, r, s = app_client.eip712_sign_new(bip32)
|
||||
assert 1 == 1 # TODO: Replace by the actual v,r,s asserts
|
||||
|
||||
Reference in New Issue
Block a user