You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
590 lines
22 KiB
590 lines
22 KiB
# This file is part of the Trezor project.
|
|
#
|
|
# Copyright (C) 2012-2019 SatoshiLabs and contributors
|
|
#
|
|
# This library is free software: you can redistribute it and/or modify
|
|
# it under the terms of the GNU Lesser General Public License version 3
|
|
# as published by the Free Software Foundation.
|
|
#
|
|
# This library is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU Lesser General Public License for more details.
|
|
#
|
|
# You should have received a copy of the License along with this library.
|
|
# If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.
|
|
|
|
import pytest
|
|
|
|
from trezorlib import ethereum, exceptions, messages
|
|
from trezorlib.debuglink import TrezorClientDebugLink as Client
|
|
from trezorlib.debuglink import message_filters
|
|
from trezorlib.exceptions import TrezorFailure
|
|
from trezorlib.tools import parse_path, unharden
|
|
|
|
from ...common import parametrize_using_common_fixtures
|
|
from ...input_flows import (
|
|
InputFlowEthereumSignTxDataGoBack,
|
|
InputFlowEthereumSignTxDataScrollDown,
|
|
InputFlowEthereumSignTxDataSkip,
|
|
InputFlowEthereumSignTxGoBackFromSummary,
|
|
InputFlowEthereumSignTxShowFeeInfo,
|
|
)
|
|
from .common import encode_network
|
|
|
|
TO_ADDR = "0x1d1c328764a41bda0492b66baa30c4a339ff85ef"
|
|
|
|
|
|
pytestmark = [pytest.mark.altcoin, pytest.mark.ethereum]
|
|
|
|
|
|
def make_defs(parameters: dict) -> messages.EthereumDefinitions:
|
|
# With removal of most built-in defs from firmware, we have test vectors
|
|
# that no longer run. Because this is not the place to test the definitions,
|
|
# we generate fake entries so that we can check the signing results.
|
|
address_n = parse_path(parameters["path"])
|
|
slip44 = unharden(address_n[1])
|
|
network = encode_network(chain_id=parameters["chain_id"], slip44=slip44)
|
|
|
|
return messages.EthereumDefinitions(encoded_network=network)
|
|
|
|
|
|
@parametrize_using_common_fixtures(
|
|
"ethereum/sign_tx.json",
|
|
"ethereum/sign_tx_eip155.json",
|
|
)
|
|
@pytest.mark.parametrize("chunkify", (True, False))
|
|
def test_signtx(client: Client, chunkify: bool, parameters: dict, result: dict):
|
|
_do_test_signtx(client, parameters, result, chunkify=chunkify)
|
|
|
|
|
|
def _do_test_signtx(
|
|
client: Client,
|
|
parameters: dict,
|
|
result: dict,
|
|
input_flow=None,
|
|
chunkify: bool = False,
|
|
):
|
|
with client:
|
|
if input_flow:
|
|
client.watch_layout()
|
|
client.set_input_flow(input_flow)
|
|
sig_v, sig_r, sig_s = ethereum.sign_tx(
|
|
client,
|
|
n=parse_path(parameters["path"]),
|
|
nonce=int(parameters["nonce"], 16),
|
|
gas_price=int(parameters["gas_price"], 16),
|
|
gas_limit=int(parameters["gas_limit"], 16),
|
|
to=parameters["to_address"],
|
|
chain_id=parameters["chain_id"],
|
|
value=int(parameters["value"], 16),
|
|
tx_type=parameters["tx_type"],
|
|
data=bytes.fromhex(parameters["data"]),
|
|
definitions=make_defs(parameters),
|
|
chunkify=chunkify,
|
|
)
|
|
|
|
expected_v = 2 * parameters["chain_id"] + 35
|
|
assert sig_v in (expected_v, expected_v + 1)
|
|
assert sig_r.hex() == result["sig_r"]
|
|
assert sig_s.hex() == result["sig_s"]
|
|
assert sig_v == result["sig_v"]
|
|
|
|
|
|
# Data taken from sign_tx_eip1559.json["tests"][0]
|
|
example_input_data = {
|
|
"parameters": {
|
|
"chain_id": 1,
|
|
"path": "m/44'/60'/0'/0/0",
|
|
"nonce": "0x0",
|
|
"gas_price": "0x4a817c800",
|
|
"gas_limit": "0x5208",
|
|
"value": "0x2540be400",
|
|
"to_address": "0x8eA7a3fccC211ED48b763b4164884DDbcF3b0A98",
|
|
"tx_type": None,
|
|
"data": "",
|
|
},
|
|
"result": {
|
|
"sig_v": 38,
|
|
"sig_r": "6a6349bddb5749bb8b96ce2566a035ef87a09dbf89b5c7e3dfdf9ed725912f24",
|
|
"sig_s": "4ae58ccd3bacee07cdc4a3e8540544fd009c4311af7048122da60f2054c07ee4",
|
|
},
|
|
}
|
|
|
|
|
|
@pytest.mark.skip_t1("T1 does not support input flows")
|
|
def test_signtx_fee_info(client: Client):
|
|
input_flow = InputFlowEthereumSignTxShowFeeInfo(client).get()
|
|
_do_test_signtx(
|
|
client,
|
|
example_input_data["parameters"],
|
|
example_input_data["result"],
|
|
input_flow,
|
|
)
|
|
|
|
|
|
@pytest.mark.skip_t1("T1 does not support input flows")
|
|
def test_signtx_go_back_from_summary(client: Client):
|
|
input_flow = InputFlowEthereumSignTxGoBackFromSummary(client).get()
|
|
_do_test_signtx(
|
|
client,
|
|
example_input_data["parameters"],
|
|
example_input_data["result"],
|
|
input_flow,
|
|
)
|
|
|
|
|
|
@parametrize_using_common_fixtures("ethereum/sign_tx_eip1559.json")
|
|
@pytest.mark.parametrize("chunkify", (True, False))
|
|
def test_signtx_eip1559(client: Client, chunkify: bool, parameters: dict, result: dict):
|
|
with client:
|
|
sig_v, sig_r, sig_s = ethereum.sign_tx_eip1559(
|
|
client,
|
|
n=parse_path(parameters["path"]),
|
|
nonce=int(parameters["nonce"], 16),
|
|
gas_limit=int(parameters["gas_limit"], 16),
|
|
max_gas_fee=int(parameters["max_gas_fee"], 16),
|
|
max_priority_fee=int(parameters["max_priority_fee"], 16),
|
|
to=parameters["to_address"],
|
|
chain_id=parameters["chain_id"],
|
|
value=int(parameters["value"], 16),
|
|
data=bytes.fromhex(parameters["data"]),
|
|
definitions=make_defs(parameters),
|
|
chunkify=chunkify,
|
|
)
|
|
|
|
assert sig_r.hex() == result["sig_r"]
|
|
assert sig_s.hex() == result["sig_s"]
|
|
assert sig_v == result["sig_v"]
|
|
|
|
|
|
def test_signtx_erc20_balanceof_misaligned_data(client: Client):
|
|
# "Data" field for a 'balanceOf' call with two last bytes removed.
|
|
with pytest.raises(TrezorFailure):
|
|
with client:
|
|
ethereum.sign_tx_eip1559(
|
|
client,
|
|
n=parse_path("m/44h/60h/0h/0/0"),
|
|
nonce=0,
|
|
gas_limit=20,
|
|
max_gas_fee=20,
|
|
max_priority_fee=1,
|
|
to=TO_ADDR,
|
|
chain_id=1,
|
|
value=0,
|
|
data=bytes.fromhex(
|
|
"70a08231000000000000000000000000574bbb36871ba6b78e27f4b4dcfb76ea009188"
|
|
),
|
|
)
|
|
|
|
|
|
def test_signtx_erc20_balanceof(client: Client):
|
|
# "Data" field for a 'balanceOf' call. The function checks the balance of the address 0x574bbb36871ba6b78e27f4b4dcfb76ea0091880b
|
|
# The function has 1 argument: 'address'
|
|
with client:
|
|
ethereum.sign_tx_eip1559(
|
|
client,
|
|
n=parse_path("m/44h/60h/0h/0/0"),
|
|
nonce=0,
|
|
gas_limit=20,
|
|
max_gas_fee=20,
|
|
max_priority_fee=1,
|
|
to=TO_ADDR,
|
|
chain_id=1,
|
|
value=0,
|
|
data=bytes.fromhex(
|
|
"70a08231000000000000000000000000574bbb36871ba6b78e27f4b4dcfb76ea0091880b"
|
|
),
|
|
)
|
|
|
|
|
|
def test_signtx_erc20_allowance(client: Client):
|
|
# "Data" field for an 'allowance' call. This function checks the amount of tokens that an owner allowed to a spender.
|
|
# The function has 2 arguments: 'address', 'address'
|
|
with client:
|
|
ethereum.sign_tx_eip1559(
|
|
client,
|
|
n=parse_path("m/44h/60h/0h/0/0"),
|
|
nonce=0,
|
|
gas_limit=20,
|
|
max_gas_fee=20,
|
|
max_priority_fee=1,
|
|
to=TO_ADDR,
|
|
chain_id=1,
|
|
value=0,
|
|
data=bytes.fromhex(
|
|
"dd62ed3e0000000000000000000000001111111111111111111111111111111111111111000000000000000000000000574bbb36871ba6b78e27f4b4dcfb76ea0091880b"
|
|
),
|
|
)
|
|
|
|
|
|
def test_signtx_erc20_transferfrom(client: Client):
|
|
# "Data" field for a 'transferFrom' call. The function allows a spender to transfer a certain amount of tokens from the owner's balance to another address.
|
|
# The function has 3 arguments: 'from', 'to', 'value'
|
|
with client:
|
|
ethereum.sign_tx_eip1559(
|
|
client,
|
|
n=parse_path("m/44h/60h/0h/0/0"),
|
|
nonce=0,
|
|
gas_limit=20,
|
|
max_gas_fee=20,
|
|
max_priority_fee=1,
|
|
to=TO_ADDR,
|
|
chain_id=1,
|
|
value=0,
|
|
data=bytes.fromhex(
|
|
"23b872dd0000000000000000000000001111111111111111111111111111111111111111000000000000000000000000574bbb36871ba6b78e27f4b4dcfb76ea0091880b0000000000000000000000000000000000000000000000000000000000000064"
|
|
),
|
|
)
|
|
|
|
|
|
def test_signtx_erc20_invity(client: Client):
|
|
# https://eth1.trezor.io/tx/0xcce715f7bd2fb509a41f64519d29e5d666e5f2f664ea18ce486d446e83466e56
|
|
# "nonce": "0x10",
|
|
# "gasPrice": "0x737be7600",
|
|
# "gas": "0x39805",
|
|
# "to": "0x1111111254EEB25477B68fb85Ed929f73A960582",
|
|
# "value": "0x26b81237cb570000",
|
|
# "input": "0x12aa3caf00000000000000000000000092f3f71cef740ed5784874b8c70ff87ecdf33588000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000092f3f71cef740ed5784874b8c70ff87ecdf335880000000000000000000000007490ca03e52adbd7a05ed8cc30a228aeb968ae2500000000000000000000000000000000000000000000000026b81237cb5700000000000000000000000000000000000000000000000000000000000128cd0eef000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e10000000000000000000000000000000000c300009500004600002c000026e021973ee919693206e122950ff4b162ac52eb6248db00000000000000000080db5f7200e00000206b4be0b94041c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2d0e30db002a00000000000000000000000000000000000000000000000000000000128cd0eefee63c1e50088e6a0c2ddd26feeb64f039a2c41296fcb3f5640c02aaa39b223fe8d0a0e5c4f27ead9083c756cc280a06c4eca27a0b86991c6218b36c1d19d4a2e9eb0ce3606eb481111111254eeb25477b68fb85ed929f73a96058200000000000000000000000000000000000000000000000000000000000000cb1c12d1",
|
|
# "hash": "0xcce715f7bd2fb509a41f64519d29e5d666e5f2f664ea18ce486d446e83466e56",
|
|
# "blockNumber": "0x10fed3b",
|
|
# "from": "0x7490CA03E52ADbD7A05ed8cc30a228AeB968ae25",
|
|
# "transactionIndex": "0x72"
|
|
with client:
|
|
ethereum.sign_tx(
|
|
client,
|
|
n=parse_path("m/44h/60h/0h/0/0"),
|
|
nonce=0x10,
|
|
gas_price=0x737BE7600,
|
|
gas_limit=0x39805,
|
|
to="0x1111111254EEB25477B68fb85Ed929f73A960582",
|
|
chain_id=1,
|
|
value=0x26B81237CB570000, # TODO this wouldn't pass the check for smart contract
|
|
tx_type=None,
|
|
data=bytes.fromhex(
|
|
"12aa3caf00000000000000000000000092f3f71cef740ed5784874b8c70ff87ecdf33588000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000092f3f71cef740ed5784874b8c70ff87ecdf335880000000000000000000000007490ca03e52adbd7a05ed8cc30a228aeb968ae2500000000000000000000000000000000000000000000000026b81237cb5700000000000000000000000000000000000000000000000000000000000128cd0eef000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e10000000000000000000000000000000000c300009500004600002c000026e021973ee919693206e122950ff4b162ac52eb6248db00000000000000000080db5f7200e00000206b4be0b94041c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2d0e30db002a00000000000000000000000000000000000000000000000000000000128cd0eefee63c1e50088e6a0c2ddd26feeb64f039a2c41296fcb3f5640c02aaa39b223fe8d0a0e5c4f27ead9083c756cc280a06c4eca27a0b86991c6218b36c1d19d4a2e9eb0ce3606eb481111111254eeb25477b68fb85ed929f73a96058200000000000000000000000000000000000000000000000000000000000000cb1c12d1"
|
|
),
|
|
)
|
|
|
|
|
|
def test_signtx_erc20_args_test(client: Client):
|
|
# Testing various data types in ERC-20 function arguments
|
|
arg0_int = "0000000000000000000000000000000000000000000000000000000000001251"
|
|
arg1_str = "00000000000000000000000000000000000000000000000000000048656c6c6f"
|
|
arg2_bytes = "1111111122222222333333334444444455555555666666667777777788888888"
|
|
arg3_address = "000000000000000000000000574bbb36871ba6b78e27f4b4dcfb76ea0091880b"
|
|
|
|
with client:
|
|
ethereum.sign_tx_eip1559(
|
|
client,
|
|
n=parse_path("m/44h/60h/0h/0/0"),
|
|
nonce=0,
|
|
gas_limit=20,
|
|
max_gas_fee=20,
|
|
max_priority_fee=1,
|
|
to=TO_ADDR,
|
|
chain_id=1,
|
|
value=0,
|
|
data=bytes.fromhex(
|
|
"00000042" + arg0_int + arg1_str + arg2_bytes + arg3_address
|
|
),
|
|
)
|
|
|
|
|
|
def test_sanity_checks(client: Client):
|
|
"""Is not vectorized because these are internal-only tests that do not
|
|
need to be exposed to the public.
|
|
"""
|
|
# contract creation without data should fail.
|
|
with pytest.raises(TrezorFailure, match=r"DataError"):
|
|
ethereum.sign_tx(
|
|
client,
|
|
n=parse_path("m/44h/60h/0h/0/0"),
|
|
nonce=123_456,
|
|
gas_price=20_000,
|
|
gas_limit=20_000,
|
|
to="",
|
|
value=12_345_678_901_234_567_890,
|
|
chain_id=1,
|
|
)
|
|
|
|
# gas overflow
|
|
with pytest.raises(TrezorFailure, match=r"DataError"):
|
|
ethereum.sign_tx(
|
|
client,
|
|
n=parse_path("m/44h/60h/0h/0/0"),
|
|
nonce=123_456,
|
|
gas_price=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF,
|
|
gas_limit=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF,
|
|
to=TO_ADDR,
|
|
value=12_345_678_901_234_567_890,
|
|
chain_id=1,
|
|
)
|
|
|
|
# bad chain ID
|
|
with pytest.raises(TrezorFailure, match=r"Chain ID out of bounds"):
|
|
ethereum.sign_tx(
|
|
client,
|
|
n=parse_path("m/44h/60h/0h/0/0"),
|
|
nonce=123_456,
|
|
gas_price=20_000,
|
|
gas_limit=20_000,
|
|
to=TO_ADDR,
|
|
value=12_345_678_901_234_567_890,
|
|
chain_id=0,
|
|
)
|
|
|
|
|
|
def test_data_streaming(client: Client):
|
|
"""Only verifying the expected responses, the signatures are
|
|
checked in vectorized function above.
|
|
"""
|
|
with client:
|
|
is_t1 = client.features.model == "1"
|
|
client.set_expected_responses(
|
|
[
|
|
messages.ButtonRequest(code=messages.ButtonRequestType.SignTx),
|
|
(is_t1, messages.ButtonRequest(code=messages.ButtonRequestType.SignTx)),
|
|
(
|
|
not is_t1,
|
|
messages.ButtonRequest(code=messages.ButtonRequestType.Other),
|
|
),
|
|
messages.ButtonRequest(code=messages.ButtonRequestType.SignTx),
|
|
message_filters.EthereumTxRequest(
|
|
data_length=1_024,
|
|
signature_r=None,
|
|
signature_s=None,
|
|
signature_v=None,
|
|
),
|
|
message_filters.EthereumTxRequest(
|
|
data_length=1_024,
|
|
signature_r=None,
|
|
signature_s=None,
|
|
signature_v=None,
|
|
),
|
|
message_filters.EthereumTxRequest(
|
|
data_length=1_024,
|
|
signature_r=None,
|
|
signature_s=None,
|
|
signature_v=None,
|
|
),
|
|
message_filters.EthereumTxRequest(
|
|
data_length=3,
|
|
signature_r=None,
|
|
signature_s=None,
|
|
signature_v=None,
|
|
),
|
|
message_filters.EthereumTxRequest(data_length=None),
|
|
]
|
|
)
|
|
|
|
ethereum.sign_tx(
|
|
client,
|
|
n=parse_path("m/44h/60h/0h/0/0"),
|
|
nonce=0,
|
|
gas_price=20_000,
|
|
gas_limit=20_000,
|
|
to=TO_ADDR,
|
|
value=0,
|
|
data=b"ABCDEFGHIJKLMNOP" * 256 + b"!!!",
|
|
chain_id=1,
|
|
)
|
|
|
|
|
|
def test_signtx_eip1559_access_list(client: Client):
|
|
with client:
|
|
|
|
sig_v, sig_r, sig_s = ethereum.sign_tx_eip1559(
|
|
client,
|
|
n=parse_path("m/44h/60h/0h/0/100"),
|
|
nonce=0,
|
|
gas_limit=20,
|
|
to="0x1d1c328764a41bda0492b66baa30c4a339ff85ef",
|
|
chain_id=1,
|
|
value=10,
|
|
max_gas_fee=20,
|
|
max_priority_fee=1,
|
|
access_list=[
|
|
messages.EthereumAccessList(
|
|
address="0xde0b295669a9fd93d5f28d9ec85e40f4cb697bae",
|
|
storage_keys=[
|
|
bytes.fromhex(
|
|
"0000000000000000000000000000000000000000000000000000000000000003"
|
|
),
|
|
bytes.fromhex(
|
|
"0000000000000000000000000000000000000000000000000000000000000007"
|
|
),
|
|
],
|
|
)
|
|
],
|
|
)
|
|
|
|
assert sig_v == 1
|
|
assert (
|
|
sig_r.hex()
|
|
== "9f8763f3ff8d4d409f6b96bc3f1d84dd504e2c667b162778508478645401f121"
|
|
)
|
|
assert (
|
|
sig_s.hex()
|
|
== "51e30b68b9091cf8138c07380c4378c2711779b68b2e5264d141479f13a12f57"
|
|
)
|
|
|
|
|
|
def test_signtx_eip1559_access_list_larger(client: Client):
|
|
with client:
|
|
|
|
sig_v, sig_r, sig_s = ethereum.sign_tx_eip1559(
|
|
client,
|
|
n=parse_path("m/44h/60h/0h/0/100"),
|
|
nonce=0,
|
|
gas_limit=20,
|
|
to="0x1d1c328764a41bda0492b66baa30c4a339ff85ef",
|
|
chain_id=1,
|
|
value=10,
|
|
max_gas_fee=20,
|
|
max_priority_fee=1,
|
|
access_list=[
|
|
messages.EthereumAccessList(
|
|
address="0xde0b295669a9fd93d5f28d9ec85e40f4cb697bae",
|
|
storage_keys=[
|
|
bytes.fromhex(
|
|
"0000000000000000000000000000000000000000000000000000000000000003"
|
|
),
|
|
bytes.fromhex(
|
|
"0000000000000000000000000000000000000000000000000000000000000007"
|
|
),
|
|
],
|
|
),
|
|
messages.EthereumAccessList(
|
|
address="0xbb9bc244d798123fde783fcc1c72d3bb8c189413",
|
|
storage_keys=[
|
|
bytes.fromhex(
|
|
"0000000000000000000000000000000000000000000000000000000000000006"
|
|
),
|
|
bytes.fromhex(
|
|
"0000000000000000000000000000000000000000000000000000000000000007"
|
|
),
|
|
bytes.fromhex(
|
|
"0000000000000000000000000000000000000000000000000000000000000009"
|
|
),
|
|
],
|
|
),
|
|
],
|
|
)
|
|
|
|
assert sig_v == 1
|
|
assert (
|
|
sig_r.hex()
|
|
== "718a3a30827c979975c846d2f60495310c4959ee3adce2d89e0211785725465c"
|
|
)
|
|
assert (
|
|
sig_s.hex()
|
|
== "7d0ea2a28ef5702ca763c1f340427c0020292ffcbb4553dd1c8ea8e2b9126dbc"
|
|
)
|
|
|
|
|
|
def test_sanity_checks_eip1559(client: Client):
|
|
"""Is not vectorized because these are internal-only tests that do not
|
|
need to be exposed to the public.
|
|
"""
|
|
# contract creation without data should fail.
|
|
with pytest.raises(TrezorFailure, match=r"DataError"):
|
|
ethereum.sign_tx_eip1559(
|
|
client,
|
|
n=parse_path("m/44h/60h/0h/0/100"),
|
|
nonce=0,
|
|
gas_limit=20,
|
|
to="",
|
|
chain_id=1,
|
|
value=10,
|
|
max_gas_fee=20,
|
|
max_priority_fee=1,
|
|
)
|
|
|
|
# max fee overflow
|
|
with pytest.raises(TrezorFailure, match=r"DataError"):
|
|
ethereum.sign_tx_eip1559(
|
|
client,
|
|
n=parse_path("m/44h/60h/0h/0/100"),
|
|
nonce=0,
|
|
gas_limit=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF,
|
|
to=TO_ADDR,
|
|
chain_id=1,
|
|
value=10,
|
|
max_gas_fee=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF,
|
|
max_priority_fee=1,
|
|
)
|
|
|
|
# priority fee overflow
|
|
with pytest.raises(TrezorFailure, match=r"DataError"):
|
|
ethereum.sign_tx_eip1559(
|
|
client,
|
|
n=parse_path("m/44h/60h/0h/0/100"),
|
|
nonce=0,
|
|
gas_limit=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF,
|
|
to=TO_ADDR,
|
|
chain_id=1,
|
|
value=10,
|
|
max_gas_fee=20,
|
|
max_priority_fee=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF,
|
|
)
|
|
|
|
# bad chain ID
|
|
with pytest.raises(TrezorFailure, match=r"Chain ID out of bounds"):
|
|
ethereum.sign_tx_eip1559(
|
|
client,
|
|
n=parse_path("m/44h/60h/0h/0/100"),
|
|
nonce=0,
|
|
gas_limit=20,
|
|
to=TO_ADDR,
|
|
chain_id=0,
|
|
value=10,
|
|
max_gas_fee=20,
|
|
max_priority_fee=1,
|
|
)
|
|
|
|
|
|
def input_flow_data_skip(client: Client, cancel: bool = False):
|
|
return InputFlowEthereumSignTxDataSkip(client, cancel).get()
|
|
|
|
|
|
def input_flow_data_scroll_down(client: Client, cancel: bool = False):
|
|
return InputFlowEthereumSignTxDataScrollDown(client, cancel).get()
|
|
|
|
|
|
def input_flow_data_go_back(client: Client, cancel: bool = False):
|
|
return InputFlowEthereumSignTxDataGoBack(client, cancel).get()
|
|
|
|
|
|
HEXDATA = "0123456789abcd000023456789abcd010003456789abcd020000456789abcd030000056789abcd040000006789abcd050000000789abcd060000000089abcd070000000009abcd080000000000abcd090000000001abcd0a0000000011abcd0b0000000111abcd0c0000001111abcd0d0000011111abcd0e0000111111abcd0f0000000002abcd100000000022abcd110000000222abcd120000002222abcd130000022222abcd140000222222abcd15"
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"flow", (input_flow_data_skip, input_flow_data_scroll_down, input_flow_data_go_back)
|
|
)
|
|
@pytest.mark.skip_t1
|
|
def test_signtx_data_pagination(client: Client, flow):
|
|
def _sign_tx_call():
|
|
ethereum.sign_tx(
|
|
client,
|
|
n=parse_path("m/44h/60h/0h/0/0"),
|
|
nonce=0x0,
|
|
gas_price=0x14,
|
|
gas_limit=0x14,
|
|
to="0x1d1c328764a41bda0492b66baa30c4a339ff85ef",
|
|
chain_id=1,
|
|
value=0xA,
|
|
tx_type=None,
|
|
data=bytes.fromhex(HEXDATA),
|
|
)
|
|
|
|
with client:
|
|
client.watch_layout()
|
|
client.set_input_flow(flow(client))
|
|
_sign_tx_call()
|
|
|
|
with client, pytest.raises(exceptions.Cancelled):
|
|
client.watch_layout()
|
|
client.set_input_flow(flow(client, cancel=True))
|
|
_sign_tx_call()
|