Skip to content

Commit

Permalink
test: update transaction signing test
Browse files Browse the repository at this point in the history
- Refactor test_sign_tx_short_tx to test_sign_tx_transfer
- Update transaction signing method to remove account number and wallet type
- Add navigation utility function for cross-device screenshot comparison
- Update command sender to use new SIGN_TRANSACTION instruction
- Add snapshot images for NanoSP and NanoX devices
  • Loading branch information
keiff3r committed Feb 12, 2025
1 parent dea39ec commit f7c0a65
Show file tree
Hide file tree
Showing 18 changed files with 74 additions and 20 deletions.
8 changes: 4 additions & 4 deletions tests/application_client/everscale_command_sender.py
Original file line number Diff line number Diff line change
Expand Up @@ -154,12 +154,12 @@ def sign_message(self, account_number: int, wallet_type: WalletType, message: by
yield response

@contextmanager
def sign_tx(self, account_number: int, wallet_type: WalletType, transaction: bytes) -> Generator[None, None, None]:
def sign_tx(self, transaction: bytes) -> Generator[None, None, None]:
with self.backend.exchange_async(cla=CLA,
ins=InsType.SIGN_TX,
p1=P1.P1_START,
ins=InsType.SIGN_TRANSACTION,
p1=P1.P1_CONFIRM,
p2=P2.P2_LAST,
data=account_number.to_bytes(4, "big") + wallet_type.to_bytes(1, "big") + transaction) as response:
data=transaction) as response:
yield response

def get_async_response(self) -> Optional[RAPDU]:
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
30 changes: 16 additions & 14 deletions tests/test_sign_cmd.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,9 @@
from ragger.navigator import Navigator, NavInsID
from ragger.navigator.navigation_scenario import NavigateWithScenario

from application_client.everscale_transaction import Transaction
from application_client.everscale_command_sender import EverscaleCommandSender, Errors, WalletType
from application_client.everscale_response_unpacker import unpack_get_public_key_response, unpack_sign_tx_response
from utils import check_signature_validity
from application_client.everscale_command_sender import EverscaleCommandSender
from application_client.everscale_response_unpacker import unpack_sign_tx_response
from utils import navigate_until_text_and_compare

# In this tests we check the behavior of the device when asked to sign a transaction

Expand All @@ -19,29 +18,32 @@
# We will ensure that the displayed information is correct by using screenshots comparison

# TODO: Add a valid raw transaction and a valid expected signature
def test_sign_tx_short_tx(backend: BackendInterface, scenario_navigator: NavigateWithScenario) -> None:
@pytest.mark.active_test_scope
def test_sign_tx_transfer(backend: BackendInterface, navigator: Navigator, default_screenshot_path: str, test_name: str) -> None:
# Use the app interface instead of raw interface
client = EverscaleCommandSender(backend)
account_number = 0
wallet_type = WalletType.WALLET_V3
# First we need to get the public key of the device in order to build the transaction
rapdu = client.get_public_key(account_number=account_number)
_, public_key, _, _ = unpack_get_public_key_response(rapdu.data)

# Raw transaction
transaction = bytes.fromhex("0000000000000000000000000000000000000000000000000000000000000000")
transaction = bytes.fromhex("00000000010904455645520001010301006c000161b3badb535d1b88d0e4d60d316567b1448568efafdf21846ecd0ba02e3adabf97000000ca7cfb9642b3d6449ea677323640010165801be2256b3d704f24c46aea3298c1a5ea8f8d1aa86ccc89474bc0570265e7898ac0000000000000000036d36956f8b969d038020000")


# Send the sign device instruction.
# As it requires on-screen validation, the function is asynchronous.
# It will yield the result when the navigation is done
with client.sign_tx(account_number=account_number, wallet_type=wallet_type, transaction=transaction):
with client.sign_tx(transaction):
# Validate the on-screen request by performing the navigation appropriate for this device
scenario_navigator.review_approve()
navigate_until_text_and_compare(
backend.firmware,
navigator,
"Accept",
default_screenshot_path,
test_name
)

# The device as yielded the result, parse it and ensure that the signature is correct
response = client.get_async_response().data
_, der_sig, _ = unpack_sign_tx_response(response)
assert der_sig.hex() == "0000000000000000000000000000000000000000000000000000000000000000"
assert der_sig.hex() == "a0396cd952160f068e0a7d6279ba2b61a2215a4dd997fcc1fe8905722341a20a86424dfdb2598b86855e73e47a1804023ff3f9afffd91825df0f58825dabd808"


# # In this test we send to the device a transaction to trig a blind-signing flow
Expand Down
1 change: 0 additions & 1 deletion tests/test_sign_message_cmd.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
from ragger.navigator import Navigator, NavInsID
from ragger.navigator.navigation_scenario import NavigateWithScenario

from application_client.everscale_transaction import Transaction
from application_client.everscale_command_sender import EverscaleCommandSender, Errors, WalletType
from application_client.everscale_response_unpacker import unpack_get_public_key_response, unpack_sign_tx_response
from utils import check_signature_validity
Expand Down
55 changes: 54 additions & 1 deletion tests/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from ecdsa.curves import SECP256k1
from ecdsa.keys import VerifyingKey
from ecdsa.util import sigdecode_der

from ragger.navigator import NavInsID

# Check if a signature of a given message is valid
def check_signature_validity(public_key: bytes, signature: bytes, message: bytes) -> bool:
Expand Down Expand Up @@ -74,3 +74,56 @@ def _read_makefile() -> List[str]:
with open(makefile, "r", encoding="utf-8") as f_p:
lines = f_p.readlines()
return lines


def navigate_until_text_and_compare(
firmware,
navigator,
text: str,
screenshot_path: str,
test_name: str,
screen_change_before_first_instruction: bool = True,
screen_change_after_last_instruction: bool = True,
nav_ins_confirm_instruction: NavInsID = NavInsID.USE_CASE_REVIEW_CONFIRM,
):
"""Navigate through device screens until specified text is found and compare screenshots.
This function handles navigation through device screens differently based on the device type (Stax/Flex vs others).
It will navigate through screens until the specified text is found, taking screenshots for comparison along the way.
Args:
firmware: The firmware object containing device information
navigator: The navigator object used to control device navigation
text: The text string to search for on device screens
screenshot_path: Path where screenshot comparison files will be saved
test_name: The name of the test that is being run
screen_change_before_first_instruction: Whether to wait for screen change before first instruction
screen_change_after_last_instruction: Whether to wait for screen change after last instruction
Returns:
None
Note:
For Stax/Flex devices:
- Uses swipe left gesture for navigation
- Uses review confirm for confirmation
For other devices:
- Uses right click for navigation
- Uses both click for confirmation
"""
if firmware.device.startswith(("stax", "flex")):
go_right_instruction = NavInsID.SWIPE_CENTER_TO_LEFT
confirm_instructions = [nav_ins_confirm_instruction]
else:
go_right_instruction = NavInsID.RIGHT_CLICK
confirm_instructions = [NavInsID.BOTH_CLICK]

navigator.navigate_until_text_and_compare(
go_right_instruction,
confirm_instructions,
text,
screenshot_path,
test_name,
300,
screen_change_before_first_instruction,
screen_change_after_last_instruction,
)

0 comments on commit f7c0a65

Please sign in to comment.