Skip to content

Commit

Permalink
Tests: test signing level/round constraints
Browse files Browse the repository at this point in the history
  • Loading branch information
spalmer25 committed Feb 1, 2024
1 parent 9262156 commit 98f1118
Show file tree
Hide file tree
Showing 2 changed files with 149 additions and 19 deletions.
140 changes: 123 additions & 17 deletions test/python/test_instructions.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
"""Module gathering the baking app instruction tests."""

from pathlib import Path
from typing import Callable, Tuple
import pytest
from ragger.firmware import Firmware
from ragger.navigator import Navigator, NavInsID
from utils.client import TezosClient, Version, Hwm
from utils.client import TezosClient, Version, Hwm, StatusCode
from utils.account import Account
from utils.helper import get_current_commit
from utils.message import (
Message,
Preattestation,
Attestation,
AttestationDal,
Expand All @@ -22,7 +24,6 @@
TESTS_ROOT_DIR
)


def test_review_home(
firmware: Firmware,
navigator: Navigator,
Expand Down Expand Up @@ -270,6 +271,37 @@ def test_get_all_hwm(
f"Expected test hmw {test_hwm} but got {received_test_hwm}"


def build_preattestation(op_level, op_round, chain_id):
"""Build a preattestation."""
return Preattestation(
op_level=op_level,
op_round=op_round
).forge(chain_id=chain_id)

def build_attestation(op_level, op_round, chain_id):
"""Build a attestation."""
return Attestation(
op_level=op_level,
op_round=op_round
).forge(chain_id=chain_id)

def build_attestation_dal(op_level, op_round, chain_id):
"""Build a attestation_dal."""
return AttestationDal(
op_level=op_level,
op_round=op_round
).forge(chain_id=chain_id)

def build_block(level, current_round, chain_id):
"""Build a block."""
return Block(
header=BlockHeader(
level=level,
fitness=Fitness(current_round=current_round)
)
).forge(chain_id=chain_id)


@pytest.mark.parametrize("account", [DEFAULT_ACCOUNT])
@pytest.mark.parametrize("with_hash", [False, True])
def test_sign_preattestation(
Expand All @@ -291,10 +323,11 @@ def test_sign_preattestation(
test_hwm
)

preattestation = Preattestation(
preattestation = build_preattestation(
op_level=1,
op_round=2
).forge(chain_id=main_chain_id)
op_round=2,
chain_id=main_chain_id
)

if with_hash:
signature = client.sign_message(account, preattestation)
Expand Down Expand Up @@ -337,10 +370,11 @@ def test_sign_attestation(
test_hwm
)

attestation = Attestation(
attestation = build_attestation(
op_level=1,
op_round=2
).forge(chain_id=main_chain_id)
op_round=2,
chain_id=main_chain_id
)

if with_hash:
signature = client.sign_message(account, attestation)
Expand Down Expand Up @@ -383,10 +417,11 @@ def test_sign_attestation_dal(
test_hwm
)

attestation = AttestationDal(
attestation = build_attestation_dal(
op_level=1,
op_round=2
).forge(chain_id=main_chain_id)
op_round=2,
chain_id=main_chain_id
)

if with_hash:
signature = client.sign_message(account, attestation)
Expand Down Expand Up @@ -429,12 +464,11 @@ def test_sign_block(
test_hwm
)

block = Block(
header=BlockHeader(
level=1,
fitness=Fitness(current_round=2)
)
).forge(chain_id=main_chain_id)
block = build_block(
level=1,
current_round=2,
chain_id=main_chain_id
)

if with_hash:
signature = client.sign_message(account, block)
Expand All @@ -455,6 +489,78 @@ def test_sign_block(
path=test_name
)

PARAMETERS = [
(build_attestation, (0, 0), build_preattestation, (0, 1), True ),
(build_block, (0, 1), build_attestation_dal, (1, 0), True ),
(build_block, (0, 1), build_attestation_dal, (0, 0), False),
(build_attestation, (1, 0), build_preattestation, (0, 1), False),
] + [
(build_preattestation, (0, 0), build_preattestation, (0, 0), False),
(build_preattestation, (0, 0), build_block, (0, 0), False),
(build_preattestation, (0, 0), build_attestation, (0, 0), True ),
(build_preattestation, (0, 0), build_attestation_dal, (0, 0), True ),
(build_attestation, (0, 0), build_preattestation, (0, 0), False),
(build_attestation, (0, 0), build_attestation, (0, 0), False),
(build_attestation, (0, 0), build_attestation_dal, (0, 0), False),
(build_attestation, (0, 0), build_block, (0, 0), False),
(build_attestation_dal, (0, 0), build_preattestation, (0, 0), False),
(build_attestation_dal, (0, 0), build_attestation, (0, 0), False),
(build_attestation_dal, (0, 0), build_attestation_dal, (0, 0), False),
(build_attestation_dal, (0, 0), build_block, (0, 0), False),
(build_block, (1, 1), build_preattestation, (1, 1), True ),
(build_block, (1, 1), build_attestation, (1, 1), True ),
(build_block, (1, 1), build_attestation_dal, (1, 1), True ),
(build_block, (1, 1), build_block, (1, 1), False),
]

@pytest.mark.parametrize(
"message_builder_1, level_round_1, " \
"message_builder_2, level_round_2, " \
"success",
PARAMETERS)
@pytest.mark.parametrize("account", [DEFAULT_ACCOUNT])
def test_sign_level_authorized(
account: Account,
message_builder_1: Callable[[int, int, str], Message],
level_round_1: Tuple[int, int],
message_builder_2: Callable[[int, int, str], Message],
level_round_2: Tuple[int, int],
success: bool,
client: TezosClient,
tezos_navigator: TezosNavigator) -> None:
"""Test whether the level/round constraints behave as expected."""

main_chain_id = DEFAULT_CHAIN_ID
main_level = 1

tezos_navigator.setup_app_context(
account,
main_chain_id,
main_hwm=Hwm(main_level),
test_hwm=Hwm(0)
)

level_1, round_1 = level_round_1
message_1 = message_builder_1(
level_1 + main_level,
round_1,
main_chain_id
)
level_2, round_2 = level_round_2
message_2 = message_builder_2(
level_2 + main_level,
round_2,
main_chain_id
)

client.sign_message(account, message_1)

if success:
client.sign_message(account, message_2)
else:
with StatusCode.WRONG_VALUES.is_expected():
client.sign_message(account, message_2)


# Data generated by the old application itself
HMAC_TEST_SET = [
Expand Down
28 changes: 26 additions & 2 deletions test/python/utils/client.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
"""Module providing a tezos client."""

from typing import Tuple, Optional
from typing import Tuple, Optional, Generator
from enum import IntEnum
from contextlib import contextmanager

from ragger.utils import RAPDU
from ragger.backend import BackendInterface
Expand Down Expand Up @@ -142,7 +143,30 @@ class Index(IntEnum):
class StatusCode(IntEnum):
"""Class representing the status code."""

OK = 0x9000
OK = 0x9000
WRONG_PARAM = 0x6b00
WRONG_LENGTH = 0x6c00
INVALID_INS = 0x6d00
WRONG_LENGTH_FOR_INS = 0x917e
REJECT = 0x6985
PARSE_ERROR = 0x9405
REFERENCED_DATA_NOT_FOUND = 0x6a88
WRONG_VALUES = 0x6a80
SECURITY = 0x6982
HID_REQUIRED = 0x6983
CLASS = 0x6e00
MEMORY_ERROR = 0x9200

@contextmanager
def is_expected(self) -> Generator[None, None, None]:
"""Fail if the right RAPDU code exception is not raise."""
try:
yield
assert False, f"Expect fail with { self.name } but succeed"
except ExceptionRAPDU as e:
failing_code = StatusCode(e.status)
assert self == failing_code, \
f"Expect fail with { self.name } but fail with { failing_code.name }"


MAX_APDU_SIZE: int = 235
Expand Down

0 comments on commit 98f1118

Please sign in to comment.