1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2025-03-12 14:16:06 +00:00

test: update device tests

[no changelog]
This commit is contained in:
M1nd3r 2024-12-02 15:49:04 +01:00
parent 87646a7ada
commit df5d93ebd5
123 changed files with 3824 additions and 3507 deletions

View File

@ -17,7 +17,7 @@
import pytest
from trezorlib.binance import get_address
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.debuglink import SessionDebugWrapper as Session
from trezorlib.tools import parse_path
from ...input_flows import InputFlowShowAddressQRCode
@ -38,23 +38,23 @@ BINANCE_ADDRESS_TEST_VECTORS = [
@pytest.mark.parametrize("path, expected_address", BINANCE_ADDRESS_TEST_VECTORS)
def test_binance_get_address(client: Client, path: str, expected_address: str):
def test_binance_get_address(session: Session, path: str, expected_address: str):
# data from https://github.com/binance-chain/javascript-sdk/blob/master/__tests__/crypto.test.js#L50
address = get_address(client, parse_path(path), show_display=True)
address = get_address(session, parse_path(path), show_display=True)
assert address == expected_address
@pytest.mark.parametrize("path, expected_address", BINANCE_ADDRESS_TEST_VECTORS)
def test_binance_get_address_chunkify_details(
client: Client, path: str, expected_address: str
session: Session, path: str, expected_address: str
):
# data from https://github.com/binance-chain/javascript-sdk/blob/master/__tests__/crypto.test.js#L50
with client:
with session.client as client:
IF = InputFlowShowAddressQRCode(client)
client.set_input_flow(IF.get())
address = get_address(
client, parse_path(path), show_display=True, chunkify=True
session, parse_path(path), show_display=True, chunkify=True
)
assert address == expected_address

View File

@ -17,7 +17,7 @@
import pytest
from trezorlib import binance
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.debuglink import SessionDebugWrapper as Session
from trezorlib.tools import parse_path
from ...input_flows import InputFlowShowXpubQRCode
@ -31,11 +31,11 @@ BINANCE_PATH = parse_path("m/44h/714h/0h/0/0")
@pytest.mark.setup_client(
mnemonic="offer caution gift cross surge pretty orange during eye soldier popular holiday mention east eight office fashion ill parrot vault rent devote earth cousin"
)
def test_binance_get_public_key(client: Client):
with client:
def test_binance_get_public_key(session: Session):
with session.client as client:
IF = InputFlowShowXpubQRCode(client)
client.set_input_flow(IF.get())
sig = binance.get_public_key(client, BINANCE_PATH, show_display=True)
sig = binance.get_public_key(session, BINANCE_PATH, show_display=True)
assert (
sig.hex()
== "029729a52e4e3c2b4a4e52aa74033eedaf8ba1df5ab6d1f518fd69e67bbd309b0e"

View File

@ -17,7 +17,7 @@
import pytest
from trezorlib import binance
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.debuglink import SessionDebugWrapper as Session
from trezorlib.tools import parse_path
BINANCE_TEST_VECTORS = [
@ -110,10 +110,10 @@ BINANCE_TEST_VECTORS = [
@pytest.mark.parametrize("message, expected_response", BINANCE_TEST_VECTORS)
@pytest.mark.parametrize("chunkify", (True, False))
def test_binance_sign_message(
client: Client, chunkify: bool, message: dict, expected_response: dict
session: Session, chunkify: bool, message: dict, expected_response: dict
):
response = binance.sign_tx(
client, parse_path("m/44h/714h/0h/0/0"), message, chunkify=chunkify
session, parse_path("m/44h/714h/0h/0/0"), message, chunkify=chunkify
)
assert response.public_key.hex() == expected_response["public_key"]

View File

@ -4,6 +4,7 @@ from hashlib import sha256
from ecdsa import SECP256k1, SigningKey
from trezorlib import btc, messages
from trezorlib.transport.session import Session
from ...common import compact_size
@ -27,7 +28,12 @@ def hash_bytes_prefixed(hasher, data):
def make_payment_request(
client, recipient_name, outputs, change_addresses=None, memos=None, nonce=None
session: Session,
recipient_name,
outputs,
change_addresses=None,
memos=None,
nonce=None,
):
h_pr = sha256(b"SL\x00\x24")
@ -52,7 +58,7 @@ def make_payment_request(
hash_bytes_prefixed(h_pr, memo.text.encode())
elif isinstance(memo, RefundMemo):
address_resp = btc.get_authenticated_address(
client, "Testnet", memo.address_n
session, "Testnet", memo.address_n
)
msg_memo = messages.RefundMemo(
address=address_resp.address, mac=address_resp.mac
@ -63,7 +69,7 @@ def make_payment_request(
hash_bytes_prefixed(h_pr, address_resp.address.encode())
elif isinstance(memo, CoinPurchaseMemo):
address_resp = btc.get_authenticated_address(
client, memo.coin_name, memo.address_n
session, memo.coin_name, memo.address_n
)
msg_memo = messages.CoinPurchaseMemo(
coin_type=memo.slip44,

View File

@ -19,6 +19,7 @@ import time
import pytest
from trezorlib import btc, device, messages
from trezorlib.debuglink import SessionDebugWrapper as Session
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.exceptions import TrezorFailure
from trezorlib.tools import parse_path
@ -59,15 +60,15 @@ SLIP25_PATH = parse_path("m/10025h")
@pytest.mark.parametrize("chunkify", (True, False))
@pytest.mark.setup_client(pin=PIN)
def test_sign_tx(client: Client, chunkify: bool):
def test_sign_tx(session: Session, chunkify: bool):
# NOTE: FAKE input tx
assert session.features.unlocked is False
commitment_data = b"\x0fwww.example.com" + (1).to_bytes(ROUND_ID_LEN, "big")
with client:
with session.client as client:
client.use_pin_sequence([PIN])
btc.authorize_coinjoin(
client,
session,
coordinator="www.example.com",
max_rounds=2,
max_coordinator_fee_rate=500_000, # 0.5 %
@ -77,14 +78,14 @@ def test_sign_tx(client: Client, chunkify: bool):
script_type=messages.InputScriptType.SPENDTAPROOT,
)
client.call(messages.LockDevice())
session.call(messages.LockDevice())
with client:
client.set_expected_responses(
with session:
session.set_expected_responses(
[messages.PreauthorizedRequest, messages.OwnershipProof]
)
btc.get_ownership_proof(
client,
session,
"Testnet",
parse_path("m/10025h/1h/0h/1h/1/0"),
script_type=messages.InputScriptType.SPENDTAPROOT,
@ -93,12 +94,12 @@ def test_sign_tx(client: Client, chunkify: bool):
preauthorized=True,
)
with client:
client.set_expected_responses(
with session:
session.set_expected_responses(
[messages.PreauthorizedRequest, messages.OwnershipProof]
)
btc.get_ownership_proof(
client,
session,
"Testnet",
parse_path("m/10025h/1h/0h/1h/1/5"),
script_type=messages.InputScriptType.SPENDTAPROOT,
@ -206,8 +207,8 @@ def test_sign_tx(client: Client, chunkify: bool):
no_fee_indices=[],
)
with client:
client.set_expected_responses(
with session:
session.set_expected_responses(
[
messages.PreauthorizedRequest(),
request_input(0),
@ -222,7 +223,7 @@ def test_sign_tx(client: Client, chunkify: bool):
]
)
signatures, serialized_tx = btc.sign_tx(
client,
session,
"Testnet",
inputs,
outputs,
@ -243,7 +244,7 @@ def test_sign_tx(client: Client, chunkify: bool):
# Test for a second time.
btc.sign_tx(
client,
session,
"Testnet",
inputs,
outputs,
@ -256,7 +257,7 @@ def test_sign_tx(client: Client, chunkify: bool):
# Test for a third time, number of rounds should be exceeded.
with pytest.raises(TrezorFailure, match="No preauthorized operation"):
btc.sign_tx(
client,
session,
"Testnet",
inputs,
outputs,
@ -267,7 +268,7 @@ def test_sign_tx(client: Client, chunkify: bool):
)
def test_sign_tx_large(client: Client):
def test_sign_tx_large(session: Session):
# NOTE: FAKE input tx
commitment_data = b"\x0fwww.example.com" + (1).to_bytes(ROUND_ID_LEN, "big")
@ -278,17 +279,16 @@ def test_sign_tx_large(client: Client):
output_denom = 10_000 # sats
max_expected_delay = 60 # seconds
with client:
btc.authorize_coinjoin(
client,
coordinator="www.example.com",
max_rounds=2,
max_coordinator_fee_rate=500_000, # 0.5 %
max_fee_per_kvbyte=3500,
n=parse_path("m/10025h/1h/0h/1h"),
coin_name="Testnet",
script_type=messages.InputScriptType.SPENDTAPROOT,
)
btc.authorize_coinjoin(
session,
coordinator="www.example.com",
max_rounds=2,
max_coordinator_fee_rate=500_000, # 0.5 %
max_fee_per_kvbyte=3500,
n=parse_path("m/10025h/1h/0h/1h"),
coin_name="Testnet",
script_type=messages.InputScriptType.SPENDTAPROOT,
)
# INPUTS.
@ -399,22 +399,21 @@ def test_sign_tx_large(client: Client):
)
start = time.time()
with client:
btc.sign_tx(
client,
"Testnet",
inputs,
outputs,
prev_txes=TX_CACHE_TESTNET,
coinjoin_request=coinjoin_req,
preauthorized=True,
serialize=False,
)
btc.sign_tx(
session,
"Testnet",
inputs,
outputs,
prev_txes=TX_CACHE_TESTNET,
coinjoin_request=coinjoin_req,
preauthorized=True,
serialize=False,
)
delay = time.time() - start
assert delay <= max_expected_delay
def test_sign_tx_spend(client: Client):
def test_sign_tx_spend(session: Session):
# NOTE: FAKE input tx
inputs = [
@ -446,15 +445,15 @@ def test_sign_tx_spend(client: Client):
# Ensure that Trezor refuses to spend from CoinJoin without user authorization.
with pytest.raises(TrezorFailure, match="Forbidden key path"):
_, serialized_tx = btc.sign_tx(
client,
session,
"Testnet",
inputs,
outputs,
prev_txes=TX_CACHE_TESTNET,
)
with client:
client.set_expected_responses(
with session:
session.set_expected_responses(
[
messages.ButtonRequest(code=B.Other),
messages.UnlockedPathRequest(),
@ -462,7 +461,7 @@ def test_sign_tx_spend(client: Client):
request_output(0),
request_output(1),
messages.ButtonRequest(code=B.ConfirmOutput),
(is_core(client), messages.ButtonRequest(code=B.ConfirmOutput)),
(is_core(session), messages.ButtonRequest(code=B.ConfirmOutput)),
messages.ButtonRequest(code=B.SignTx),
request_input(0),
request_output(0),
@ -472,7 +471,7 @@ def test_sign_tx_spend(client: Client):
]
)
_, serialized_tx = btc.sign_tx(
client,
session,
"Testnet",
inputs,
outputs,
@ -487,7 +486,7 @@ def test_sign_tx_spend(client: Client):
)
def test_sign_tx_migration(client: Client):
def test_sign_tx_migration(session: Session):
inputs = [
messages.TxInputType(
address_n=parse_path("m/84h/1h/3h/0/12"),
@ -520,15 +519,15 @@ def test_sign_tx_migration(client: Client):
# Ensure that Trezor refuses to receive to CoinJoin path without the user first authorizing access to CoinJoin paths.
with pytest.raises(TrezorFailure, match="Forbidden key path"):
_, serialized_tx = btc.sign_tx(
client,
session,
"Testnet",
inputs,
outputs,
prev_txes=TX_CACHE_TESTNET,
)
with client:
client.set_expected_responses(
with session:
session.set_expected_responses(
[
messages.ButtonRequest(code=B.Other),
messages.UnlockedPathRequest(),
@ -536,7 +535,7 @@ def test_sign_tx_migration(client: Client):
request_input(1),
request_output(0),
messages.ButtonRequest(code=B.ConfirmOutput),
(is_core(client), messages.ButtonRequest(code=B.ConfirmOutput)),
(is_core(session), messages.ButtonRequest(code=B.ConfirmOutput)),
messages.ButtonRequest(code=B.SignTx),
request_input(0),
request_meta(TXHASH_2cc3c1),
@ -558,7 +557,7 @@ def test_sign_tx_migration(client: Client):
]
)
_, serialized_tx = btc.sign_tx(
client,
session,
"Testnet",
inputs,
outputs,
@ -573,11 +572,11 @@ def test_sign_tx_migration(client: Client):
)
def test_wrong_coordinator(client: Client):
def test_wrong_coordinator(session: Session):
# Ensure that a preauthorized GetOwnershipProof fails if the commitment_data doesn't match the coordinator.
btc.authorize_coinjoin(
client,
session,
coordinator="www.example.com",
max_rounds=10,
max_coordinator_fee_rate=500_000, # 0.5 %
@ -589,7 +588,7 @@ def test_wrong_coordinator(client: Client):
with pytest.raises(TrezorFailure, match="Unauthorized operation"):
btc.get_ownership_proof(
client,
session,
"Testnet",
parse_path("m/10025h/1h/0h/1h/1/0"),
script_type=messages.InputScriptType.SPENDTAPROOT,
@ -599,9 +598,9 @@ def test_wrong_coordinator(client: Client):
)
def test_wrong_account_type(client: Client):
def test_wrong_account_type(session: Session):
params = {
"client": client,
"session": session,
"coordinator": "www.example.com",
"max_rounds": 10,
"max_coordinator_fee_rate": 500_000, # 0.5 %
@ -625,11 +624,11 @@ def test_wrong_account_type(client: Client):
)
def test_cancel_authorization(client: Client):
def test_cancel_authorization(session: Session):
# Ensure that a preauthorized GetOwnershipProof fails if the commitment_data doesn't match the coordinator.
btc.authorize_coinjoin(
client,
session,
coordinator="www.example.com",
max_rounds=10,
max_coordinator_fee_rate=500_000, # 0.5 %
@ -639,11 +638,11 @@ def test_cancel_authorization(client: Client):
script_type=messages.InputScriptType.SPENDTAPROOT,
)
device.cancel_authorization(client)
device.cancel_authorization(session)
with pytest.raises(TrezorFailure, match="No preauthorized operation"):
btc.get_ownership_proof(
client,
session,
"Testnet",
parse_path("m/10025h/1h/0h/1h/1/0"),
script_type=messages.InputScriptType.SPENDTAPROOT,
@ -653,35 +652,35 @@ def test_cancel_authorization(client: Client):
)
def test_get_public_key(client: Client):
def test_get_public_key(session: Session):
ACCOUNT_PATH = parse_path("m/10025h/1h/0h/1h")
EXPECTED_XPUB = "tpubDEMKm4M3S2Grx5DHTfbX9et5HQb9KhdjDCkUYdH9gvVofvPTE6yb2MH52P9uc4mx6eFohUmfN1f4hhHNK28GaZnWRXr3b8KkfFcySo1SmXU"
# Ensure that user cannot access SLIP-25 path without UnlockPath.
with pytest.raises(TrezorFailure, match="Forbidden key path"):
resp = btc.get_public_node(
client,
session,
ACCOUNT_PATH,
coin_name="Testnet",
script_type=messages.InputScriptType.SPENDTAPROOT,
)
# Get unlock path MAC.
with client:
client.set_expected_responses(
with session:
session.set_expected_responses(
[
messages.ButtonRequest(code=B.Other),
messages.UnlockedPathRequest,
messages.Failure(code=messages.FailureType.ActionCancelled),
]
)
unlock_path_mac = device.unlock_path(client, n=SLIP25_PATH)
unlock_path_mac = device.unlock_path(session, n=SLIP25_PATH)
# Ensure that UnlockPath fails with invalid MAC.
invalid_unlock_path_mac = bytes([unlock_path_mac[0] ^ 1]) + unlock_path_mac[1:]
with pytest.raises(TrezorFailure, match="Invalid MAC"):
resp = btc.get_public_node(
client,
session,
ACCOUNT_PATH,
coin_name="Testnet",
script_type=messages.InputScriptType.SPENDTAPROOT,
@ -690,15 +689,15 @@ def test_get_public_key(client: Client):
)
# Ensure that user does not need to confirm access when path unlock is requested with MAC.
with client:
client.set_expected_responses(
with session:
session.set_expected_responses(
[
messages.UnlockedPathRequest,
messages.PublicKey,
]
)
resp = btc.get_public_node(
client,
session,
ACCOUNT_PATH,
coin_name="Testnet",
script_type=messages.InputScriptType.SPENDTAPROOT,
@ -708,11 +707,12 @@ def test_get_public_key(client: Client):
assert resp.xpub == EXPECTED_XPUB
def test_get_address(client: Client):
def test_get_address(session: Session):
# Ensure that the SLIP-0025 external chain is inaccessible without user confirmation.
with pytest.raises(TrezorFailure, match="Forbidden key path"):
btc.get_address(
client,
session,
"Testnet",
parse_path("m/10025h/1h/0h/1h/0/0"),
script_type=messages.InputScriptType.SPENDTAPROOT,
@ -720,20 +720,20 @@ def test_get_address(client: Client):
)
# Unlock CoinJoin path.
with client:
client.set_expected_responses(
with session:
session.set_expected_responses(
[
messages.ButtonRequest(code=B.Other),
messages.UnlockedPathRequest,
messages.Failure(code=messages.FailureType.ActionCancelled),
]
)
unlock_path_mac = device.unlock_path(client, SLIP25_PATH)
unlock_path_mac = device.unlock_path(session, SLIP25_PATH)
# Ensure that the SLIP-0025 external chain is accessible after user confirmation.
for chunkify in (True, False):
resp = btc.get_address(
client,
session,
"Testnet",
parse_path("m/10025h/1h/0h/1h/0/0"),
script_type=messages.InputScriptType.SPENDTAPROOT,
@ -745,7 +745,7 @@ def test_get_address(client: Client):
assert resp == "tb1pl3y9gf7xk2ryvmav5ar66ra0d2hk7lhh9mmusx3qvn0n09kmaghqh32ru7"
resp = btc.get_address(
client,
session,
"Testnet",
parse_path("m/10025h/1h/0h/1h/0/1"),
script_type=messages.InputScriptType.SPENDTAPROOT,
@ -758,7 +758,7 @@ def test_get_address(client: Client):
# Ensure that the SLIP-0025 internal chain is inaccessible even with user authorization.
with pytest.raises(TrezorFailure, match="Forbidden key path"):
btc.get_address(
client,
session,
"Testnet",
parse_path("m/10025h/1h/0h/1h/1/0"),
script_type=messages.InputScriptType.SPENDTAPROOT,
@ -769,7 +769,7 @@ def test_get_address(client: Client):
with pytest.raises(TrezorFailure, match="Forbidden key path"):
btc.get_address(
client,
session,
"Testnet",
parse_path("m/10025h/1h/0h/1h/1/1"),
script_type=messages.InputScriptType.SPENDTAPROOT,
@ -781,7 +781,7 @@ def test_get_address(client: Client):
# Ensure that another SLIP-0025 account is inaccessible with the same MAC.
with pytest.raises(TrezorFailure, match="Forbidden key path"):
btc.get_address(
client,
session,
"Testnet",
parse_path("m/10025h/1h/1h/1h/0/0"),
script_type=messages.InputScriptType.SPENDTAPROOT,
@ -793,8 +793,10 @@ def test_get_address(client: Client):
def test_multisession_authorization(client: Client):
# Authorize CoinJoin with www.example1.com in session 1.
session1 = client.get_session()
btc.authorize_coinjoin(
client,
session1,
coordinator="www.example1.com",
max_rounds=10,
max_coordinator_fee_rate=500_000, # 0.5 %
@ -803,14 +805,14 @@ def test_multisession_authorization(client: Client):
coin_name="Testnet",
script_type=messages.InputScriptType.SPENDTAPROOT,
)
session2 = client.get_session()
# Open a second session.
session_id1 = client.session_id
client.init_device(new_session=True)
# session_id1 = session.session_id
# TODO client.init_device(new_session=True)
# Authorize CoinJoin with www.example2.com in session 2.
btc.authorize_coinjoin(
client,
session2,
coordinator="www.example2.com",
max_rounds=10,
max_coordinator_fee_rate=500_000, # 0.5 %
@ -823,7 +825,7 @@ def test_multisession_authorization(client: Client):
# Requesting a preauthorized ownership proof for www.example1.com should fail in session 2.
with pytest.raises(TrezorFailure, match="Unauthorized operation"):
ownership_proof, _ = btc.get_ownership_proof(
client,
session2,
"Testnet",
parse_path("m/10025h/1h/0h/1h/1/0"),
script_type=messages.InputScriptType.SPENDTAPROOT,
@ -834,7 +836,7 @@ def test_multisession_authorization(client: Client):
# Requesting a preauthorized ownership proof for www.example2.com should succeed in session 2.
ownership_proof, _ = btc.get_ownership_proof(
client,
session2,
"Testnet",
parse_path("m/10025h/1h/0h/1h/1/0"),
script_type=messages.InputScriptType.SPENDTAPROOT,
@ -849,12 +851,12 @@ def test_multisession_authorization(client: Client):
)
# Switch back to the first session.
session_id2 = client.session_id
client.init_device(session_id=session_id1)
# session_id2 = session.session_id
# TODO client.init_device(session_id=session_id1)
client.resume_session(session1)
# Requesting a preauthorized ownership proof for www.example1.com should succeed in session 1.
ownership_proof, _ = btc.get_ownership_proof(
client,
session1,
"Testnet",
parse_path("m/10025h/1h/0h/1h/1/0"),
script_type=messages.InputScriptType.SPENDTAPROOT,
@ -871,7 +873,7 @@ def test_multisession_authorization(client: Client):
# Requesting a preauthorized ownership proof for www.example2.com should fail in session 1.
with pytest.raises(TrezorFailure, match="Unauthorized operation"):
ownership_proof, _ = btc.get_ownership_proof(
client,
session1,
"Testnet",
parse_path("m/10025h/1h/0h/1h/1/0"),
script_type=messages.InputScriptType.SPENDTAPROOT,
@ -881,12 +883,12 @@ def test_multisession_authorization(client: Client):
)
# Cancel the authorization in session 1.
device.cancel_authorization(client)
device.cancel_authorization(session1)
# Requesting a preauthorized ownership proof should fail now.
with pytest.raises(TrezorFailure, match="No preauthorized operation"):
ownership_proof, _ = btc.get_ownership_proof(
client,
session1,
"Testnet",
parse_path("m/10025h/1h/0h/1h/1/0"),
script_type=messages.InputScriptType.SPENDTAPROOT,
@ -896,11 +898,11 @@ def test_multisession_authorization(client: Client):
)
# Switch to the second session.
client.init_device(session_id=session_id2)
# TODO client.init_device(session_id=session_id2)
client.resume_session(session2)
# Requesting a preauthorized ownership proof for www.example2.com should still succeed in session 2.
ownership_proof, _ = btc.get_ownership_proof(
client,
session2,
"Testnet",
parse_path("m/10025h/1h/0h/1h/1/0"),
script_type=messages.InputScriptType.SPENDTAPROOT,

View File

@ -17,7 +17,7 @@
import pytest
from trezorlib import btc, messages
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.debuglink import SessionDebugWrapper as Session
from trezorlib.exceptions import TrezorFailure
from trezorlib.tools import H_, parse_path
@ -53,7 +53,7 @@ FAKE_TXHASH_203416 = bytes.fromhex(
pytestmark = pytest.mark.altcoin
def test_send_bch_change(client: Client):
def test_send_bch_change(session: Session):
inp1 = messages.TxInputType(
address_n=parse_path("m/44h/145h/0h/0/0"),
# bitcoincash:qr08q88p9etk89wgv05nwlrkm4l0urz4cyl36hh9sv
@ -72,14 +72,14 @@ def test_send_bch_change(client: Client):
amount=73_452,
script_type=messages.OutputScriptType.PAYTOADDRESS,
)
with client:
client.set_expected_responses(
with session:
session.set_expected_responses(
[
request_input(0),
request_output(0),
request_output(1),
messages.ButtonRequest(code=B.ConfirmOutput),
(is_core(client), messages.ButtonRequest(code=B.ConfirmOutput)),
(is_core(session), messages.ButtonRequest(code=B.ConfirmOutput)),
messages.ButtonRequest(code=B.SignTx),
request_input(0),
request_meta(TXHASH_bc37c2),
@ -92,9 +92,9 @@ def test_send_bch_change(client: Client):
]
)
_, serialized_tx = btc.sign_tx(
client, "Bcash", [inp1], [out1, out2], prev_txes=TX_API
session, "Bcash", [inp1], [out1, out2], prev_txes=TX_API
)
# raise Exception(hexlify(serialized_tx))
assert_tx_matches(
serialized_tx,
hash_link="https://bch1.trezor.io/api/tx/502e8577b237b0152843a416f8f1ab0c63321b1be7a8cad7bf5c5c216fcf062c",
@ -102,7 +102,7 @@ def test_send_bch_change(client: Client):
)
def test_send_bch_nochange(client: Client):
def test_send_bch_nochange(session: Session):
inp1 = messages.TxInputType(
address_n=parse_path("m/44h/145h/0h/1/0"),
# bitcoincash:qzc5q87w069lzg7g3gzx0c8dz83mn7l02scej5aluw
@ -124,14 +124,14 @@ def test_send_bch_nochange(client: Client):
amount=1_934_960,
script_type=messages.OutputScriptType.PAYTOADDRESS,
)
with client:
client.set_expected_responses(
with session:
session.set_expected_responses(
[
request_input(0),
request_input(1),
request_output(0),
messages.ButtonRequest(code=B.ConfirmOutput),
(is_core(client), messages.ButtonRequest(code=B.ConfirmOutput)),
(is_core(session), messages.ButtonRequest(code=B.ConfirmOutput)),
messages.ButtonRequest(code=B.SignTx),
request_input(0),
request_meta(TXHASH_502e85),
@ -150,7 +150,7 @@ def test_send_bch_nochange(client: Client):
]
)
_, serialized_tx = btc.sign_tx(
client, "Bcash", [inp1, inp2], [out1], prev_txes=TX_API
session, "Bcash", [inp1, inp2], [out1], prev_txes=TX_API
)
assert_tx_matches(
@ -160,7 +160,7 @@ def test_send_bch_nochange(client: Client):
)
def test_send_bch_oldaddr(client: Client):
def test_send_bch_oldaddr(session: Session):
inp1 = messages.TxInputType(
address_n=parse_path("m/44h/145h/0h/1/0"),
# bitcoincash:qzc5q87w069lzg7g3gzx0c8dz83mn7l02scej5aluw
@ -182,14 +182,14 @@ def test_send_bch_oldaddr(client: Client):
amount=1_934_960,
script_type=messages.OutputScriptType.PAYTOADDRESS,
)
with client:
client.set_expected_responses(
with session:
session.set_expected_responses(
[
request_input(0),
request_input(1),
request_output(0),
messages.ButtonRequest(code=B.ConfirmOutput),
(is_core(client), messages.ButtonRequest(code=B.ConfirmOutput)),
(is_core(session), messages.ButtonRequest(code=B.ConfirmOutput)),
messages.ButtonRequest(code=B.SignTx),
request_input(0),
request_meta(TXHASH_502e85),
@ -208,7 +208,7 @@ def test_send_bch_oldaddr(client: Client):
]
)
_, serialized_tx = btc.sign_tx(
client, "Bcash", [inp1, inp2], [out1], prev_txes=TX_API
session, "Bcash", [inp1, inp2], [out1], prev_txes=TX_API
)
assert_tx_matches(
@ -218,7 +218,7 @@ def test_send_bch_oldaddr(client: Client):
)
def test_attack_change_input(client: Client):
def test_attack_change_input(session: Session):
# NOTE: fake input tx used
inp1 = messages.TxInputType(
@ -252,15 +252,15 @@ def test_attack_change_input(client: Client):
return msg
with client:
client.set_filter(messages.TxAck, attack_processor)
client.set_expected_responses(
with session:
session.set_filter(messages.TxAck, attack_processor)
session.set_expected_responses(
[
request_input(0),
request_output(0),
request_output(1),
messages.ButtonRequest(code=B.ConfirmOutput),
(is_core(client), messages.ButtonRequest(code=B.ConfirmOutput)),
(is_core(session), messages.ButtonRequest(code=B.ConfirmOutput)),
messages.ButtonRequest(code=B.SignTx),
request_input(0),
request_meta(FAKE_TXHASH_bd32ff),
@ -271,16 +271,16 @@ def test_attack_change_input(client: Client):
]
)
with pytest.raises(TrezorFailure):
btc.sign_tx(client, "Bcash", [inp1], [out1, out2], prev_txes=TX_API)
btc.sign_tx(session, "Bcash", [inp1], [out1, out2], prev_txes=TX_API)
@pytest.mark.multisig
def test_send_bch_multisig_wrongchange(client: Client):
def test_send_bch_multisig_wrongchange(session: Session):
# NOTE: fake input tx used
nodes = [
btc.get_public_node(
client, parse_path(f"m/48h/145h/{i}h/0h"), coin_name="Bcash"
session, parse_path(f"m/48h/145h/{i}h/0h"), coin_name="Bcash"
).node
for i in range(1, 4)
]
@ -327,13 +327,13 @@ def test_send_bch_multisig_wrongchange(client: Client):
script_type=messages.OutputScriptType.PAYTOMULTISIG,
amount=23_000,
)
with client:
client.set_expected_responses(
with session:
session.set_expected_responses(
[
request_input(0),
request_output(0),
messages.ButtonRequest(code=B.ConfirmOutput),
(is_core(client), messages.ButtonRequest(code=B.ConfirmOutput)),
(is_core(session), messages.ButtonRequest(code=B.ConfirmOutput)),
messages.ButtonRequest(code=B.SignTx),
request_input(0),
request_meta(FAKE_TXHASH_062fbd),
@ -346,7 +346,7 @@ def test_send_bch_multisig_wrongchange(client: Client):
]
)
(signatures1, serialized_tx) = btc.sign_tx(
client, "Bcash", [inp1], [out1], prev_txes=TX_API
session, "Bcash", [inp1], [out1], prev_txes=TX_API
)
assert (
signatures1[0].hex()
@ -359,12 +359,12 @@ def test_send_bch_multisig_wrongchange(client: Client):
@pytest.mark.multisig
def test_send_bch_multisig_change(client: Client):
def test_send_bch_multisig_change(session: Session):
# NOTE: fake input tx used
nodes = [
btc.get_public_node(
client, parse_path(f"m/48h/145h/{i}h/0h"), coin_name="Bcash"
session, parse_path(f"m/48h/145h/{i}h/0h"), coin_name="Bcash"
).node
for i in range(1, 4)
]
@ -395,13 +395,13 @@ def test_send_bch_multisig_change(client: Client):
script_type=messages.OutputScriptType.PAYTOMULTISIG,
amount=24_000,
)
with client:
client.set_expected_responses(
with session:
session.set_expected_responses(
[
request_input(0),
request_output(0),
messages.ButtonRequest(code=B.ConfirmOutput),
(is_core(client), messages.ButtonRequest(code=B.ConfirmOutput)),
(is_core(session), messages.ButtonRequest(code=B.ConfirmOutput)),
request_output(1),
messages.ButtonRequest(code=B.SignTx),
request_input(0),
@ -415,7 +415,7 @@ def test_send_bch_multisig_change(client: Client):
]
)
(signatures1, serialized_tx) = btc.sign_tx(
client, "Bcash", [inp1], [out1, out2], prev_txes=TX_API
session, "Bcash", [inp1], [out1, out2], prev_txes=TX_API
)
assert (
@ -434,13 +434,13 @@ def test_send_bch_multisig_change(client: Client):
)
out2.address_n[2] = H_(1)
with client:
client.set_expected_responses(
with session:
session.set_expected_responses(
[
request_input(0),
request_output(0),
messages.ButtonRequest(code=B.ConfirmOutput),
(is_core(client), messages.ButtonRequest(code=B.ConfirmOutput)),
(is_core(session), messages.ButtonRequest(code=B.ConfirmOutput)),
request_output(1),
messages.ButtonRequest(code=B.SignTx),
request_input(0),
@ -454,7 +454,7 @@ def test_send_bch_multisig_change(client: Client):
]
)
(signatures1, serialized_tx) = btc.sign_tx(
client, "Bcash", [inp1], [out1, out2], prev_txes=TX_API
session, "Bcash", [inp1], [out1, out2], prev_txes=TX_API
)
assert (
@ -468,7 +468,7 @@ def test_send_bch_multisig_change(client: Client):
@pytest.mark.models("core")
def test_send_bch_external_presigned(client: Client):
def test_send_bch_external_presigned(session: Session):
inp1 = messages.TxInputType(
# address_n=parse_path("44'/145'/0'/1/0"),
# bitcoincash:qzc5q87w069lzg7g3gzx0c8dz83mn7l02scej5aluw
@ -496,14 +496,14 @@ def test_send_bch_external_presigned(client: Client):
amount=1_934_960,
script_type=messages.OutputScriptType.PAYTOADDRESS,
)
with client:
client.set_expected_responses(
with session:
session.set_expected_responses(
[
request_input(0),
request_input(1),
request_output(0),
messages.ButtonRequest(code=B.ConfirmOutput),
(is_core(client), messages.ButtonRequest(code=B.ConfirmOutput)),
(is_core(session), messages.ButtonRequest(code=B.ConfirmOutput)),
messages.ButtonRequest(code=B.SignTx),
request_input(0),
request_meta(TXHASH_502e85),
@ -522,7 +522,7 @@ def test_send_bch_external_presigned(client: Client):
]
)
_, serialized_tx = btc.sign_tx(
client, "Bcash", [inp1, inp2], [out1], prev_txes=TX_API
session, "Bcash", [inp1, inp2], [out1], prev_txes=TX_API
)
assert_tx_matches(

View File

@ -17,7 +17,7 @@
import pytest
from trezorlib import btc, messages
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.debuglink import SessionDebugWrapper as Session
from trezorlib.exceptions import TrezorFailure
from trezorlib.tools import H_, parse_path, tx_hash
@ -51,7 +51,7 @@ pytestmark = [pytest.mark.altcoin, pytest.mark.models("t1b1", "t2t1")]
# All data taken from T1
def test_send_bitcoin_gold_change(client: Client):
def test_send_bitcoin_gold_change(session: Session):
# NOTE: fake input tx used
inp1 = messages.TxInputType(
@ -71,14 +71,14 @@ def test_send_bitcoin_gold_change(client: Client):
amount=1_252_382_934 - 1_896_050 - 1_000,
script_type=messages.OutputScriptType.PAYTOADDRESS,
)
with client:
client.set_expected_responses(
with session:
session.set_expected_responses(
[
request_input(0),
request_output(0),
request_output(1),
messages.ButtonRequest(code=B.ConfirmOutput),
(is_core(client), messages.ButtonRequest(code=B.ConfirmOutput)),
(is_core(session), messages.ButtonRequest(code=B.ConfirmOutput)),
messages.ButtonRequest(code=B.SignTx),
request_input(0),
request_meta(FAKE_TXHASH_6f0398),
@ -92,7 +92,7 @@ def test_send_bitcoin_gold_change(client: Client):
]
)
_, serialized_tx = btc.sign_tx(
client, "Bgold", [inp1], [out1, out2], prev_txes=TX_API
session, "Bgold", [inp1], [out1, out2], prev_txes=TX_API
)
assert (
@ -101,7 +101,7 @@ def test_send_bitcoin_gold_change(client: Client):
)
def test_send_bitcoin_gold_nochange(client: Client):
def test_send_bitcoin_gold_nochange(session: Session):
# NOTE: fake input tx used
inp1 = messages.TxInputType(
@ -124,14 +124,14 @@ def test_send_bitcoin_gold_nochange(client: Client):
amount=1_252_382_934 + 38_448_607 - 1_000,
script_type=messages.OutputScriptType.PAYTOADDRESS,
)
with client:
client.set_expected_responses(
with session:
session.set_expected_responses(
[
request_input(0),
request_input(1),
request_output(0),
messages.ButtonRequest(code=B.ConfirmOutput),
(is_core(client), messages.ButtonRequest(code=B.ConfirmOutput)),
(is_core(session), messages.ButtonRequest(code=B.ConfirmOutput)),
messages.ButtonRequest(code=B.SignTx),
request_input(0),
request_meta(FAKE_TXHASH_6f0398),
@ -150,7 +150,7 @@ def test_send_bitcoin_gold_nochange(client: Client):
]
)
_, serialized_tx = btc.sign_tx(
client, "Bgold", [inp1, inp2], [out1], prev_txes=TX_API
session, "Bgold", [inp1, inp2], [out1], prev_txes=TX_API
)
assert (
@ -159,7 +159,7 @@ def test_send_bitcoin_gold_nochange(client: Client):
)
def test_attack_change_input(client: Client):
def test_attack_change_input(session: Session):
# NOTE: fake input tx used
inp1 = messages.TxInputType(
@ -193,15 +193,15 @@ def test_attack_change_input(client: Client):
return msg
with client:
client.set_filter(messages.TxAck, attack_processor)
client.set_expected_responses(
with session:
session.set_filter(messages.TxAck, attack_processor)
session.set_expected_responses(
[
request_input(0),
request_output(0),
request_output(1),
messages.ButtonRequest(code=B.ConfirmOutput),
(is_core(client), messages.ButtonRequest(code=B.ConfirmOutput)),
(is_core(session), messages.ButtonRequest(code=B.ConfirmOutput)),
messages.ButtonRequest(code=B.SignTx),
request_input(0),
request_meta(FAKE_TXHASH_6f0398),
@ -213,16 +213,16 @@ def test_attack_change_input(client: Client):
]
)
with pytest.raises(TrezorFailure):
btc.sign_tx(client, "Bgold", [inp1], [out1, out2], prev_txes=TX_API)
btc.sign_tx(session, "Bgold", [inp1], [out1, out2], prev_txes=TX_API)
@pytest.mark.multisig
def test_send_btg_multisig_change(client: Client):
def test_send_btg_multisig_change(session: Session):
# NOTE: fake input tx used
nodes = [
btc.get_public_node(
client, parse_path(f"m/48h/156h/{i}h/0h"), coin_name="Bgold"
session, parse_path(f"m/48h/156h/{i}h/0h"), coin_name="Bgold"
).node
for i in range(1, 4)
]
@ -254,13 +254,13 @@ def test_send_btg_multisig_change(client: Client):
script_type=messages.OutputScriptType.PAYTOMULTISIG,
amount=1_252_382_934 - 24_000 - 1_000,
)
with client:
client.set_expected_responses(
with session:
session.set_expected_responses(
[
request_input(0),
request_output(0),
messages.ButtonRequest(code=B.ConfirmOutput),
(is_core(client), messages.ButtonRequest(code=B.ConfirmOutput)),
(is_core(session), messages.ButtonRequest(code=B.ConfirmOutput)),
request_output(1),
messages.ButtonRequest(code=B.SignTx),
request_input(0),
@ -275,7 +275,7 @@ def test_send_btg_multisig_change(client: Client):
]
)
signatures, serialized_tx = btc.sign_tx(
client, "Bgold", [inp1], [out1, out2], prev_txes=TX_API
session, "Bgold", [inp1], [out1, out2], prev_txes=TX_API
)
assert (
@ -293,13 +293,13 @@ def test_send_btg_multisig_change(client: Client):
)
out2.address_n[2] = H_(1)
with client:
client.set_expected_responses(
with session:
session.set_expected_responses(
[
request_input(0),
request_output(0),
messages.ButtonRequest(code=B.ConfirmOutput),
(is_core(client), messages.ButtonRequest(code=B.ConfirmOutput)),
(is_core(session), messages.ButtonRequest(code=B.ConfirmOutput)),
request_output(1),
messages.ButtonRequest(code=B.SignTx),
request_input(0),
@ -314,7 +314,7 @@ def test_send_btg_multisig_change(client: Client):
]
)
signatures, serialized_tx = btc.sign_tx(
client, "Bgold", [inp1], [out1, out2], prev_txes=TX_API
session, "Bgold", [inp1], [out1, out2], prev_txes=TX_API
)
assert (
@ -327,7 +327,7 @@ def test_send_btg_multisig_change(client: Client):
)
def test_send_p2sh(client: Client):
def test_send_p2sh(session: Session):
# NOTE: fake input tx used
inp1 = messages.TxInputType(
@ -347,16 +347,16 @@ def test_send_p2sh(client: Client):
script_type=messages.OutputScriptType.PAYTOADDRESS,
amount=1_252_382_934 - 11_000 - 12_300_000,
)
with client:
client.set_expected_responses(
with session:
session.set_expected_responses(
[
request_input(0),
request_output(0),
messages.ButtonRequest(code=B.ConfirmOutput),
(is_core(client), messages.ButtonRequest(code=B.ConfirmOutput)),
(is_core(session), messages.ButtonRequest(code=B.ConfirmOutput)),
request_output(1),
messages.ButtonRequest(code=B.ConfirmOutput),
(is_core(client), messages.ButtonRequest(code=B.ConfirmOutput)),
(is_core(session), messages.ButtonRequest(code=B.ConfirmOutput)),
messages.ButtonRequest(code=B.SignTx),
request_input(0),
request_meta(FAKE_TXHASH_db7239),
@ -371,7 +371,7 @@ def test_send_p2sh(client: Client):
]
)
_, serialized_tx = btc.sign_tx(
client, "Bgold", [inp1], [out1, out2], prev_txes=TX_API
session, "Bgold", [inp1], [out1, out2], prev_txes=TX_API
)
assert (
@ -380,7 +380,7 @@ def test_send_p2sh(client: Client):
)
def test_send_p2sh_witness_change(client: Client):
def test_send_p2sh_witness_change(session: Session):
# NOTE: fake input tx used
inp1 = messages.TxInputType(
@ -400,13 +400,13 @@ def test_send_p2sh_witness_change(client: Client):
script_type=messages.OutputScriptType.PAYTOP2SHWITNESS,
amount=1_252_382_934 - 11_000 - 12_300_000,
)
with client:
client.set_expected_responses(
with session:
session.set_expected_responses(
[
request_input(0),
request_output(0),
messages.ButtonRequest(code=B.ConfirmOutput),
(is_core(client), messages.ButtonRequest(code=B.ConfirmOutput)),
(is_core(session), messages.ButtonRequest(code=B.ConfirmOutput)),
request_output(1),
messages.ButtonRequest(code=B.SignTx),
request_input(0),
@ -422,7 +422,7 @@ def test_send_p2sh_witness_change(client: Client):
]
)
_, serialized_tx = btc.sign_tx(
client, "Bgold", [inp1], [out1, out2], prev_txes=TX_API
session, "Bgold", [inp1], [out1, out2], prev_txes=TX_API
)
assert (
@ -432,12 +432,12 @@ def test_send_p2sh_witness_change(client: Client):
@pytest.mark.multisig
def test_send_multisig_1(client: Client):
def test_send_multisig_1(session: Session):
# NOTE: fake input tx used
nodes = [
btc.get_public_node(
client, parse_path(f"m/49h/156h/{i}h"), coin_name="Bgold"
session, parse_path(f"m/49h/156h/{i}h"), coin_name="Bgold"
).node
for i in range(1, 4)
]
@ -460,13 +460,13 @@ def test_send_multisig_1(client: Client):
script_type=messages.OutputScriptType.PAYTOADDRESS,
)
with client:
client.set_expected_responses(
with session:
session.set_expected_responses(
[
request_input(0),
request_output(0),
messages.ButtonRequest(code=B.ConfirmOutput),
(is_core(client), messages.ButtonRequest(code=B.ConfirmOutput)),
(is_core(session), messages.ButtonRequest(code=B.ConfirmOutput)),
messages.ButtonRequest(code=B.SignTx),
request_input(0),
request_meta(FAKE_TXHASH_7f1f6b),
@ -479,17 +479,17 @@ def test_send_multisig_1(client: Client):
request_finished(),
]
)
signatures, _ = btc.sign_tx(client, "Bgold", [inp1], [out1], prev_txes=TX_API)
signatures, _ = btc.sign_tx(session, "Bgold", [inp1], [out1], prev_txes=TX_API)
# store signature
inp1.multisig.signatures[0] = signatures[0]
# sign with third key
inp1.address_n[2] = H_(3)
client.set_expected_responses(
session.set_expected_responses(
[
request_input(0),
request_output(0),
messages.ButtonRequest(code=B.ConfirmOutput),
(is_core(client), messages.ButtonRequest(code=B.ConfirmOutput)),
(is_core(session), messages.ButtonRequest(code=B.ConfirmOutput)),
messages.ButtonRequest(code=B.SignTx),
request_input(0),
request_meta(FAKE_TXHASH_7f1f6b),
@ -503,7 +503,7 @@ def test_send_multisig_1(client: Client):
]
)
_, serialized_tx = btc.sign_tx(
client, "Bgold", [inp1], [out1], prev_txes=TX_API
session, "Bgold", [inp1], [out1], prev_txes=TX_API
)
assert (
@ -512,7 +512,7 @@ def test_send_multisig_1(client: Client):
)
def test_send_mixed_inputs(client: Client):
def test_send_mixed_inputs(session: Session):
# NOTE: fake input tx used
# First is non-segwit, second is segwit.
@ -537,9 +537,9 @@ def test_send_mixed_inputs(client: Client):
script_type=messages.OutputScriptType.PAYTOADDRESS,
)
with client:
with session:
_, serialized_tx = btc.sign_tx(
client, "Bgold", [inp1, inp2], [out1], prev_txes=TX_API
session, "Bgold", [inp1, inp2], [out1], prev_txes=TX_API
)
assert (
@ -549,7 +549,7 @@ def test_send_mixed_inputs(client: Client):
@pytest.mark.models("core")
def test_send_btg_external_presigned(client: Client):
def test_send_btg_external_presigned(session: Session):
# NOTE: fake input tx used
inp1 = messages.TxInputType(
@ -577,14 +577,14 @@ def test_send_btg_external_presigned(client: Client):
amount=1_252_382_934 + 58_456 - 1_000,
script_type=messages.OutputScriptType.PAYTOADDRESS,
)
with client:
client.set_expected_responses(
with session:
session.set_expected_responses(
[
request_input(0),
request_input(1),
request_output(0),
messages.ButtonRequest(code=B.ConfirmOutput),
(is_core(client), messages.ButtonRequest(code=B.ConfirmOutput)),
(is_core(session), messages.ButtonRequest(code=B.ConfirmOutput)),
messages.ButtonRequest(code=B.SignTx),
request_input(0),
request_meta(FAKE_TXHASH_6f0398),
@ -603,7 +603,7 @@ def test_send_btg_external_presigned(client: Client):
]
)
_, serialized_tx = btc.sign_tx(
client, "Bgold", [inp1, inp2], [out1], prev_txes=TX_API
session, "Bgold", [inp1, inp2], [out1], prev_txes=TX_API
)
assert (

View File

@ -17,7 +17,7 @@
import pytest
from trezorlib import btc, messages
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.debuglink import SessionDebugWrapper as Session
from trezorlib.tools import parse_path
from ...common import is_core
@ -43,7 +43,7 @@ TXHASH_15575a = bytes.fromhex(
pytestmark = [pytest.mark.altcoin, pytest.mark.models("t1b1", "t2t1")]
def test_send_dash(client: Client):
def test_send_dash(session: Session):
inp1 = messages.TxInputType(
address_n=parse_path("m/44h/5h/0h/0/0"),
# dash:XdTw4G5AWW4cogGd7ayybyBNDbuB45UpgH
@ -57,13 +57,13 @@ def test_send_dash(client: Client):
amount=999_999_000,
script_type=messages.OutputScriptType.PAYTOADDRESS,
)
with client:
client.set_expected_responses(
with session:
session.set_expected_responses(
[
request_input(0),
request_output(0),
messages.ButtonRequest(code=B.ConfirmOutput),
(is_core(client), messages.ButtonRequest(code=B.ConfirmOutput)),
(is_core(session), messages.ButtonRequest(code=B.ConfirmOutput)),
messages.ButtonRequest(code=B.SignTx),
request_input(0),
request_meta(inp1.prev_hash),
@ -77,7 +77,9 @@ def test_send_dash(client: Client):
request_finished(),
]
)
_, serialized_tx = btc.sign_tx(client, "Dash", [inp1], [out1], prev_txes=TX_API)
_, serialized_tx = btc.sign_tx(
session, "Dash", [inp1], [out1], prev_txes=TX_API
)
assert (
serialized_tx.hex()
@ -85,7 +87,7 @@ def test_send_dash(client: Client):
)
def test_send_dash_dip2_input(client: Client):
def test_send_dash_dip2_input(session: Session):
inp1 = messages.TxInputType(
address_n=parse_path("m/44h/5h/0h/0/0"),
# dash:XdTw4G5AWW4cogGd7ayybyBNDbuB45UpgH
@ -104,14 +106,14 @@ def test_send_dash_dip2_input(client: Client):
amount=95_000_000,
script_type=messages.OutputScriptType.PAYTOADDRESS,
)
with client:
client.set_expected_responses(
with session:
session.set_expected_responses(
[
request_input(0),
request_output(0),
request_output(1),
messages.ButtonRequest(code=B.ConfirmOutput),
(is_core(client), messages.ButtonRequest(code=B.ConfirmOutput)),
(is_core(session), messages.ButtonRequest(code=B.ConfirmOutput)),
messages.ButtonRequest(code=B.SignTx),
request_input(0),
request_meta(inp1.prev_hash),
@ -128,7 +130,7 @@ def test_send_dash_dip2_input(client: Client):
]
)
_, serialized_tx = btc.sign_tx(
client, "Dash", [inp1], [out1, out2], prev_txes=TX_API
session, "Dash", [inp1], [out1, out2], prev_txes=TX_API
)
assert (

View File

@ -17,7 +17,7 @@
import pytest
from trezorlib import btc, messages
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.debuglink import SessionDebugWrapper as Session
from trezorlib.tools import parse_path
from ...common import is_core
@ -57,7 +57,7 @@ pytestmark = [
]
def test_send_decred(client: Client):
def test_send_decred(session: Session):
# NOTE: fake input tx used
inp1 = messages.TxInputType(
@ -76,13 +76,13 @@ def test_send_decred(client: Client):
script_type=messages.OutputScriptType.PAYTOADDRESS,
)
with client:
client.set_expected_responses(
with session:
session.set_expected_responses(
[
request_input(0),
request_output(0),
messages.ButtonRequest(code=B.ConfirmOutput),
(is_core(client), messages.ButtonRequest(code=B.ConfirmOutput)),
(is_core(session), messages.ButtonRequest(code=B.ConfirmOutput)),
messages.ButtonRequest(code=B.FeeOverThreshold),
messages.ButtonRequest(code=B.SignTx),
request_input(0),
@ -95,7 +95,7 @@ def test_send_decred(client: Client):
]
)
_, serialized_tx = btc.sign_tx(
client, "Decred Testnet", [inp1], [out1], prev_txes=TX_API
session, "Decred Testnet", [inp1], [out1], prev_txes=TX_API
)
assert (
@ -105,7 +105,7 @@ def test_send_decred(client: Client):
@pytest.mark.models("core")
def test_purchase_ticket_decred(client: Client):
def test_purchase_ticket_decred(session: Session):
# NOTE: fake input tx used
inp1 = messages.TxInputType(
@ -133,8 +133,8 @@ def test_purchase_ticket_decred(client: Client):
script_type=messages.OutputScriptType.PAYTOADDRESS,
)
with client:
client.set_expected_responses(
with session:
session.set_expected_responses(
[
request_input(0),
request_output(0),
@ -153,7 +153,7 @@ def test_purchase_ticket_decred(client: Client):
]
)
_, serialized_tx = btc.sign_tx(
client,
session,
"Decred Testnet",
[inp1],
[out1, out2, out3],
@ -168,7 +168,7 @@ def test_purchase_ticket_decred(client: Client):
@pytest.mark.models("core")
def test_spend_from_stake_generation_and_revocation_decred(client: Client):
def test_spend_from_stake_generation_and_revocation_decred(session: Session):
# NOTE: fake input tx used
inp1 = messages.TxInputType(
@ -197,14 +197,14 @@ def test_spend_from_stake_generation_and_revocation_decred(client: Client):
script_type=messages.OutputScriptType.PAYTOADDRESS,
)
with client:
client.set_expected_responses(
with session:
session.set_expected_responses(
[
request_input(0),
request_input(1),
request_output(0),
messages.ButtonRequest(code=B.ConfirmOutput),
(is_core(client), messages.ButtonRequest(code=B.ConfirmOutput)),
(is_core(session), messages.ButtonRequest(code=B.ConfirmOutput)),
messages.ButtonRequest(code=B.SignTx),
request_input(0),
request_meta(FAKE_TXHASH_8b6890),
@ -223,7 +223,7 @@ def test_spend_from_stake_generation_and_revocation_decred(client: Client):
]
)
_, serialized_tx = btc.sign_tx(
client, "Decred Testnet", [inp1, inp2], [out1], prev_txes=TX_API
session, "Decred Testnet", [inp1, inp2], [out1], prev_txes=TX_API
)
assert (
@ -232,7 +232,7 @@ def test_spend_from_stake_generation_and_revocation_decred(client: Client):
)
def test_send_decred_change(client: Client):
def test_send_decred_change(session: Session):
# NOTE: fake input tx used
inp1 = messages.TxInputType(
@ -278,15 +278,15 @@ def test_send_decred_change(client: Client):
script_type=messages.OutputScriptType.PAYTOADDRESS,
)
with client:
client.set_expected_responses(
with session:
session.set_expected_responses(
[
request_input(0),
request_input(1),
request_input(2),
request_output(0),
messages.ButtonRequest(code=B.ConfirmOutput),
(is_core(client), messages.ButtonRequest(code=B.ConfirmOutput)),
(is_core(session), messages.ButtonRequest(code=B.ConfirmOutput)),
request_output(1),
messages.ButtonRequest(code=B.SignTx),
request_input(0),
@ -311,7 +311,7 @@ def test_send_decred_change(client: Client):
]
)
_, serialized_tx = btc.sign_tx(
client,
session,
"Decred Testnet",
[inp1, inp2, inp3],
[out1, out2],
@ -325,12 +325,12 @@ def test_send_decred_change(client: Client):
@pytest.mark.multisig
def test_decred_multisig_change(client: Client):
def test_decred_multisig_change(session: Session):
# NOTE: fake input tx used
paths = [parse_path(f"m/48h/1h/{index}'/0'") for index in range(3)]
nodes = [
btc.get_public_node(client, address_n, coin_name="Decred Testnet").node
btc.get_public_node(session, address_n, coin_name="Decred Testnet").node
for address_n in paths
]
@ -384,15 +384,15 @@ def test_decred_multisig_change(client: Client):
script_type=messages.OutputScriptType.PAYTOADDRESS,
)
with client:
client.set_expected_responses(
with session:
session.set_expected_responses(
[
request_input(0),
request_input(1),
request_output(0),
request_output(1),
messages.ButtonRequest(code=B.ConfirmOutput),
(is_core(client), messages.ButtonRequest(code=B.ConfirmOutput)),
(is_core(session), messages.ButtonRequest(code=B.ConfirmOutput)),
messages.ButtonRequest(code=B.SignTx),
request_input(0),
request_meta(FAKE_TXHASH_9ac7d2),
@ -410,7 +410,7 @@ def test_decred_multisig_change(client: Client):
]
)
signature, serialized_tx = btc.sign_tx(
client,
session,
"Decred Testnet",
[inp1, inp2],
[out1, out2],

View File

@ -18,7 +18,7 @@ import pytest
from trezorlib import btc, messages, models
from trezorlib.cli import btc as btc_cli
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.debuglink import SessionDebugWrapper as Session
from trezorlib.tools import H_
from ...input_flows import InputFlowShowXpubQRCode
@ -165,14 +165,16 @@ def _address_n(purpose, coin, account, script_type):
@pytest.mark.parametrize(
"coin, account, purpose, script_type, descriptors", VECTORS_DESCRIPTORS
)
def test_descriptors(client: Client, coin, account, purpose, script_type, descriptors):
with client:
def test_descriptors(
session: Session, coin, account, purpose, script_type, descriptors
):
with session.client as client:
IF = InputFlowShowXpubQRCode(client)
client.set_input_flow(IF.get())
address_n = _address_n(purpose, coin, account, script_type)
res = btc.get_public_node(
client,
session,
_address_n(purpose, coin, account, script_type),
show_display=True,
coin_name=coin,
@ -187,13 +189,13 @@ def test_descriptors(client: Client, coin, account, purpose, script_type, descri
"coin, account, purpose, script_type, descriptors", VECTORS_DESCRIPTORS
)
def test_descriptors_trezorlib(
client: Client, coin, account, purpose, script_type, descriptors
session: Session, coin, account, purpose, script_type, descriptors
):
with client:
with session.client as client:
if client.model != models.T1B1:
IF = InputFlowShowXpubQRCode(client)
client.set_input_flow(IF.get())
res = btc_cli._get_descriptor(
client, coin, account, purpose, script_type, show_display=True
session, coin, account, purpose, script_type, show_display=True
)
assert res == descriptors

View File

@ -17,7 +17,7 @@
import pytest
from trezorlib import btc, messages
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.debuglink import SessionDebugWrapper as Session
from trezorlib.tools import parse_path
from ...tx_cache import TxCache
@ -30,7 +30,7 @@ TXHASH_8a34cc = bytes.fromhex(
@pytest.mark.altcoin
def test_spend_lelantus(client: Client):
def test_spend_lelantus(session: Session):
inp1 = messages.TxInputType(
# THgGLVqfzJcaxRVPWE5fd8YJ1GpVePq2Uk
address_n=parse_path("m/44h/1h/0h/0/4"),
@ -45,7 +45,7 @@ def test_spend_lelantus(client: Client):
script_type=messages.OutputScriptType.PAYTOADDRESS,
)
_, serialized_tx = btc.sign_tx(
client, "Firo Testnet", [inp1], [out1], prev_txes=TX_API
session, "Firo Testnet", [inp1], [out1], prev_txes=TX_API
)
assert_tx_matches(
serialized_tx,

View File

@ -17,7 +17,7 @@
import pytest
from trezorlib import btc, messages
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.debuglink import SessionDebugWrapper as Session
from trezorlib.tools import parse_path
TXHASH_33043a = bytes.fromhex(
@ -27,7 +27,7 @@ TXHASH_33043a = bytes.fromhex(
pytestmark = pytest.mark.altcoin
def test_send_p2tr(client: Client):
def test_send_p2tr(session: Session):
inp1 = messages.TxInputType(
# fc1prr07akly3xjtmggue0p04vghr8pdcgxrye2s00sahptwjeawxrkq2rxzr7
address_n=parse_path("m/86h/75h/0h/0/1"),
@ -42,7 +42,7 @@ def test_send_p2tr(client: Client):
amount=99_996_670_000,
script_type=messages.OutputScriptType.PAYTOADDRESS,
)
_, serialized_tx = btc.sign_tx(client, "Fujicoin", [inp1], [out1])
_, serialized_tx = btc.sign_tx(session, "Fujicoin", [inp1], [out1])
# Transaction hex changed with fix #2085, all other details are the same as this tx:
# https://explorer.fujicoin.org/tx/a1c6a81f5e8023b17e6e3e51e2596d5b5e1d4914ea13c0c31cef90b3c3edee86
assert (

View File

@ -17,7 +17,7 @@
import pytest
from trezorlib import btc, device, messages
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.debuglink import SessionDebugWrapper as Session
from trezorlib.exceptions import TrezorFailure
from trezorlib.messages import MultisigPubkeysOrder, SafetyCheckLevel
from trezorlib.tools import parse_path
@ -36,112 +36,112 @@ def getmultisig(chain, nr, xpubs):
)
def test_btc(client: Client):
def test_btc(session: Session):
assert (
btc.get_address(client, "Bitcoin", parse_path("m/44h/0h/0h/0/0"))
btc.get_address(session, "Bitcoin", parse_path("m/44h/0h/0h/0/0"))
== "1JAd7XCBzGudGpJQSDSfpmJhiygtLQWaGL"
)
assert (
btc.get_address(client, "Bitcoin", parse_path("m/44h/0h/0h/0/1"))
btc.get_address(session, "Bitcoin", parse_path("m/44h/0h/0h/0/1"))
== "1GWFxtwWmNVqotUPXLcKVL2mUKpshuJYo"
)
assert (
btc.get_address(client, "Bitcoin", parse_path("m/44h/0h/0h/1/0"))
btc.get_address(session, "Bitcoin", parse_path("m/44h/0h/0h/1/0"))
== "1DyHzbQUoQEsLxJn6M7fMD8Xdt1XvNiwNE"
)
@pytest.mark.altcoin
def test_ltc(client: Client):
def test_ltc(session: Session):
assert (
btc.get_address(client, "Litecoin", parse_path("m/44h/2h/0h/0/0"))
btc.get_address(session, "Litecoin", parse_path("m/44h/2h/0h/0/0"))
== "LcubERmHD31PWup1fbozpKuiqjHZ4anxcL"
)
assert (
btc.get_address(client, "Litecoin", parse_path("m/44h/2h/0h/0/1"))
btc.get_address(session, "Litecoin", parse_path("m/44h/2h/0h/0/1"))
== "LVWBmHBkCGNjSPHucvL2PmnuRAJnucmRE6"
)
assert (
btc.get_address(client, "Litecoin", parse_path("m/44h/2h/0h/1/0"))
btc.get_address(session, "Litecoin", parse_path("m/44h/2h/0h/1/0"))
== "LWj6ApswZxay4cJEJES2sGe7fLMLRvvv8h"
)
def test_tbtc(client: Client):
def test_tbtc(session: Session):
assert (
btc.get_address(client, "Testnet", parse_path("m/44h/1h/0h/0/0"))
btc.get_address(session, "Testnet", parse_path("m/44h/1h/0h/0/0"))
== "mvbu1Gdy8SUjTenqerxUaZyYjmveZvt33q"
)
assert (
btc.get_address(client, "Testnet", parse_path("m/44h/1h/0h/0/1"))
btc.get_address(session, "Testnet", parse_path("m/44h/1h/0h/0/1"))
== "mopZWqZZyQc3F2Sy33cvDtJchSAMsnLi7b"
)
assert (
btc.get_address(client, "Testnet", parse_path("m/44h/1h/0h/1/0"))
btc.get_address(session, "Testnet", parse_path("m/44h/1h/0h/1/0"))
== "mm6kLYbGEL1tGe4ZA8xacfgRPdW1NLjCbZ"
)
@pytest.mark.altcoin
def test_bch(client: Client):
def test_bch(session: Session):
assert (
btc.get_address(client, "Bcash", parse_path("m/44h/145h/0h/0/0"))
btc.get_address(session, "Bcash", parse_path("m/44h/145h/0h/0/0"))
== "bitcoincash:qr08q88p9etk89wgv05nwlrkm4l0urz4cyl36hh9sv"
)
assert (
btc.get_address(client, "Bcash", parse_path("m/44h/145h/0h/0/1"))
btc.get_address(session, "Bcash", parse_path("m/44h/145h/0h/0/1"))
== "bitcoincash:qr23ajjfd9wd73l87j642puf8cad20lfmqdgwvpat4"
)
assert (
btc.get_address(client, "Bcash", parse_path("m/44h/145h/0h/1/0"))
btc.get_address(session, "Bcash", parse_path("m/44h/145h/0h/1/0"))
== "bitcoincash:qzc5q87w069lzg7g3gzx0c8dz83mn7l02scej5aluw"
)
@pytest.mark.altcoin
def test_grs(client: Client):
def test_grs(session: Session):
assert (
btc.get_address(client, "Groestlcoin", parse_path("m/44h/17h/0h/0/0"))
btc.get_address(session, "Groestlcoin", parse_path("m/44h/17h/0h/0/0"))
== "Fj62rBJi8LvbmWu2jzkaUX1NFXLEqDLoZM"
)
assert (
btc.get_address(client, "Groestlcoin", parse_path("m/44h/17h/0h/1/0"))
btc.get_address(session, "Groestlcoin", parse_path("m/44h/17h/0h/1/0"))
== "FmRaqvVBRrAp2Umfqx9V1ectZy8gw54QDN"
)
assert (
btc.get_address(client, "Groestlcoin", parse_path("m/44h/17h/0h/1/1"))
btc.get_address(session, "Groestlcoin", parse_path("m/44h/17h/0h/1/1"))
== "Fmhtxeh7YdCBkyQF7AQG4QnY8y3rJg89di"
)
@pytest.mark.altcoin
def test_tgrs(client: Client):
def test_tgrs(session: Session):
assert (
btc.get_address(client, "Groestlcoin Testnet", parse_path("m/44h/1h/0h/0/0"))
btc.get_address(session, "Groestlcoin Testnet", parse_path("m/44h/1h/0h/0/0"))
== "mvbu1Gdy8SUjTenqerxUaZyYjmvedc787y"
)
assert (
btc.get_address(client, "Groestlcoin Testnet", parse_path("m/44h/1h/0h/1/0"))
btc.get_address(session, "Groestlcoin Testnet", parse_path("m/44h/1h/0h/1/0"))
== "mm6kLYbGEL1tGe4ZA8xacfgRPdW1LMq8cN"
)
assert (
btc.get_address(client, "Groestlcoin Testnet", parse_path("m/44h/1h/0h/1/1"))
btc.get_address(session, "Groestlcoin Testnet", parse_path("m/44h/1h/0h/1/1"))
== "mjXZwmEi1z1MzveZrKUAo4DBgbdq6ZhGD6"
)
@pytest.mark.altcoin
def test_elements(client: Client):
def test_elements(session: Session):
assert (
btc.get_address(client, "Elements", parse_path("m/44h/1h/0h/0/0"))
btc.get_address(session, "Elements", parse_path("m/44h/1h/0h/0/0"))
== "2dpWh6jbhAowNsQ5agtFzi7j6nKscj6UnEr"
)
@pytest.mark.models("core")
def test_address_mac(client: Client):
def test_address_mac(session: Session):
resp = btc.get_authenticated_address(
client, "Bitcoin", parse_path("m/44h/0h/0h/1/0")
session, "Bitcoin", parse_path("m/44h/0h/0h/1/0")
)
assert resp.address == "1DyHzbQUoQEsLxJn6M7fMD8Xdt1XvNiwNE"
assert (
@ -150,7 +150,7 @@ def test_address_mac(client: Client):
)
resp = btc.get_authenticated_address(
client, "Testnet", parse_path("m/44h/1h/0h/1/0")
session, "Testnet", parse_path("m/44h/1h/0h/1/0")
)
assert resp.address == "mm6kLYbGEL1tGe4ZA8xacfgRPdW1NLjCbZ"
assert (
@ -160,16 +160,16 @@ def test_address_mac(client: Client):
# Script type mismatch.
resp = btc.get_authenticated_address(
client, "Bitcoin", parse_path("m/84h/0h/0h/0/0"), show_display=False
session, "Bitcoin", parse_path("m/84h/0h/0h/0/0"), show_display=False
)
assert resp.mac is None
@pytest.mark.models("core")
@pytest.mark.altcoin
def test_altcoin_address_mac(client: Client):
def test_altcoin_address_mac(session: Session):
resp = btc.get_authenticated_address(
client, "Litecoin", parse_path("m/44h/2h/0h/1/0")
session, "Litecoin", parse_path("m/44h/2h/0h/1/0")
)
assert resp.address == "LWj6ApswZxay4cJEJES2sGe7fLMLRvvv8h"
assert (
@ -178,7 +178,7 @@ def test_altcoin_address_mac(client: Client):
)
resp = btc.get_authenticated_address(
client, "Bcash", parse_path("m/44h/145h/0h/1/0")
session, "Bcash", parse_path("m/44h/145h/0h/1/0")
)
assert resp.address == "bitcoincash:qzc5q87w069lzg7g3gzx0c8dz83mn7l02scej5aluw"
assert (
@ -187,7 +187,7 @@ def test_altcoin_address_mac(client: Client):
)
resp = btc.get_authenticated_address(
client, "Groestlcoin", parse_path("m/44h/17h/0h/1/1")
session, "Groestlcoin", parse_path("m/44h/17h/0h/1/1")
)
assert resp.address == "Fmhtxeh7YdCBkyQF7AQG4QnY8y3rJg89di"
assert (
@ -198,9 +198,9 @@ def test_altcoin_address_mac(client: Client):
@pytest.mark.multisig
@pytest.mark.models(skip="legacy", reason="Sortedmulti is not supported")
def test_multisig_pubkeys_order(client: Client):
xpub_internal = btc.get_public_node(client, parse_path("m/45h/0")).xpub
xpub_external = btc.get_public_node(client, parse_path("m/44h/1")).xpub
def test_multisig_pubkeys_order(session: Session):
xpub_internal = btc.get_public_node(session, parse_path("m/45h/0")).xpub
xpub_external = btc.get_public_node(session, parse_path("m/44h/1")).xpub
multisig_unsorted_1 = messages.MultisigRedeemScriptType(
nodes=[bip32.deserialize(xpub) for xpub in [xpub_internal, xpub_internal]],
@ -239,45 +239,45 @@ def test_multisig_pubkeys_order(client: Client):
assert (
btc.get_address(
client, "Bitcoin", parse_path("m/45h/0/0/0"), multisig=multisig_unsorted_1
session, "Bitcoin", parse_path("m/45h/0/0/0"), multisig=multisig_unsorted_1
)
== address_unsorted_1
)
assert (
btc.get_address(
client, "Bitcoin", parse_path("m/45h/0/0/0"), multisig=multisig_unsorted_2
session, "Bitcoin", parse_path("m/45h/0/0/0"), multisig=multisig_unsorted_2
)
== address_unsorted_2
)
assert (
btc.get_address(
client, "Bitcoin", parse_path("m/45h/0/0/0"), multisig=multisig_sorted_1
session, "Bitcoin", parse_path("m/45h/0/0/0"), multisig=multisig_sorted_1
)
== address_unsorted_2
)
assert (
btc.get_address(
client, "Bitcoin", parse_path("m/45h/0/0/0"), multisig=multisig_sorted_2
session, "Bitcoin", parse_path("m/45h/0/0/0"), multisig=multisig_sorted_2
)
== address_unsorted_2
)
@pytest.mark.multisig
def test_multisig(client: Client):
def test_multisig(session: Session):
xpubs = []
for n in range(1, 4):
node = btc.get_public_node(client, parse_path(f"m/44h/0h/{n}h"))
node = btc.get_public_node(session, parse_path(f"m/44h/0h/{n}h"))
xpubs.append(node.xpub)
for nr in range(1, 4):
with client:
if is_core(client):
with session.client as client:
if is_core(session):
IF = InputFlowConfirmAllWarnings(client)
client.set_input_flow(IF.get())
assert (
btc.get_address(
client,
session,
"Bitcoin",
parse_path(f"m/44h/0h/{nr}h/0/0"),
show_display=(nr == 1),
@ -287,7 +287,7 @@ def test_multisig(client: Client):
)
assert (
btc.get_address(
client,
session,
"Bitcoin",
parse_path(f"m/44h/0h/{nr}h/1/0"),
show_display=(nr == 1),
@ -299,11 +299,11 @@ def test_multisig(client: Client):
@pytest.mark.multisig
@pytest.mark.parametrize("show_display", (True, False))
def test_multisig_missing(client: Client, show_display):
def test_multisig_missing(session: Session, show_display):
# Use account numbers 1, 2 and 3 to create a valid multisig,
# but not containing the keys from account 0 used below.
nodes = [
btc.get_public_node(client, parse_path(f"m/44h/0h/{i}h")).node
btc.get_public_node(session, parse_path(f"m/44h/0h/{i}h")).node
for i in range(1, 4)
]
@ -322,12 +322,12 @@ def test_multisig_missing(client: Client, show_display):
)
for multisig in (multisig1, multisig2):
with client, pytest.raises(TrezorFailure):
if is_core(client):
with session.client as client, pytest.raises(TrezorFailure):
if is_core(session):
IF = InputFlowConfirmAllWarnings(client)
client.set_input_flow(IF.get())
btc.get_address(
client,
session,
"Bitcoin",
parse_path("m/44h/0h/0h/0/0"),
show_display=show_display,
@ -337,22 +337,22 @@ def test_multisig_missing(client: Client, show_display):
@pytest.mark.altcoin
@pytest.mark.multisig
def test_bch_multisig(client: Client):
def test_bch_multisig(session: Session):
xpubs = []
for n in range(1, 4):
node = btc.get_public_node(
client, parse_path(f"m/44h/145h/{n}h"), coin_name="Bcash"
session, parse_path(f"m/44h/145h/{n}h"), coin_name="Bcash"
)
xpubs.append(node.xpub)
for nr in range(1, 4):
with client:
if is_core(client):
with session.client as client:
if is_core(session):
IF = InputFlowConfirmAllWarnings(client)
client.set_input_flow(IF.get())
assert (
btc.get_address(
client,
session,
"Bcash",
parse_path(f"m/44h/145h/{nr}h/0/0"),
show_display=(nr == 1),
@ -362,7 +362,7 @@ def test_bch_multisig(client: Client):
)
assert (
btc.get_address(
client,
session,
"Bcash",
parse_path(f"m/44h/145h/{nr}h/1/0"),
show_display=(nr == 1),
@ -372,43 +372,43 @@ def test_bch_multisig(client: Client):
)
def test_public_ckd(client: Client):
node = btc.get_public_node(client, parse_path("m/44h/0h/0h")).node
node_sub1 = btc.get_public_node(client, parse_path("m/44h/0h/0h/1/0")).node
def test_public_ckd(session: Session):
node = btc.get_public_node(session, parse_path("m/44h/0h/0h")).node
node_sub1 = btc.get_public_node(session, parse_path("m/44h/0h/0h/1/0")).node
node_sub2 = bip32.public_ckd(node, [1, 0])
assert node_sub1.chain_code == node_sub2.chain_code
assert node_sub1.public_key == node_sub2.public_key
address1 = btc.get_address(client, "Bitcoin", parse_path("m/44h/0h/0h/1/0"))
address1 = btc.get_address(session, "Bitcoin", parse_path("m/44h/0h/0h/1/0"))
address2 = bip32.get_address(node_sub2, 0)
assert address2 == "1DyHzbQUoQEsLxJn6M7fMD8Xdt1XvNiwNE"
assert address1 == address2
def test_invalid_path(client: Client):
def test_invalid_path(session: Session):
with pytest.raises(TrezorFailure, match="Forbidden key path"):
# slip44 id mismatch
btc.get_address(
client, "Bitcoin", parse_path("m/44h/111h/0h/0/0"), show_display=True
session, "Bitcoin", parse_path("m/44h/111h/0h/0/0"), show_display=True
)
def test_unknown_path(client: Client):
def test_unknown_path(session: Session):
UNKNOWN_PATH = parse_path("m/44h/9h/0h/0/0")
with client:
client.set_expected_responses([messages.Failure])
with session:
session.set_expected_responses([messages.Failure])
with pytest.raises(TrezorFailure, match="Forbidden key path"):
# account number is too high
btc.get_address(client, "Bitcoin", UNKNOWN_PATH, show_display=True)
btc.get_address(session, "Bitcoin", UNKNOWN_PATH, show_display=True)
# disable safety checks
device.apply_settings(client, safety_checks=SafetyCheckLevel.PromptTemporarily)
device.apply_settings(session, safety_checks=SafetyCheckLevel.PromptTemporarily)
with client:
client.set_expected_responses(
with session, session.client as client:
session.set_expected_responses(
[
messages.ButtonRequest(
code=messages.ButtonRequestType.UnknownDerivationPath
@ -417,31 +417,31 @@ def test_unknown_path(client: Client):
messages.Address,
]
)
if is_core(client):
if is_core(session):
IF = InputFlowConfirmAllWarnings(client)
client.set_input_flow(IF.get())
# try again with a warning
btc.get_address(client, "Bitcoin", UNKNOWN_PATH, show_display=True)
btc.get_address(session, "Bitcoin", UNKNOWN_PATH, show_display=True)
with client:
with session:
# no warning is displayed when the call is silent
client.set_expected_responses([messages.Address])
btc.get_address(client, "Bitcoin", UNKNOWN_PATH, show_display=False)
session.set_expected_responses([messages.Address])
btc.get_address(session, "Bitcoin", UNKNOWN_PATH, show_display=False)
@pytest.mark.altcoin
def test_crw(client: Client):
def test_crw(session: Session):
assert (
btc.get_address(client, "Crown", parse_path("m/44h/72h/0h/0/0"))
btc.get_address(session, "Crown", parse_path("m/44h/72h/0h/0/0"))
== "CRWYdvZM1yXMKQxeN3hRsAbwa7drfvTwys48"
)
@pytest.mark.multisig
@pytest.mark.models(skip="legacy", reason="Not fixed")
def test_multisig_different_paths(client: Client):
def test_multisig_different_paths(session: Session):
nodes = [
btc.get_public_node(client, parse_path(f"m/45h/{i}"), coin_name="Bitcoin").node
btc.get_public_node(session, parse_path(f"m/45h/{i}"), coin_name="Bitcoin").node
for i in range(2)
]
@ -457,12 +457,12 @@ def test_multisig_different_paths(client: Client):
with pytest.raises(
Exception, match="Using different paths for different xpubs is not allowed"
):
with client:
if is_core(client):
with session.client as client, session:
if is_core(session):
IF = InputFlowConfirmAllWarnings(client)
client.set_input_flow(IF.get())
btc.get_address(
client,
session,
"Bitcoin",
parse_path("m/45h/0/0/0"),
show_display=True,
@ -470,13 +470,13 @@ def test_multisig_different_paths(client: Client):
script_type=messages.InputScriptType.SPENDMULTISIG,
)
device.apply_settings(client, safety_checks=SafetyCheckLevel.PromptTemporarily)
with client:
if is_core(client):
device.apply_settings(session, safety_checks=SafetyCheckLevel.PromptTemporarily)
with session.client as client:
if is_core(session):
IF = InputFlowConfirmAllWarnings(client)
client.set_input_flow(IF.get())
btc.get_address(
client,
session,
"Bitcoin",
parse_path("m/45h/0/0/0"),
show_display=True,

View File

@ -17,7 +17,7 @@
import pytest
from trezorlib import btc, messages
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.debuglink import SessionDebugWrapper as Session
from trezorlib.exceptions import TrezorFailure
from trezorlib.tools import parse_path
@ -25,10 +25,10 @@ from ...common import is_core
from ...input_flows import InputFlowConfirmAllWarnings
def test_show_segwit(client: Client):
def test_show_segwit(session: Session):
assert (
btc.get_address(
client,
session,
"Testnet",
parse_path("m/49h/1h/0h/1/0"),
True,
@ -39,7 +39,7 @@ def test_show_segwit(client: Client):
)
assert (
btc.get_address(
client,
session,
"Testnet",
parse_path("m/49h/1h/0h/0/0"),
False,
@ -50,7 +50,7 @@ def test_show_segwit(client: Client):
)
assert (
btc.get_address(
client,
session,
"Testnet",
parse_path("m/44h/1h/0h/0/0"),
False,
@ -61,7 +61,7 @@ def test_show_segwit(client: Client):
)
assert (
btc.get_address(
client,
session,
"Testnet",
parse_path("m/44h/1h/0h/0/0"),
False,
@ -73,14 +73,14 @@ def test_show_segwit(client: Client):
@pytest.mark.altcoin
def test_show_segwit_altcoin(client: Client):
with client:
if is_core(client):
def test_show_segwit_altcoin(session: Session):
with session.client as client:
if is_core(session):
IF = InputFlowConfirmAllWarnings(client)
client.set_input_flow(IF.get())
assert (
btc.get_address(
client,
session,
"Groestlcoin Testnet",
parse_path("m/49h/1h/0h/1/0"),
True,
@ -91,7 +91,7 @@ def test_show_segwit_altcoin(client: Client):
)
assert (
btc.get_address(
client,
session,
"Groestlcoin Testnet",
parse_path("m/49h/1h/0h/0/0"),
True,
@ -102,7 +102,7 @@ def test_show_segwit_altcoin(client: Client):
)
assert (
btc.get_address(
client,
session,
"Groestlcoin Testnet",
parse_path("m/44h/1h/0h/0/0"),
True,
@ -113,7 +113,7 @@ def test_show_segwit_altcoin(client: Client):
)
assert (
btc.get_address(
client,
session,
"Groestlcoin Testnet",
parse_path("m/44h/1h/0h/0/0"),
True,
@ -124,7 +124,7 @@ def test_show_segwit_altcoin(client: Client):
)
assert (
btc.get_address(
client,
session,
"Elements",
parse_path("m/49h/1h/0h/0/0"),
True,
@ -136,10 +136,10 @@ def test_show_segwit_altcoin(client: Client):
@pytest.mark.multisig
def test_show_multisig_3(client: Client):
def test_show_multisig_3(session: Session):
nodes = [
btc.get_public_node(
client, parse_path(f"m/49h/1h/{i}h"), coin_name="Testnet"
session, parse_path(f"m/49h/1h/{i}h"), coin_name="Testnet"
).node
for i in range(1, 4)
]
@ -155,7 +155,7 @@ def test_show_multisig_3(client: Client):
for i in [1, 2, 3]:
assert (
btc.get_address(
client,
session,
"Testnet",
parse_path(f"m/49h/1h/{i}h/0/7"),
False,
@ -168,11 +168,11 @@ def test_show_multisig_3(client: Client):
@pytest.mark.multisig
@pytest.mark.parametrize("show_display", (True, False))
def test_multisig_missing(client: Client, show_display):
def test_multisig_missing(session: Session, show_display):
# Use account numbers 1, 2 and 3 to create a valid multisig,
# but not containing the keys from account 0 used below.
nodes = [
btc.get_public_node(client, parse_path(f"m/49h/0h/{i}h")).node
btc.get_public_node(session, parse_path(f"m/49h/0h/{i}h")).node
for i in range(1, 4)
]
@ -193,7 +193,7 @@ def test_multisig_missing(client: Client, show_display):
for multisig in (multisig1, multisig2):
with pytest.raises(TrezorFailure):
btc.get_address(
client,
session,
"Bitcoin",
parse_path("m/49h/0h/0h/0/0"),
show_display=show_display,

View File

@ -17,7 +17,7 @@
import pytest
from trezorlib import btc, messages
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.debuglink import SessionDebugWrapper as Session
from trezorlib.exceptions import TrezorFailure
from trezorlib.tools import parse_path
@ -141,7 +141,7 @@ BIP86_VECTORS = ( # path, address for "abandon ... abandon about" seed
@pytest.mark.parametrize("show_display", (True, False))
@pytest.mark.parametrize("coin, path, script_type, address", VECTORS)
def test_show_segwit(
client: Client,
session: Session,
show_display: bool,
coin: str,
path: str,
@ -150,7 +150,7 @@ def test_show_segwit(
):
assert (
btc.get_address(
client,
session,
coin,
parse_path(path),
show_display,
@ -166,10 +166,10 @@ def test_show_segwit(
mnemonic="abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about"
)
@pytest.mark.parametrize("path, address", BIP86_VECTORS)
def test_bip86(client: Client, path: str, address: str):
def test_bip86(session: Session, path: str, address: str):
assert (
btc.get_address(
client,
session,
"Bitcoin",
parse_path(path),
False,
@ -181,10 +181,10 @@ def test_bip86(client: Client, path: str, address: str):
@pytest.mark.multisig
def test_show_multisig_3(client: Client):
def test_show_multisig_3(session: Session):
nodes = [
btc.get_public_node(
client, parse_path(f"m/84h/1h/{index}h"), coin_name="Testnet"
session, parse_path(f"m/84h/1h/{index}h"), coin_name="Testnet"
).node
for index in range(1, 4)
]
@ -197,7 +197,7 @@ def test_show_multisig_3(client: Client):
for i in [1, 2, 3]:
assert (
btc.get_address(
client,
session,
"Testnet",
parse_path(f"m/84h/1h/{i}h/0/1"),
False,
@ -208,7 +208,7 @@ def test_show_multisig_3(client: Client):
)
assert (
btc.get_address(
client,
session,
"Testnet",
parse_path(f"m/84h/1h/{i}h/0/0"),
False,
@ -221,11 +221,11 @@ def test_show_multisig_3(client: Client):
@pytest.mark.multisig
@pytest.mark.parametrize("show_display", (True, False))
def test_multisig_missing(client: Client, show_display: bool):
def test_multisig_missing(session: Session, show_display: bool):
# Use account numbers 1, 2 and 3 to create a valid multisig,
# but not containing the keys from account 0 used below.
nodes = [
btc.get_public_node(client, parse_path(f"m/84h/0h/{i}h")).node
btc.get_public_node(session, parse_path(f"m/84h/0h/{i}h")).node
for i in range(1, 4)
]
@ -246,7 +246,7 @@ def test_multisig_missing(client: Client, show_display: bool):
for multisig in (multisig1, multisig2):
with pytest.raises(TrezorFailure):
btc.get_address(
client,
session,
"Bitcoin",
parse_path("m/84h/0h/0h/0/0"),
show_display=show_display,

View File

@ -17,7 +17,7 @@
import pytest
from trezorlib import btc, messages, tools
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.debuglink import SessionDebugWrapper as Session
from trezorlib.exceptions import Cancelled, TrezorFailure
from ...common import is_core
@ -55,20 +55,20 @@ VECTORS = ( # path, script_type, address
@pytest.mark.models("legacy")
@pytest.mark.parametrize("path, script_type, address", VECTORS)
def test_show_t1(
client: Client, path: str, script_type: messages.InputScriptType, address: str
session: Session, path: str, script_type: messages.InputScriptType, address: str
):
def input_flow_t1():
yield
client.debug.press_no()
session.debug.press_no()
yield
client.debug.press_yes()
session.debug.press_yes()
with client:
with session:
# This is the only place where even T1 is using input flow
client.set_input_flow(input_flow_t1)
session.set_input_flow(input_flow_t1)
assert (
btc.get_address(
client,
session,
"Bitcoin",
tools.parse_path(path),
script_type=script_type,
@ -82,18 +82,18 @@ def test_show_t1(
@pytest.mark.parametrize("chunkify", (True, False))
@pytest.mark.parametrize("path, script_type, address", VECTORS)
def test_show_tt(
client: Client,
session: Session,
chunkify: bool,
path: str,
script_type: messages.InputScriptType,
address: str,
):
with client:
with session.client as client:
IF = InputFlowShowAddressQRCode(client)
client.set_input_flow(IF.get())
assert (
btc.get_address(
client,
session,
"Bitcoin",
tools.parse_path(path),
script_type=script_type,
@ -107,13 +107,13 @@ def test_show_tt(
@pytest.mark.models("core")
@pytest.mark.parametrize("path, script_type, address", VECTORS)
def test_show_cancel(
client: Client, path: str, script_type: messages.InputScriptType, address: str
session: Session, path: str, script_type: messages.InputScriptType, address: str
):
with client, pytest.raises(Cancelled):
with session.client as client, pytest.raises(Cancelled):
IF = InputFlowShowAddressQRCodeCancel(client)
client.set_input_flow(IF.get())
btc.get_address(
client,
session,
"Bitcoin",
tools.parse_path(path),
script_type=script_type,
@ -121,10 +121,10 @@ def test_show_cancel(
)
def test_show_unrecognized_path(client: Client):
def test_show_unrecognized_path(session: Session):
with pytest.raises(TrezorFailure):
btc.get_address(
client,
session,
"Bitcoin",
tools.parse_path("m/24684621h/516582h/5156h/21/856"),
script_type=messages.InputScriptType.SPENDWITNESS,
@ -133,10 +133,10 @@ def test_show_unrecognized_path(client: Client):
@pytest.mark.multisig
def test_show_multisig_3(client: Client):
def test_show_multisig_3(session: Session):
nodes = [
btc.get_public_node(
client, tools.parse_path(f"m/45h/{i}"), coin_name="Bitcoin"
session, tools.parse_path(f"m/45h/{i}"), coin_name="Bitcoin"
).node
for i in [1, 2, 3]
]
@ -157,13 +157,13 @@ def test_show_multisig_3(client: Client):
for multisig in (multisig1, multisig2):
for i in [1, 2, 3]:
with client:
if is_core(client):
with session.client as client:
if is_core(session):
IF = InputFlowConfirmAllWarnings(client)
client.set_input_flow(IF.get())
assert (
btc.get_address(
client,
session,
"Bitcoin",
tools.parse_path(f"m/45h/{i}/0/0"),
show_display=True,
@ -250,7 +250,7 @@ VECTORS_MULTISIG = ( # script_type, bip48_type, address, xpubs, ignore_xpub_mag
"script_type, bip48_type, address, xpubs, ignore_xpub_magic", VECTORS_MULTISIG
)
def test_show_multisig_xpubs(
client: Client,
session: Session,
script_type: messages.InputScriptType,
bip48_type: int,
address: str,
@ -259,7 +259,7 @@ def test_show_multisig_xpubs(
):
nodes = [
btc.get_public_node(
client,
session,
tools.parse_path(f"m/48h/0h/{i}h/{bip48_type}h"),
coin_name="Bitcoin",
)
@ -273,13 +273,13 @@ def test_show_multisig_xpubs(
)
for i in range(3):
with client:
with session, session.client as client:
IF = InputFlowShowMultisigXPUBs(client, address, xpubs, i)
client.set_input_flow(IF.get())
client.debug.synchronize_at("Homescreen")
client.watch_layout()
btc.get_address(
client,
session,
"Bitcoin",
tools.parse_path(f"m/48h/0h/{i}h/{bip48_type}h/0/0"),
show_display=True,
@ -290,10 +290,10 @@ def test_show_multisig_xpubs(
@pytest.mark.multisig
def test_show_multisig_15(client: Client):
def test_show_multisig_15(session: Session):
nodes = [
btc.get_public_node(
client, tools.parse_path(f"m/45h/{i}"), coin_name="Bitcoin"
session, tools.parse_path(f"m/45h/{i}"), coin_name="Bitcoin"
).node
for i in range(15)
]
@ -314,13 +314,13 @@ def test_show_multisig_15(client: Client):
for multisig in [multisig1, multisig2]:
for i in range(15):
with client:
if is_core(client):
with session.client as client:
if is_core(session):
IF = InputFlowConfirmAllWarnings(client)
client.set_input_flow(IF.get())
assert (
btc.get_address(
client,
session,
"Bitcoin",
tools.parse_path(f"m/45h/{i}/0/0"),
show_display=True,

View File

@ -17,14 +17,14 @@
import pytest
from trezorlib import btc, messages
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.debuglink import SessionDebugWrapper as Session
from trezorlib.exceptions import TrezorFailure
from trezorlib.tools import parse_path
def test_p2wpkh_ownership_id(client: Client):
def test_p2wpkh_ownership_id(session: Session):
ownership_id = btc.get_ownership_id(
client,
session,
"Bitcoin",
parse_path("m/84h/0h/0h/1/0"),
script_type=messages.InputScriptType.SPENDWITNESS,
@ -35,9 +35,9 @@ def test_p2wpkh_ownership_id(client: Client):
)
def test_p2tr_ownership_id(client: Client):
def test_p2tr_ownership_id(session: Session):
ownership_id = btc.get_ownership_id(
client,
session,
"Bitcoin",
parse_path("m/86h/0h/0h/1/0"),
script_type=messages.InputScriptType.SPENDTAPROOT,
@ -48,12 +48,12 @@ def test_p2tr_ownership_id(client: Client):
)
def test_attack_ownership_id(client: Client):
def test_attack_ownership_id(session: Session):
# Multisig with global suffix specification.
# Use account numbers 1, 2 and 3 to create a valid multisig,
# but not containing the keys from account 0 used below.
nodes = [
btc.get_public_node(client, parse_path(f"m/84h/0h/{i}h")).node
btc.get_public_node(session, parse_path(f"m/84h/0h/{i}h")).node
for i in range(1, 4)
]
multisig1 = messages.MultisigRedeemScriptType(
@ -62,7 +62,7 @@ def test_attack_ownership_id(client: Client):
# Multisig with per-node suffix specification.
node = btc.get_public_node(
client, parse_path("m/84h/0h/0h/0"), coin_name="Bitcoin"
session, parse_path("m/84h/0h/0h/0"), coin_name="Bitcoin"
).node
multisig2 = messages.MultisigRedeemScriptType(
pubkeys=[
@ -77,7 +77,7 @@ def test_attack_ownership_id(client: Client):
for multisig in (multisig1, multisig2):
with pytest.raises(TrezorFailure):
btc.get_ownership_id(
client,
session,
"Bitcoin",
parse_path("m/84h/0h/0h/0/0"),
multisig=multisig,
@ -85,9 +85,9 @@ def test_attack_ownership_id(client: Client):
)
def test_p2wpkh_ownership_proof(client: Client):
def test_p2wpkh_ownership_proof(session: Session):
ownership_proof, _ = btc.get_ownership_proof(
client,
session,
"Bitcoin",
parse_path("m/84h/0h/0h/1/0"),
script_type=messages.InputScriptType.SPENDWITNESS,
@ -98,9 +98,9 @@ def test_p2wpkh_ownership_proof(client: Client):
)
def test_p2tr_ownership_proof(client: Client):
def test_p2tr_ownership_proof(session: Session):
ownership_proof, _ = btc.get_ownership_proof(
client,
session,
"Bitcoin",
parse_path("m/86h/0h/0h/1/0"),
script_type=messages.InputScriptType.SPENDTAPROOT,
@ -111,10 +111,10 @@ def test_p2tr_ownership_proof(client: Client):
)
def test_fake_ownership_id(client: Client):
def test_fake_ownership_id(session: Session):
with pytest.raises(TrezorFailure, match="Invalid ownership identifier"):
btc.get_ownership_proof(
client,
session,
"Bitcoin",
parse_path("m/84h/0h/0h/1/0"),
script_type=messages.InputScriptType.SPENDWITNESS,
@ -124,9 +124,9 @@ def test_fake_ownership_id(client: Client):
)
def test_confirm_ownership_proof(client: Client):
def test_confirm_ownership_proof(session: Session):
ownership_proof, _ = btc.get_ownership_proof(
client,
session,
"Bitcoin",
parse_path("m/84h/0h/0h/1/0"),
script_type=messages.InputScriptType.SPENDWITNESS,
@ -139,9 +139,9 @@ def test_confirm_ownership_proof(client: Client):
)
def test_confirm_ownership_proof_with_data(client: Client):
def test_confirm_ownership_proof_with_data(session: Session):
ownership_proof, _ = btc.get_ownership_proof(
client,
session,
"Bitcoin",
parse_path("m/84h/0h/0h/1/0"),
script_type=messages.InputScriptType.SPENDWITNESS,

View File

@ -17,7 +17,7 @@
import pytest
from trezorlib import btc, messages
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.debuglink import SessionDebugWrapper as Session
from trezorlib.exceptions import TrezorFailure
from trezorlib.tools import parse_path
@ -110,35 +110,35 @@ VECTORS_INVALID = ( # coin_name, path
@pytest.mark.parametrize("coin_name, xpub_magic, path, xpub", VECTORS_BITCOIN)
def test_get_public_node(client: Client, coin_name, xpub_magic, path, xpub):
res = btc.get_public_node(client, path, coin_name=coin_name)
def test_get_public_node(session: Session, coin_name, xpub_magic, path, xpub):
res = btc.get_public_node(session, path, coin_name=coin_name)
assert res.xpub == xpub
assert bip32.serialize(res.node, xpub_magic) == xpub
@pytest.mark.models("core")
@pytest.mark.parametrize("coin_name, xpub_magic, path, xpub", VECTORS_BITCOIN)
def test_get_public_node_show(client: Client, coin_name, xpub_magic, path, xpub):
with client:
def test_get_public_node_show(session: Session, coin_name, xpub_magic, path, xpub):
with session.client as client:
IF = InputFlowShowXpubQRCode(client)
client.set_input_flow(IF.get())
res = btc.get_public_node(client, path, coin_name=coin_name, show_display=True)
res = btc.get_public_node(session, path, coin_name=coin_name, show_display=True)
assert res.xpub == xpub
assert bip32.serialize(res.node, xpub_magic) == xpub
@pytest.mark.xfail(reason="Currently path validation on get_public_node is disabled.")
@pytest.mark.parametrize("coin_name, path", VECTORS_INVALID)
def test_invalid_path(client: Client, coin_name, path):
def test_invalid_path(session: Session, coin_name, path):
with pytest.raises(TrezorFailure, match="Forbidden key path"):
btc.get_public_node(client, path, coin_name=coin_name)
btc.get_public_node(session, path, coin_name=coin_name)
def test_slip25_path(client: Client):
def test_slip25_path(session: Session):
# Ensure that CoinJoin XPUBs are inaccessible without user authorization.
with pytest.raises(TrezorFailure, match="Forbidden key path"):
btc.get_public_node(
client,
session,
parse_path("m/10025h/0h/0h/1h"),
script_type=messages.InputScriptType.SPENDTAPROOT,
)
@ -169,14 +169,14 @@ VECTORS_SCRIPT_TYPES = ( # script_type, xpub, xpub_ignored_magic
@pytest.mark.parametrize("script_type, xpub, xpub_ignored_magic", VECTORS_SCRIPT_TYPES)
def test_script_type(client: Client, script_type, xpub, xpub_ignored_magic):
def test_script_type(session: Session, script_type, xpub, xpub_ignored_magic):
path = parse_path("m/44h/0h/0")
res = btc.get_public_node(
client, path, coin_name="Bitcoin", script_type=script_type
session, path, coin_name="Bitcoin", script_type=script_type
)
assert res.xpub == xpub
res = btc.get_public_node(
client,
session,
path,
coin_name="Bitcoin",
script_type=script_type,

View File

@ -17,7 +17,7 @@
import pytest
from trezorlib import btc
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.debuglink import SessionDebugWrapper as Session
from trezorlib.exceptions import TrezorFailure
from trezorlib.tools import parse_path
@ -54,21 +54,21 @@ VECTORS = ( # curve, path, pubkey
@pytest.mark.parametrize("curve, path, pubkey", VECTORS)
def test_publickey_curve(client: Client, curve, path, pubkey):
resp = btc.get_public_node(client, path, ecdsa_curve_name=curve)
def test_publickey_curve(session: Session, curve, path, pubkey):
resp = btc.get_public_node(session, path, ecdsa_curve_name=curve)
assert resp.node.public_key.hex() == pubkey
def test_ed25519_public(client: Client):
def test_ed25519_public(session: Session):
with pytest.raises(TrezorFailure):
btc.get_public_node(client, PATH_PUBLIC, ecdsa_curve_name="ed25519")
btc.get_public_node(session, PATH_PUBLIC, ecdsa_curve_name="ed25519")
@pytest.mark.xfail(reason="Currently path validation on get_public_node is disabled.")
def test_coin_and_curve(client: Client):
def test_coin_and_curve(session: Session):
with pytest.raises(
TrezorFailure, match="Cannot use coin_name or script_type with ecdsa_curve_name"
):
btc.get_public_node(
client, PATH_PRIVATE, coin_name="Bitcoin", ecdsa_curve_name="ed25519"
session, PATH_PRIVATE, coin_name="Bitcoin", ecdsa_curve_name="ed25519"
)

View File

@ -17,7 +17,7 @@
import pytest
from trezorlib import btc, messages
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.debuglink import SessionDebugWrapper as Session
from trezorlib.tools import parse_path
from ...tx_cache import TxCache
@ -42,7 +42,7 @@ TXHASH_45aeb9 = bytes.fromhex(
pytestmark = pytest.mark.altcoin
def test_legacy(client: Client):
def test_legacy(session: Session):
inp1 = messages.TxInputType(
# FXHDsC5ZqWQHkDmShzgRVZ1MatpWhwxTAA
address_n=parse_path("m/44h/17h/0h/0/2"),
@ -56,7 +56,7 @@ def test_legacy(client: Client):
script_type=messages.OutputScriptType.PAYTOADDRESS,
)
_, serialized_tx = btc.sign_tx(
client, "Groestlcoin", [inp1], [out1], prev_txes=TX_API
session, "Groestlcoin", [inp1], [out1], prev_txes=TX_API
)
assert (
serialized_tx.hex()
@ -64,7 +64,7 @@ def test_legacy(client: Client):
)
def test_legacy_change(client: Client):
def test_legacy_change(session: Session):
inp1 = messages.TxInputType(
# FXHDsC5ZqWQHkDmShzgRVZ1MatpWhwxTAA
address_n=parse_path("m/44h/17h/0h/0/2"),
@ -78,7 +78,7 @@ def test_legacy_change(client: Client):
script_type=messages.OutputScriptType.PAYTOADDRESS,
)
_, serialized_tx = btc.sign_tx(
client, "Groestlcoin", [inp1], [out1], prev_txes=TX_API
session, "Groestlcoin", [inp1], [out1], prev_txes=TX_API
)
assert (
serialized_tx.hex()
@ -86,7 +86,7 @@ def test_legacy_change(client: Client):
)
def test_send_segwit_p2sh(client: Client):
def test_send_segwit_p2sh(session: Session):
inp1 = messages.TxInputType(
# 2N1LGaGg836mqSQqiuUBLfcyGBhyZYBtBZ7
address_n=parse_path("m/49h/1h/0h/1/0"),
@ -107,7 +107,7 @@ def test_send_segwit_p2sh(client: Client):
script_type=messages.OutputScriptType.PAYTOADDRESS,
)
_, serialized_tx = btc.sign_tx(
client,
session,
"Groestlcoin Testnet",
[inp1],
[out1, out2],
@ -120,7 +120,7 @@ def test_send_segwit_p2sh(client: Client):
)
def test_send_segwit_p2sh_change(client: Client):
def test_send_segwit_p2sh_change(session: Session):
inp1 = messages.TxInputType(
# 2N1LGaGg836mqSQqiuUBLfcyGBhyZYBtBZ7
address_n=parse_path("m/49h/1h/0h/1/0"),
@ -141,7 +141,7 @@ def test_send_segwit_p2sh_change(client: Client):
amount=123_456_789 - 11_000 - 12_300_000,
)
_, serialized_tx = btc.sign_tx(
client,
session,
"Groestlcoin Testnet",
[inp1],
[out1, out2],
@ -154,7 +154,7 @@ def test_send_segwit_p2sh_change(client: Client):
)
def test_send_segwit_native(client: Client):
def test_send_segwit_native(session: Session):
inp1 = messages.TxInputType(
address_n=parse_path("m/84h/1h/0h/0/0"),
amount=12_300_000,
@ -174,7 +174,7 @@ def test_send_segwit_native(client: Client):
amount=12_300_000 - 11_000 - 5_000_000,
)
_, serialized_tx = btc.sign_tx(
client,
session,
"Groestlcoin Testnet",
[inp1],
[out1, out2],
@ -187,7 +187,7 @@ def test_send_segwit_native(client: Client):
)
def test_send_segwit_native_change(client: Client):
def test_send_segwit_native_change(session: Session):
inp1 = messages.TxInputType(
address_n=parse_path("m/84h/1h/0h/0/0"),
amount=12_300_000,
@ -207,7 +207,7 @@ def test_send_segwit_native_change(client: Client):
amount=12_300_000 - 11_000 - 5_000_000,
)
_, serialized_tx = btc.sign_tx(
client,
session,
"Groestlcoin Testnet",
[inp1],
[out1, out2],
@ -220,7 +220,7 @@ def test_send_segwit_native_change(client: Client):
)
def test_send_p2tr(client: Client):
def test_send_p2tr(session: Session):
inp1 = messages.TxInputType(
# tgrs1paxhjl357yzctuf3fe58fcdx6nul026hhh6kyldpfsf3tckj9a3wsvuqrgn
address_n=parse_path("m/86h/1h/1h/0/0"),
@ -236,7 +236,7 @@ def test_send_p2tr(client: Client):
script_type=messages.OutputScriptType.PAYTOADDRESS,
)
_, serialized_tx = btc.sign_tx(
client, "Groestlcoin Testnet", [inp1], [out1], prev_txes=TX_API_TESTNET
session, "Groestlcoin Testnet", [inp1], [out1], prev_txes=TX_API_TESTNET
)
# Transaction hex changed with fix #2085, all other details are the same as this tx:
# https://blockbook-test.groestlcoin.org/tx/c66a79075044aaab3dba17daffb23f48addee87d7c87c7bc88e2997ce38a74ee

View File

@ -17,7 +17,7 @@
import pytest
from trezorlib import btc, messages
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.debuglink import SessionDebugWrapper as Session
from trezorlib.tools import parse_path
from ...common import is_core
@ -43,7 +43,7 @@ TXHASH_7b28bd = bytes.fromhex(
pytestmark = [pytest.mark.altcoin, pytest.mark.komodo]
def test_one_one_fee_sapling(client: Client):
def test_one_one_fee_sapling(session: Session):
# prevout: 2807c5b126ec8e2b078cab0f12e4c8b4ce1d7724905f8ebef8dca26b0c8e0f1d:0
# input 1: 10.9998 KMD
@ -61,13 +61,13 @@ def test_one_one_fee_sapling(client: Client):
script_type=messages.OutputScriptType.PAYTOADDRESS,
)
with client:
client.set_expected_responses(
with session:
session.set_expected_responses(
[
request_input(0),
request_output(0),
messages.ButtonRequest(code=B.ConfirmOutput),
(is_core(client), messages.ButtonRequest(code=B.ConfirmOutput)),
(is_core(session), messages.ButtonRequest(code=B.ConfirmOutput)),
messages.ButtonRequest(code=B.SignTx),
messages.ButtonRequest(code=B.SignTx),
request_input(0),
@ -82,7 +82,7 @@ def test_one_one_fee_sapling(client: Client):
)
_, serialized_tx = btc.sign_tx(
client,
session,
"Komodo",
[inp1],
[out1],
@ -100,7 +100,7 @@ def test_one_one_fee_sapling(client: Client):
)
def test_one_one_rewards_claim(client: Client):
def test_one_one_rewards_claim(session: Session):
# prevout: 7b28bd91119e9776f0d4ebd80e570165818a829bbf4477cd1afe5149dbcd34b1:0
# input 1: 10.9997 KMD
@ -125,16 +125,16 @@ def test_one_one_rewards_claim(client: Client):
script_type=messages.OutputScriptType.PAYTOADDRESS,
)
with client:
client.set_expected_responses(
with session:
session.set_expected_responses(
[
request_input(0),
request_output(0),
messages.ButtonRequest(code=B.ConfirmOutput),
(is_core(client), messages.ButtonRequest(code=B.ConfirmOutput)),
(is_core(session), messages.ButtonRequest(code=B.ConfirmOutput)),
request_output(1),
messages.ButtonRequest(code=B.ConfirmOutput),
(is_core(client), messages.ButtonRequest(code=B.ConfirmOutput)),
(is_core(session), messages.ButtonRequest(code=B.ConfirmOutput)),
messages.ButtonRequest(code=B.SignTx),
messages.ButtonRequest(code=B.SignTx),
request_input(0),
@ -150,7 +150,7 @@ def test_one_one_rewards_claim(client: Client):
)
_, serialized_tx = btc.sign_tx(
client,
session,
"Komodo",
[inp1],
[out1, out2],

View File

@ -17,7 +17,7 @@
import pytest
from trezorlib import btc, messages, models
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.debuglink import SessionDebugWrapper as Session
from trezorlib.exceptions import TrezorFailure
from trezorlib.tools import parse_path
@ -55,12 +55,12 @@ pytestmark = pytest.mark.multisig
@pytest.mark.multisig
@pytest.mark.parametrize("chunkify", (True, False))
def test_2_of_3(client: Client, chunkify: bool):
def test_2_of_3(session: Session, chunkify: bool):
# input tx: 6b07c1321b52d9c85743f9695e13eb431b41708cdf4e1585258d51208e5b93fc
nodes = [
btc.get_public_node(
client, parse_path(f"m/48h/1h/{index}h/0h"), coin_name="Testnet"
session, parse_path(f"m/48h/1h/{index}h/0h"), coin_name="Testnet"
).node
for index in range(1, 4)
]
@ -89,7 +89,7 @@ def test_2_of_3(client: Client, chunkify: bool):
request_input(0),
request_output(0),
messages.ButtonRequest(code=B.ConfirmOutput),
(is_core(client), messages.ButtonRequest(code=B.ConfirmOutput)),
(is_core(session), messages.ButtonRequest(code=B.ConfirmOutput)),
messages.ButtonRequest(code=B.SignTx),
request_input(0),
request_meta(TXHASH_6b07c1),
@ -101,12 +101,12 @@ def test_2_of_3(client: Client, chunkify: bool):
request_finished(),
]
with client:
client.set_expected_responses(expected_responses)
with session:
session.set_expected_responses(expected_responses)
# Now we have first signature
signatures1, _ = btc.sign_tx(
client,
session,
"Testnet",
[inp1],
[out1],
@ -143,10 +143,10 @@ def test_2_of_3(client: Client, chunkify: bool):
multisig=multisig,
)
with client:
client.set_expected_responses(expected_responses)
with session:
session.set_expected_responses(expected_responses)
signatures2, serialized_tx = btc.sign_tx(
client, "Testnet", [inp3], [out1], prev_txes=TX_API_TESTNET
session, "Testnet", [inp3], [out1], prev_txes=TX_API_TESTNET
)
assert (
@ -163,12 +163,12 @@ def test_2_of_3(client: Client, chunkify: bool):
@pytest.mark.multisig
@pytest.mark.models(skip="legacy", reason="Sortedmulti is not supported")
def test_pubkeys_order(client: Client):
def test_pubkeys_order(session: Session):
node_internal = btc.get_public_node(
client, parse_path("m/45h/0"), coin_name="Bitcoin"
session, parse_path("m/45h/0"), coin_name="Bitcoin"
).node
node_external = btc.get_public_node(
client, parse_path("m/45h/1"), coin_name="Bitcoin"
session, parse_path("m/45h/1"), coin_name="Bitcoin"
).node
# A dummy signature is used to ensure that the signatures are serialized in the correct order
@ -207,10 +207,10 @@ def test_pubkeys_order(client: Client):
)
address_unsorted_1 = btc.get_address(
client, "Bitcoin", parse_path("m/45h/0/0/0"), multisig=multisig_unsorted_1
session, "Bitcoin", parse_path("m/45h/0/0/0"), multisig=multisig_unsorted_1
)
address_unsorted_2 = btc.get_address(
client, "Bitcoin", parse_path("m/45h/0/0/0"), multisig=multisig_unsorted_2
session, "Bitcoin", parse_path("m/45h/0/0/0"), multisig=multisig_unsorted_2
)
pubkey_internal = btc.get_public_node(
@ -296,7 +296,7 @@ def test_pubkeys_order(client: Client):
tx_unsorted_2 = "0100000001637ffac0d4fbd8a6c02b114e36b079615ec3e4bdf09b769c7bf8b5fd6f8e781701000000da004800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000147304402204914036468434698e2d87985007a66691f170195e4a16507bbb86b4c00da5fde02200a788312d447b3796ee5288ce9e9c0247896debfa473339302bc928da6dd78cb014751210369b79f2094a6eb89e7aff0e012a5699f7272968a341e48e99e64a54312f2932b210262e9ac5bea4c84c7dea650424ed768cf123af9e447eef3c63d37c41d1f825e4952aeffffffff01301b0f000000000017a914320ad0ff0f1b605ab1fa8e29b70d22827cf45a9f8700000000"
_, tx = btc.sign_tx(
client,
session,
"Bitcoin",
[input_unsorted_1],
[output_unsorted_1],
@ -305,7 +305,7 @@ def test_pubkeys_order(client: Client):
assert tx.hex() == tx_unsorted_1
_, tx = btc.sign_tx(
client,
session,
"Bitcoin",
[input_unsorted_2],
[output_unsorted_2],
@ -314,7 +314,7 @@ def test_pubkeys_order(client: Client):
assert tx.hex() == tx_unsorted_2
_, tx = btc.sign_tx(
client,
session,
"Bitcoin",
[input_sorted_1],
[output_sorted_1],
@ -323,7 +323,7 @@ def test_pubkeys_order(client: Client):
assert tx.hex() == tx_unsorted_1
_, tx = btc.sign_tx(
client,
session,
"Bitcoin",
[input_sorted_2],
[output_sorted_2],
@ -333,11 +333,11 @@ def test_pubkeys_order(client: Client):
@pytest.mark.multisig
def test_15_of_15(client: Client):
def test_15_of_15(session: Session):
# input tx: 0d5b5648d47b5650edea1af3d47bbe5624213abb577cf1b1c96f98321f75cdbc
node = btc.get_public_node(
client, parse_path("m/48h/1h/1h/0h"), coin_name="Testnet"
session, parse_path("m/48h/1h/1h/0h"), coin_name="Testnet"
).node
pubs = [messages.HDNodePathType(node=node, address_n=[0, x]) for x in range(15)]
@ -363,9 +363,9 @@ def test_15_of_15(client: Client):
multisig=multisig,
)
with client:
with session:
sig, serialized_tx = btc.sign_tx(
client, "Testnet", [inp1], [out1], prev_txes=TX_API_TESTNET
session, "Testnet", [inp1], [out1], prev_txes=TX_API_TESTNET
)
signatures[x] = sig[0]
@ -377,9 +377,9 @@ def test_15_of_15(client: Client):
@pytest.mark.multisig
@pytest.mark.setup_client(mnemonic=MNEMONIC12)
def test_missing_pubkey(client: Client):
def test_missing_pubkey(session: Session):
node = btc.get_public_node(
client, parse_path("m/48h/0h/1h/0h/0"), coin_name="Bitcoin"
session, parse_path("m/48h/0h/1h/0h/0"), coin_name="Bitcoin"
).node
multisig = messages.MultisigRedeemScriptType(
@ -409,16 +409,16 @@ def test_missing_pubkey(client: Client):
)
with pytest.raises(TrezorFailure) as exc:
btc.sign_tx(client, "Bitcoin", [inp1], [out1], prev_txes=TX_API)
btc.sign_tx(session, "Bitcoin", [inp1], [out1], prev_txes=TX_API)
if client.model is models.T1B1:
if session.model is models.T1B1:
assert exc.value.message.endswith("Failed to derive scriptPubKey")
else:
assert exc.value.message.endswith("Pubkey not found in multisig script")
@pytest.mark.multisig
def test_attack_change_input(client: Client):
def test_attack_change_input(session: Session):
"""
In Phases 1 and 2 the attacker replaces a non-multisig input
`input_real` with a multisig input `input_fake`, which allows the
@ -441,7 +441,7 @@ def test_attack_change_input(client: Client):
multisig_fake = messages.MultisigRedeemScriptType(
m=1,
nodes=[
btc.get_public_node(client, address_n, coin_name="Testnet").node,
btc.get_public_node(session, address_n, coin_name="Testnet").node,
messages.HDNodeType(
depth=0,
fingerprint=0,
@ -476,12 +476,12 @@ def test_attack_change_input(client: Client):
)
# Transaction can be signed without the attack processor
with client:
if is_core(client):
with session.client as client:
if is_core(session):
IF = InputFlowConfirmAllWarnings(client)
client.set_input_flow(IF.get())
btc.sign_tx(
client,
session,
"Testnet",
[input_real],
[output_payee, output_change],
@ -498,11 +498,11 @@ def test_attack_change_input(client: Client):
attack_count -= 1
return msg
with client:
client.set_filter(messages.TxAck, attack_processor)
with session:
session.set_filter(messages.TxAck, attack_processor)
with pytest.raises(TrezorFailure):
btc.sign_tx(
client,
session,
"Testnet",
[input_real],
[output_payee, output_change],

View File

@ -19,7 +19,7 @@ from typing import Optional
import pytest
from trezorlib import btc, messages
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.debuglink import SessionDebugWrapper as Session
from trezorlib.tools import H_, parse_path
from ... import bip32
@ -123,7 +123,7 @@ TX_API = {prev_hash_1: prev_tx_1, prev_hash_2: prev_tx_2, prev_hash_3: prev_tx_3
def _responses(
client: Client,
session: Session,
INP1: messages.TxInputType,
INP2: messages.TxInputType,
change_indices: Optional[list[int]] = None,
@ -144,7 +144,7 @@ def _responses(
resp.append(messages.ButtonRequest(code=B.UnknownDerivationPath))
if 1 not in change_indices:
resp.append(messages.ButtonRequest(code=B.ConfirmOutput))
if is_core(client):
if is_core(session):
resp.append(messages.ButtonRequest(code=B.ConfirmOutput))
resp.append(request_output(1))
@ -153,7 +153,7 @@ def _responses(
resp.append(messages.ButtonRequest(code=B.UnknownDerivationPath))
if 2 not in change_indices:
resp.append(messages.ButtonRequest(code=B.ConfirmOutput))
if is_core(client):
if is_core(session):
resp.append(messages.ButtonRequest(code=B.ConfirmOutput))
resp += [
@ -182,7 +182,7 @@ def _responses(
# both outputs are external
def test_external_external(client: Client):
def test_external_external(session: Session):
out1 = messages.TxOutputType(
address="1F8yBZB2NZhPZvJekhjTwjhQRRvQeTjjXr",
amount=40_000_000,
@ -195,10 +195,10 @@ def test_external_external(client: Client):
script_type=messages.OutputScriptType.PAYTOADDRESS,
)
with client:
client.set_expected_responses(_responses(client, INP1, INP2))
with session:
session.set_expected_responses(_responses(session, INP1, INP2))
btc.sign_tx(
client,
session,
"Bitcoin",
[INP1, INP2],
[out1, out2],
@ -207,7 +207,7 @@ def test_external_external(client: Client):
# first external, second internal
def test_external_internal(client: Client):
def test_external_internal(session: Session):
out1 = messages.TxOutputType(
address="1F8yBZB2NZhPZvJekhjTwjhQRRvQeTjjXr",
amount=40_000_000,
@ -220,21 +220,21 @@ def test_external_internal(client: Client):
script_type=messages.OutputScriptType.PAYTOADDRESS,
)
with client:
client.set_expected_responses(
with session, session.client as client:
session.set_expected_responses(
_responses(
client,
session,
INP1,
INP2,
change_indices=[] if is_core(client) else [2],
foreign_indices=[2],
)
)
if is_core(client):
if is_core(session):
IF = InputFlowConfirmAllWarnings(client)
client.set_input_flow(IF.get())
btc.sign_tx(
client,
session,
"Bitcoin",
[INP1, INP2],
[out1, out2],
@ -243,7 +243,7 @@ def test_external_internal(client: Client):
# first internal, second external
def test_internal_external(client: Client):
def test_internal_external(session: Session):
out1 = messages.TxOutputType(
address_n=parse_path("m/45h/0/1/0"),
amount=40_000_000,
@ -256,21 +256,21 @@ def test_internal_external(client: Client):
script_type=messages.OutputScriptType.PAYTOADDRESS,
)
with client:
client.set_expected_responses(
with session, session.client as client:
session.set_expected_responses(
_responses(
client,
session,
INP1,
INP2,
change_indices=[] if is_core(client) else [1],
foreign_indices=[1],
)
)
if is_core(client):
if is_core(session):
IF = InputFlowConfirmAllWarnings(client)
client.set_input_flow(IF.get())
btc.sign_tx(
client,
session,
"Bitcoin",
[INP1, INP2],
[out1, out2],
@ -279,7 +279,7 @@ def test_internal_external(client: Client):
# both outputs are external
def test_multisig_external_external(client: Client):
def test_multisig_external_external(session: Session):
out1 = messages.TxOutputType(
address="3B23k4kFBRtu49zvpG3Z9xuFzfpHvxBcwt",
amount=40_000_000,
@ -292,10 +292,10 @@ def test_multisig_external_external(client: Client):
script_type=messages.OutputScriptType.PAYTOADDRESS,
)
with client:
client.set_expected_responses(_responses(client, INP1, INP2))
with session:
session.set_expected_responses(_responses(session, INP1, INP2))
btc.sign_tx(
client,
session,
"Bitcoin",
[INP1, INP2],
[out1, out2],
@ -304,7 +304,7 @@ def test_multisig_external_external(client: Client):
# inputs match, change matches (first is change)
def test_multisig_change_match_first(client: Client):
def test_multisig_change_match_first(session: Session):
multisig_out1 = messages.MultisigRedeemScriptType(
nodes=[NODE_EXT1, NODE_EXT2, NODE_INT],
address_n=[1, 0],
@ -325,12 +325,12 @@ def test_multisig_change_match_first(client: Client):
script_type=messages.OutputScriptType.PAYTOADDRESS,
)
with client:
client.set_expected_responses(
_responses(client, INP1, INP2, change_indices=[1])
with session:
session.set_expected_responses(
_responses(session, INP1, INP2, change_indices=[1])
)
btc.sign_tx(
client,
session,
"Bitcoin",
[INP1, INP2],
[out1, out2],
@ -339,7 +339,7 @@ def test_multisig_change_match_first(client: Client):
# inputs match, change matches (second is change)
def test_multisig_change_match_second(client: Client):
def test_multisig_change_match_second(session: Session):
multisig_out2 = messages.MultisigRedeemScriptType(
nodes=[NODE_EXT1, NODE_EXT2, NODE_INT],
address_n=[1, 1],
@ -360,12 +360,12 @@ def test_multisig_change_match_second(client: Client):
script_type=messages.OutputScriptType.PAYTOMULTISIG,
)
with client:
client.set_expected_responses(
_responses(client, INP1, INP2, change_indices=[2])
with session:
session.set_expected_responses(
_responses(session, INP1, INP2, change_indices=[2])
)
btc.sign_tx(
client,
session,
"Bitcoin",
[INP1, INP2],
[out1, out2],
@ -374,7 +374,7 @@ def test_multisig_change_match_second(client: Client):
# inputs match, change mismatches (second tries to be change but isn't)
def test_multisig_mismatch_multisig_change(client: Client):
def test_multisig_mismatch_multisig_change(session: Session):
multisig_out2 = messages.MultisigRedeemScriptType(
nodes=[NODE_EXT1, NODE_INT, NODE_EXT3],
address_n=[1, 0],
@ -395,10 +395,10 @@ def test_multisig_mismatch_multisig_change(client: Client):
script_type=messages.OutputScriptType.PAYTOMULTISIG,
)
with client:
client.set_expected_responses(_responses(client, INP1, INP2))
with session:
session.set_expected_responses(_responses(session, INP1, INP2))
btc.sign_tx(
client,
session,
"Bitcoin",
[INP1, INP2],
[out1, out2],
@ -408,7 +408,7 @@ def test_multisig_mismatch_multisig_change(client: Client):
# inputs match, change mismatches (second tries to be change but isn't)
@pytest.mark.models(skip="legacy", reason="Not fixed")
def test_multisig_mismatch_multisig_change_different_paths(client: Client):
def test_multisig_mismatch_multisig_change_different_paths(session: Session):
multisig_out2 = messages.MultisigRedeemScriptType(
pubkeys=[
messages.HDNodePathType(node=NODE_EXT1, address_n=[1, 0]),
@ -432,10 +432,10 @@ def test_multisig_mismatch_multisig_change_different_paths(client: Client):
script_type=messages.OutputScriptType.PAYTOMULTISIG,
)
with client:
client.set_expected_responses(_responses(client, INP1, INP2))
with session:
session.set_expected_responses(_responses(session, INP1, INP2))
btc.sign_tx(
client,
session,
"Bitcoin",
[INP1, INP2],
[out1, out2],
@ -444,7 +444,7 @@ def test_multisig_mismatch_multisig_change_different_paths(client: Client):
# inputs mismatch, change matches with first input
def test_multisig_mismatch_inputs(client: Client):
def test_multisig_mismatch_inputs(session: Session):
multisig_out1 = messages.MultisigRedeemScriptType(
nodes=[NODE_EXT2, NODE_EXT1, NODE_INT],
address_n=[1, 0],
@ -465,10 +465,10 @@ def test_multisig_mismatch_inputs(client: Client):
script_type=messages.OutputScriptType.PAYTOADDRESS,
)
with client:
client.set_expected_responses(_responses(client, INP1, INP3))
with session:
session.set_expected_responses(_responses(session, INP1, INP3))
btc.sign_tx(
client,
session,
"Bitcoin",
[INP1, INP3],
[out1, out2],

View File

@ -17,7 +17,7 @@
import pytest
from trezorlib import btc, messages
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.debuglink import SessionDebugWrapper as Session
from trezorlib.tools import parse_path
from ...common import is_core
@ -94,11 +94,11 @@ VECTORS_MULTISIG = ( # paths, address_index
# accepted in case we make this more restrictive in the future.
@pytest.mark.parametrize("path, script_types", VECTORS)
def test_getpublicnode(
client: Client, path: str, script_types: list[messages.InputScriptType]
session: Session, path: str, script_types: list[messages.InputScriptType]
):
for script_type in script_types:
res = btc.get_public_node(
client, parse_path(path), coin_name="Bitcoin", script_type=script_type
session, parse_path(path), coin_name="Bitcoin", script_type=script_type
)
assert res.xpub
@ -107,18 +107,18 @@ def test_getpublicnode(
@pytest.mark.parametrize("chunkify", (True, False))
@pytest.mark.parametrize("path, script_types", VECTORS)
def test_getaddress(
client: Client,
session: Session,
chunkify: bool,
path: str,
script_types: list[messages.InputScriptType],
):
for script_type in script_types:
with client:
if is_core(client):
with session.client as client:
if is_core(session):
IF = InputFlowConfirmAllWarnings(client)
client.set_input_flow(IF.get())
res = btc.get_address(
client,
session,
"Bitcoin",
parse_path(path),
show_display=True,
@ -131,16 +131,16 @@ def test_getaddress(
@pytest.mark.parametrize("path, script_types", VECTORS)
def test_signmessage(
client: Client, path: str, script_types: list[messages.InputScriptType]
session: Session, path: str, script_types: list[messages.InputScriptType]
):
for script_type in script_types:
with client:
if is_core(client):
with session.client as client:
if is_core(session):
IF = InputFlowConfirmAllWarnings(client)
client.set_input_flow(IF.get())
sig = btc.sign_message(
client,
session,
coin_name="Bitcoin",
n=parse_path(path),
script_type=script_type,
@ -152,12 +152,14 @@ def test_signmessage(
@pytest.mark.parametrize("path, script_types", VECTORS)
def test_signtx(
client: Client, path: str, script_types: list[messages.InputScriptType]
session: Session, path: str, script_types: list[messages.InputScriptType]
):
address_n = parse_path(path)
for script_type in script_types:
address = btc.get_address(client, "Bitcoin", address_n, script_type=script_type)
address = btc.get_address(
session, "Bitcoin", address_n, script_type=script_type
)
prevhash, prevtx = forge_prevtx([(address, 390_000)])
inp1 = messages.TxInputType(
address_n=address_n,
@ -173,12 +175,12 @@ def test_signtx(
script_type=messages.OutputScriptType.PAYTOADDRESS,
)
with client:
if is_core(client):
with session.client as client:
if is_core(session):
IF = InputFlowConfirmAllWarnings(client)
client.set_input_flow(IF.get())
_, serialized_tx = btc.sign_tx(
client, "Bitcoin", [inp1], [out1], prev_txes={prevhash: prevtx}
session, "Bitcoin", [inp1], [out1], prev_txes={prevhash: prevtx}
)
assert serialized_tx.hex()
@ -187,12 +189,12 @@ def test_signtx(
@pytest.mark.multisig
@pytest.mark.parametrize("paths, address_index", VECTORS_MULTISIG)
def test_getaddress_multisig(
client: Client, paths: list[str], address_index: list[int]
session: Session, paths: list[str], address_index: list[int]
):
pubs = [
messages.HDNodePathType(
node=btc.get_public_node(
client, parse_path(path), coin_name="Bitcoin"
session, parse_path(path), coin_name="Bitcoin"
).node,
address_n=address_index,
)
@ -200,12 +202,12 @@ def test_getaddress_multisig(
]
multisig = messages.MultisigRedeemScriptType(pubkeys=pubs, m=2)
with client:
if is_core(client):
with session.client as client:
if is_core(session):
IF = InputFlowConfirmAllWarnings(client)
client.set_input_flow(IF.get())
address = btc.get_address(
client,
session,
"Bitcoin",
parse_path(paths[0]) + address_index,
show_display=True,
@ -218,11 +220,11 @@ def test_getaddress_multisig(
@pytest.mark.multisig
@pytest.mark.parametrize("paths, address_index", VECTORS_MULTISIG)
def test_signtx_multisig(client: Client, paths: list[str], address_index: list[int]):
def test_signtx_multisig(session: Session, paths: list[str], address_index: list[int]):
pubs = [
messages.HDNodePathType(
node=btc.get_public_node(
client, parse_path(path), coin_name="Bitcoin"
session, parse_path(path), coin_name="Bitcoin"
).node,
address_n=address_index,
)
@ -235,7 +237,7 @@ def test_signtx_multisig(client: Client, paths: list[str], address_index: list[i
address_n = parse_path(paths[0]) + address_index
address = btc.get_address(
client,
session,
"Bitcoin",
address_n,
multisig=multisig,
@ -259,12 +261,12 @@ def test_signtx_multisig(client: Client, paths: list[str], address_index: list[i
script_type=messages.OutputScriptType.PAYTOADDRESS,
)
with client:
if is_core(client):
with session.client as client:
if is_core(session):
IF = InputFlowConfirmAllWarnings(client)
client.set_input_flow(IF.get())
sig, _ = btc.sign_tx(
client, "Bitcoin", [inp1], [out1], prev_txes={prevhash: prevtx}
session, "Bitcoin", [inp1], [out1], prev_txes={prevhash: prevtx}
)
assert sig[0]

View File

@ -17,7 +17,7 @@
import pytest
from trezorlib import btc, messages
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.debuglink import SessionDebugWrapper as Session
from trezorlib.exceptions import TrezorFailure
from trezorlib.tools import parse_path
@ -43,7 +43,7 @@ TXHASH_4075a1 = bytes.fromhex(
)
def test_opreturn(client: Client):
def test_opreturn(session: Session):
inp1 = messages.TxInputType(
address_n=parse_path("m/44h/1h/1h/0/21"), # myGMXcCxmuDooMdzZFPMmvHviijzqYKhza
amount=89_581,
@ -63,13 +63,13 @@ def test_opreturn(client: Client):
script_type=messages.OutputScriptType.PAYTOOPRETURN,
)
with client:
client.set_expected_responses(
with session:
session.set_expected_responses(
[
request_input(0),
request_output(0),
messages.ButtonRequest(code=B.ConfirmOutput),
(is_core(client), messages.ButtonRequest(code=B.ConfirmOutput)),
(is_core(session), messages.ButtonRequest(code=B.ConfirmOutput)),
request_output(1),
messages.ButtonRequest(code=B.ConfirmOutput),
messages.ButtonRequest(code=B.SignTx),
@ -86,7 +86,7 @@ def test_opreturn(client: Client):
]
)
_, serialized_tx = btc.sign_tx(
client, "Testnet", [inp1], [out1, out2], prev_txes=TX_API_TESTNET
session, "Testnet", [inp1], [out1, out2], prev_txes=TX_API_TESTNET
)
assert_tx_matches(
@ -96,7 +96,7 @@ def test_opreturn(client: Client):
)
def test_nonzero_opreturn(client: Client):
def test_nonzero_opreturn(session: Session):
inp1 = messages.TxInputType(
address_n=parse_path("m/44h/0h/10h/0/5"),
amount=390_000,
@ -110,18 +110,18 @@ def test_nonzero_opreturn(client: Client):
script_type=messages.OutputScriptType.PAYTOOPRETURN,
)
with client:
client.set_expected_responses(
with session:
session.set_expected_responses(
[request_input(0), request_output(0), messages.Failure()]
)
with pytest.raises(
TrezorFailure, match="OP_RETURN output with non-zero amount"
):
btc.sign_tx(client, "Bitcoin", [inp1], [out1], prev_txes=TX_API)
btc.sign_tx(session, "Bitcoin", [inp1], [out1], prev_txes=TX_API)
def test_opreturn_address(client: Client):
def test_opreturn_address(session: Session):
inp1 = messages.TxInputType(
address_n=parse_path("m/44h/0h/0h/0/2"),
amount=390_000,
@ -136,11 +136,11 @@ def test_opreturn_address(client: Client):
script_type=messages.OutputScriptType.PAYTOOPRETURN,
)
with client:
client.set_expected_responses(
with session:
session.set_expected_responses(
[request_input(0), request_output(0), messages.Failure()]
)
with pytest.raises(
TrezorFailure, match="Output's address_n provided but not expected."
):
btc.sign_tx(client, "Bitcoin", [inp1], [out1], prev_txes=TX_API)
btc.sign_tx(session, "Bitcoin", [inp1], [out1], prev_txes=TX_API)

View File

@ -17,7 +17,7 @@
import pytest
from trezorlib import btc, messages
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.debuglink import SessionDebugWrapper as Session
from trezorlib.exceptions import TrezorFailure
from trezorlib.tools import parse_path
@ -32,7 +32,7 @@ TXHASH_41b29a = bytes.fromhex(
@pytest.mark.altcoin
@pytest.mark.peercoin
def test_timestamp_included(client: Client):
def test_timestamp_included(session: Session):
# tx: 41b29ad615d8eea40a4654a052d18bb10cd08f203c351f4d241f88b031357d3d
# input 0: 0.1 PPC
@ -50,7 +50,7 @@ def test_timestamp_included(client: Client):
)
_, timestamp_tx = btc.sign_tx(
client,
session,
"Peercoin",
[inp1],
[out1],
@ -66,7 +66,7 @@ def test_timestamp_included(client: Client):
@pytest.mark.altcoin
@pytest.mark.peercoin
def test_timestamp_missing(client: Client):
def test_timestamp_missing(session: Session):
inp1 = messages.TxInputType(
address_n=parse_path("m/44h/6h/0h/0/0"),
amount=100_000,
@ -81,7 +81,7 @@ def test_timestamp_missing(client: Client):
with pytest.raises(TrezorFailure, match="Timestamp must be set."):
btc.sign_tx(
client,
session,
"Peercoin",
[inp1],
[out1],
@ -92,7 +92,7 @@ def test_timestamp_missing(client: Client):
with pytest.raises(TrezorFailure, match="Timestamp must be set."):
btc.sign_tx(
client,
session,
"Peercoin",
[inp1],
[out1],
@ -104,7 +104,7 @@ def test_timestamp_missing(client: Client):
@pytest.mark.altcoin
@pytest.mark.peercoin
def test_timestamp_missing_prevtx(client: Client):
def test_timestamp_missing_prevtx(session: Session):
inp1 = messages.TxInputType(
address_n=parse_path("m/44h/6h/0h/0/0"),
amount=100_000,
@ -122,7 +122,7 @@ def test_timestamp_missing_prevtx(client: Client):
with pytest.raises(TrezorFailure, match="Timestamp must be set."):
btc.sign_tx(
client,
session,
"Peercoin",
[inp1],
[out1],
@ -134,7 +134,7 @@ def test_timestamp_missing_prevtx(client: Client):
prevtx.timestamp = None
with pytest.raises(TrezorFailure, match="Timestamp must be set."):
btc.sign_tx(
client,
session,
"Peercoin",
[inp1],
[out1],

View File

@ -20,7 +20,7 @@ import pytest
from trezorlib import btc, messages
from trezorlib.debuglink import LayoutType
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.debuglink import SessionDebugWrapper as Session
from trezorlib.debuglink import message_filters
from trezorlib.exceptions import Cancelled
from trezorlib.tools import parse_path
@ -286,7 +286,7 @@ VECTORS = ( # case name, coin_name, path, script_type, address, message, signat
"coin_name, path, script_type, no_script_type, address, message, signature", VECTORS
)
def test_signmessage(
client: Client,
session: Session,
coin_name: str,
path: str,
script_type: messages.InputScriptType,
@ -296,7 +296,7 @@ def test_signmessage(
signature: str,
):
sig = btc.sign_message(
client,
session,
coin_name=coin_name,
n=parse_path(path),
script_type=script_type,
@ -312,7 +312,7 @@ def test_signmessage(
"coin_name, path, script_type, no_script_type, address, message, signature", VECTORS
)
def test_signmessage_info(
client: Client,
session: Session,
coin_name: str,
path: str,
script_type: messages.InputScriptType,
@ -321,11 +321,11 @@ def test_signmessage_info(
message: str,
signature: str,
):
with client, pytest.raises(Cancelled):
with session.client as client, pytest.raises(Cancelled):
IF = InputFlowSignMessageInfo(client)
client.set_input_flow(IF.get())
sig = btc.sign_message(
client,
session,
coin_name=coin_name,
n=parse_path(path),
script_type=script_type,
@ -352,12 +352,12 @@ MESSAGE_LENGTHS = (
@pytest.mark.models("core")
@pytest.mark.parametrize("message", MESSAGE_LENGTHS)
def test_signmessage_pagination(client: Client, message: str):
with client:
def test_signmessage_pagination(session: Session, message: str):
with session.client as client:
IF = InputFlowSignMessagePagination(client)
client.set_input_flow(IF.get())
btc.sign_message(
client,
session,
coin_name="Bitcoin",
n=parse_path("m/44h/0h/0h/0/0"),
message=message,
@ -365,19 +365,19 @@ def test_signmessage_pagination(client: Client, message: str):
# We cannot differentiate between a newline and space in the message read from Trezor.
# TODO: do the check also for T2B1
if client.layout_type in (LayoutType.TT, LayoutType.Mercury):
if session.client.layout_type in (LayoutType.TT, LayoutType.Mercury):
message_read = IF.message_read.replace(" ", "").replace("...", "")
signed_message = message.replace("\n", "").replace(" ", "")
assert signed_message in message_read
@pytest.mark.models("t2t1", reason="Tailored to TT fonts and screen size")
def test_signmessage_pagination_trailing_newline(client: Client):
def test_signmessage_pagination_trailing_newline(session: Session):
message = "THIS\nMUST\nNOT\nBE\nPAGINATED\n"
# The trailing newline must not cause a new paginated screen to appear.
# The UI must be a single dialog without pagination.
with client:
client.set_expected_responses(
with session:
session.set_expected_responses(
[
# expect address confirmation
message_filters.ButtonRequest(code=messages.ButtonRequestType.Other),
@ -387,18 +387,18 @@ def test_signmessage_pagination_trailing_newline(client: Client):
]
)
btc.sign_message(
client,
session,
coin_name="Bitcoin",
n=parse_path("m/44h/0h/0h/0/0"),
message=message,
)
def test_signmessage_path_warning(client: Client):
def test_signmessage_path_warning(session: Session):
message = "This is an example of a signed message."
with client:
client.set_expected_responses(
with session, session.client as client:
session.set_expected_responses(
[
# expect a path warning
message_filters.ButtonRequest(
@ -409,11 +409,11 @@ def test_signmessage_path_warning(client: Client):
messages.MessageSignature,
]
)
if is_core(client):
if is_core(session):
IF = InputFlowConfirmAllWarnings(client)
client.set_input_flow(IF.get())
btc.sign_message(
client,
session,
coin_name="Bitcoin",
n=parse_path("m/86h/0h/0h/0/0"),
message=message,

View File

@ -19,7 +19,7 @@ from datetime import datetime, timezone
import pytest
from trezorlib import btc, device, messages
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.debuglink import SessionDebugWrapper as Session
from trezorlib.exceptions import Cancelled, TrezorFailure
from trezorlib.tools import H_, parse_path
@ -111,7 +111,7 @@ TXHASH_efaa41 = bytes.fromhex(
CORNER_BUTTON = (215, 25)
def test_one_one_fee(client: Client):
def test_one_one_fee(session: Session):
# input tx: 0dac366fd8a67b2a89fbb0d31086e7acded7a5bbf9ef9daa935bc873229ef5b5
inp1 = messages.TxInputType(
@ -127,13 +127,13 @@ def test_one_one_fee(client: Client):
script_type=messages.OutputScriptType.PAYTOADDRESS,
)
with client:
client.set_expected_responses(
with session:
session.set_expected_responses(
[
request_input(0),
request_output(0),
messages.ButtonRequest(code=B.ConfirmOutput),
(is_core(client), messages.ButtonRequest(code=B.ConfirmOutput)),
(is_core(session), messages.ButtonRequest(code=B.ConfirmOutput)),
messages.ButtonRequest(code=B.SignTx),
request_input(0),
request_meta(TXHASH_0dac36),
@ -148,7 +148,7 @@ def test_one_one_fee(client: Client):
)
_, serialized_tx = btc.sign_tx(
client, "Bitcoin", [inp1], [out1], prev_txes=TX_CACHE_MAINNET
session, "Bitcoin", [inp1], [out1], prev_txes=TX_CACHE_MAINNET
)
assert_tx_matches(
@ -158,7 +158,7 @@ def test_one_one_fee(client: Client):
)
def test_testnet_one_two_fee(client: Client):
def test_testnet_one_two_fee(session: Session):
# input tx: e5040e1bc1ae7667ffb9e5248e90b2fb93cd9150234151ce90e14ab2f5933bcd
inp1 = messages.TxInputType(
@ -180,13 +180,13 @@ def test_testnet_one_two_fee(client: Client):
script_type=messages.OutputScriptType.PAYTOADDRESS,
)
with client:
client.set_expected_responses(
with session:
session.set_expected_responses(
[
request_input(0),
request_output(0),
messages.ButtonRequest(code=B.ConfirmOutput),
(is_core(client), messages.ButtonRequest(code=B.ConfirmOutput)),
(is_core(session), messages.ButtonRequest(code=B.ConfirmOutput)),
request_output(1),
messages.ButtonRequest(code=B.SignTx),
request_input(0),
@ -203,7 +203,7 @@ def test_testnet_one_two_fee(client: Client):
]
)
_, serialized_tx = btc.sign_tx(
client, "Testnet", [inp1], [out1, out2], prev_txes=TX_CACHE_TESTNET
session, "Testnet", [inp1], [out1, out2], prev_txes=TX_CACHE_TESTNET
)
assert_tx_matches(
@ -213,7 +213,7 @@ def test_testnet_one_two_fee(client: Client):
)
def test_testnet_fee_high_warning(client: Client):
def test_testnet_fee_high_warning(session: Session):
# input tx: 25fee583181847cbe9d9fd9a483a8b8626c99854a72d01de848ef40508d0f3bc
# (The "25fee" tx hash is very suitable for testing high fees)
@ -230,13 +230,13 @@ def test_testnet_fee_high_warning(client: Client):
script_type=messages.OutputScriptType.PAYTOADDRESS,
)
with client:
client.set_expected_responses(
with session:
session.set_expected_responses(
[
request_input(0),
request_output(0),
messages.ButtonRequest(code=B.ConfirmOutput),
(is_core(client), messages.ButtonRequest(code=B.ConfirmOutput)),
(is_core(session), messages.ButtonRequest(code=B.ConfirmOutput)),
messages.ButtonRequest(code=B.FeeOverThreshold),
messages.ButtonRequest(code=B.SignTx),
request_input(0),
@ -250,7 +250,7 @@ def test_testnet_fee_high_warning(client: Client):
]
)
_, serialized_tx = btc.sign_tx(
client, "Testnet", [inp1], [out1], prev_txes=TX_CACHE_TESTNET
session, "Testnet", [inp1], [out1], prev_txes=TX_CACHE_TESTNET
)
# Transaction does not exist on the blockchain, not using assert_tx_matches()
@ -260,7 +260,7 @@ def test_testnet_fee_high_warning(client: Client):
)
def test_one_two_fee(client: Client):
def test_one_two_fee(session: Session):
# input tx: 50f6f1209ca92d7359564be803cb2c932cde7d370f7cee50fd1fad6790f6206d
inp1 = messages.TxInputType(
@ -282,14 +282,14 @@ def test_one_two_fee(client: Client):
script_type=messages.OutputScriptType.PAYTOADDRESS,
)
with client:
client.set_expected_responses(
with session:
session.set_expected_responses(
[
request_input(0),
request_output(0),
request_output(1),
messages.ButtonRequest(code=B.ConfirmOutput),
(is_core(client), messages.ButtonRequest(code=B.ConfirmOutput)),
(is_core(session), messages.ButtonRequest(code=B.ConfirmOutput)),
messages.ButtonRequest(code=B.SignTx),
request_input(0),
request_meta(TXHASH_50f6f1),
@ -305,7 +305,7 @@ def test_one_two_fee(client: Client):
]
)
_, serialized_tx = btc.sign_tx(
client, "Bitcoin", [inp1], [out1, out2], prev_txes=TX_CACHE_MAINNET
session, "Bitcoin", [inp1], [out1, out2], prev_txes=TX_CACHE_MAINNET
)
assert_tx_matches(
@ -316,7 +316,7 @@ def test_one_two_fee(client: Client):
@pytest.mark.parametrize("chunkify", (True, False))
def test_one_three_fee(client: Client, chunkify: bool):
def test_one_three_fee(session: Session, chunkify: bool):
# input tx: bb5169091f09e833e155b291b662019df56870effe388c626221c5ea84274bc4
inp1 = messages.TxInputType(
@ -344,16 +344,16 @@ def test_one_three_fee(client: Client, chunkify: bool):
script_type=messages.OutputScriptType.PAYTOADDRESS,
)
with client:
client.set_expected_responses(
with session:
session.set_expected_responses(
[
request_input(0),
request_output(0),
messages.ButtonRequest(code=B.ConfirmOutput),
(is_core(client), messages.ButtonRequest(code=B.ConfirmOutput)),
(is_core(session), messages.ButtonRequest(code=B.ConfirmOutput)),
request_output(1),
messages.ButtonRequest(code=B.ConfirmOutput),
(is_core(client), messages.ButtonRequest(code=B.ConfirmOutput)),
(is_core(session), messages.ButtonRequest(code=B.ConfirmOutput)),
request_output(2),
messages.ButtonRequest(code=B.SignTx),
request_input(0),
@ -371,7 +371,7 @@ def test_one_three_fee(client: Client, chunkify: bool):
]
)
_, serialized_tx = btc.sign_tx(
client,
session,
"Testnet",
[inp1],
[out1, out2, out3],
@ -386,7 +386,7 @@ def test_one_three_fee(client: Client, chunkify: bool):
)
def test_two_two(client: Client):
def test_two_two(session: Session):
# input tx: ac4ca0e7827a1228f44449cb57b4b9a809a667ca044dc43bb124627fed4bc10a
inp1 = messages.TxInputType(
@ -415,15 +415,15 @@ def test_two_two(client: Client):
script_type=messages.OutputScriptType.PAYTOADDRESS,
)
with client:
client.set_expected_responses(
with session:
session.set_expected_responses(
[
request_input(0),
request_input(1),
request_output(0),
request_output(1),
messages.ButtonRequest(code=B.ConfirmOutput),
(is_core(client), messages.ButtonRequest(code=B.ConfirmOutput)),
(is_core(session), messages.ButtonRequest(code=B.ConfirmOutput)),
messages.ButtonRequest(code=B.SignTx),
request_input(0),
request_meta(TXHASH_ac4ca0),
@ -449,7 +449,7 @@ def test_two_two(client: Client):
]
)
_, serialized_tx = btc.sign_tx(
client,
session,
"Bitcoin",
[inp1, inp2],
[out1, out2],
@ -464,7 +464,7 @@ def test_two_two(client: Client):
@pytest.mark.slow
def test_lots_of_inputs(client: Client):
def test_lots_of_inputs(session: Session):
# Tests if device implements serialization of len(inputs) correctly
# input tx: 3019487f064329247daad245aed7a75349d09c14b1d24f170947690e030f5b20
@ -485,7 +485,7 @@ def test_lots_of_inputs(client: Client):
script_type=messages.OutputScriptType.PAYTOADDRESS,
)
_, serialized_tx = btc.sign_tx(
client, "Testnet", inputs, [out], prev_txes=TX_CACHE_TESTNET
session, "Testnet", inputs, [out], prev_txes=TX_CACHE_TESTNET
)
assert_tx_matches(
@ -495,7 +495,7 @@ def test_lots_of_inputs(client: Client):
@pytest.mark.slow
def test_lots_of_outputs(client: Client):
def test_lots_of_outputs(session: Session):
# Tests if device implements serialization of len(outputs) correctly
# input tx: 58d56a5d1325cf83543ee4c87fd73a784e4ba1499ced574be359fa2bdcb9ac8e
@ -518,7 +518,7 @@ def test_lots_of_outputs(client: Client):
outputs.append(out)
_, serialized_tx = btc.sign_tx(
client, "Testnet", [inp1], outputs, prev_txes=TX_CACHE_TESTNET
session, "Testnet", [inp1], outputs, prev_txes=TX_CACHE_TESTNET
)
assert_tx_matches(
@ -528,7 +528,7 @@ def test_lots_of_outputs(client: Client):
@pytest.mark.slow
def test_lots_of_change(client: Client):
def test_lots_of_change(session: Session):
# Tests if device implements prompting for multiple change addresses correctly
# input tx: 892d06cb3394b8e6006eec9a2aa90692b718a29be6844b6c6a9e89ec3aa6aac4
@ -559,13 +559,13 @@ def test_lots_of_change(client: Client):
request_change_outputs = [request_output(i + 1) for i in range(cnt)]
with client:
client.set_expected_responses(
with session:
session.set_expected_responses(
[
request_input(0),
request_output(0),
messages.ButtonRequest(code=B.ConfirmOutput),
(is_core(client), messages.ButtonRequest(code=B.ConfirmOutput)),
(is_core(session), messages.ButtonRequest(code=B.ConfirmOutput)),
]
+ request_change_outputs
+ [
@ -585,7 +585,7 @@ def test_lots_of_change(client: Client):
)
_, serialized_tx = btc.sign_tx(
client, "Testnet", [inp1], outputs, prev_txes=TX_CACHE_TESTNET
session, "Testnet", [inp1], outputs, prev_txes=TX_CACHE_TESTNET
)
assert_tx_matches(
@ -594,7 +594,7 @@ def test_lots_of_change(client: Client):
)
def test_fee_high_warning(client: Client):
def test_fee_high_warning(session: Session):
# input tx: 1f326f65768d55ef146efbb345bd87abe84ac7185726d0457a026fc347a26ef3
inp1 = messages.TxInputType(
@ -610,13 +610,13 @@ def test_fee_high_warning(client: Client):
script_type=messages.OutputScriptType.PAYTOADDRESS,
)
with client:
client.set_expected_responses(
with session:
session.set_expected_responses(
[
request_input(0),
request_output(0),
messages.ButtonRequest(code=B.ConfirmOutput),
(is_core(client), messages.ButtonRequest(code=B.ConfirmOutput)),
(is_core(session), messages.ButtonRequest(code=B.ConfirmOutput)),
messages.ButtonRequest(code=B.FeeOverThreshold),
messages.ButtonRequest(code=B.SignTx),
request_input(0),
@ -631,7 +631,7 @@ def test_fee_high_warning(client: Client):
]
)
_, serialized_tx = btc.sign_tx(
client, "Bitcoin", [inp1], [out1], prev_txes=TX_CACHE_MAINNET
session, "Bitcoin", [inp1], [out1], prev_txes=TX_CACHE_MAINNET
)
# Transaction does not exist on the blockchain, not using assert_tx_matches()
@ -642,7 +642,7 @@ def test_fee_high_warning(client: Client):
@pytest.mark.models("core")
def test_fee_high_hardfail(client: Client):
def test_fee_high_hardfail(session: Session):
# input tx: 25fee583181847cbe9d9fd9a483a8b8626c99854a72d01de848ef40508d0f3bc
# (The "25fee" tx hash is very suitable for testing high fees)
@ -660,18 +660,18 @@ def test_fee_high_hardfail(client: Client):
)
with pytest.raises(TrezorFailure, match="fee is unexpectedly large"):
btc.sign_tx(client, "Testnet", [inp1], [out1], prev_txes=TX_CACHE_TESTNET)
btc.sign_tx(session, "Testnet", [inp1], [out1], prev_txes=TX_CACHE_TESTNET)
# set SafetyCheckLevel to PromptTemporarily and try again
device.apply_settings(
client, safety_checks=messages.SafetyCheckLevel.PromptTemporarily
session, safety_checks=messages.SafetyCheckLevel.PromptTemporarily
)
with client:
with session.client as client:
IF = InputFlowSignTxHighFee(client)
client.set_input_flow(IF.get())
_, serialized_tx = btc.sign_tx(
client, "Testnet", [inp1], [out1], prev_txes=TX_CACHE_TESTNET
session, "Testnet", [inp1], [out1], prev_txes=TX_CACHE_TESTNET
)
assert IF.finished
@ -682,7 +682,7 @@ def test_fee_high_hardfail(client: Client):
)
def test_not_enough_funds(client: Client):
def test_not_enough_funds(session: Session):
# input tx: d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882
inp1 = messages.TxInputType(
@ -698,21 +698,21 @@ def test_not_enough_funds(client: Client):
script_type=messages.OutputScriptType.PAYTOADDRESS,
)
with client:
client.set_expected_responses(
with session:
session.set_expected_responses(
[
request_input(0),
request_output(0),
messages.ButtonRequest(code=B.ConfirmOutput),
(is_core(client), messages.ButtonRequest(code=B.ConfirmOutput)),
(is_core(session), messages.ButtonRequest(code=B.ConfirmOutput)),
messages.Failure(code=messages.FailureType.NotEnoughFunds),
]
)
with pytest.raises(TrezorFailure, match="NotEnoughFunds"):
btc.sign_tx(client, "Bitcoin", [inp1], [out1], prev_txes=TX_CACHE_MAINNET)
btc.sign_tx(session, "Bitcoin", [inp1], [out1], prev_txes=TX_CACHE_MAINNET)
def test_p2sh(client: Client):
def test_p2sh(session: Session):
# input tx: 58d56a5d1325cf83543ee4c87fd73a784e4ba1499ced574be359fa2bdcb9ac8e
inp1 = messages.TxInputType(
@ -728,13 +728,13 @@ def test_p2sh(client: Client):
script_type=messages.OutputScriptType.PAYTOSCRIPTHASH,
)
with client:
client.set_expected_responses(
with session:
session.set_expected_responses(
[
request_input(0),
request_output(0),
messages.ButtonRequest(code=B.ConfirmOutput),
(is_core(client), messages.ButtonRequest(code=B.ConfirmOutput)),
(is_core(session), messages.ButtonRequest(code=B.ConfirmOutput)),
messages.ButtonRequest(code=B.SignTx),
request_input(0),
request_meta(TXHASH_58d56a),
@ -748,7 +748,7 @@ def test_p2sh(client: Client):
]
)
_, serialized_tx = btc.sign_tx(
client, "Testnet", [inp1], [out1], prev_txes=TX_CACHE_TESTNET
session, "Testnet", [inp1], [out1], prev_txes=TX_CACHE_TESTNET
)
assert_tx_matches(
@ -758,7 +758,7 @@ def test_p2sh(client: Client):
)
def test_testnet_big_amount(client: Client):
def test_testnet_big_amount(session: Session):
# This test is testing transaction with amount bigger than fits to uint32
# input tx: 074b0070939db4c2635c1bef0c8e68412ccc8d3c8782137547c7a2bbde073fc0
@ -775,7 +775,7 @@ def test_testnet_big_amount(client: Client):
script_type=messages.OutputScriptType.PAYTOADDRESS,
)
_, serialized_tx = btc.sign_tx(
client, "Testnet", [inp1], [out1], prev_txes=TX_CACHE_TESTNET
session, "Testnet", [inp1], [out1], prev_txes=TX_CACHE_TESTNET
)
assert_tx_matches(
@ -785,7 +785,7 @@ def test_testnet_big_amount(client: Client):
)
def test_attack_change_outputs(client: Client):
def test_attack_change_outputs(session: Session):
# input tx: ac4ca0e7827a1228f44449cb57b4b9a809a667ca044dc43bb124627fed4bc10a
inp1 = messages.TxInputType(
@ -815,15 +815,15 @@ def test_attack_change_outputs(client: Client):
)
# Test if the transaction can be signed normally
with client:
client.set_expected_responses(
with session:
session.set_expected_responses(
[
request_input(0),
request_input(1),
request_output(0),
request_output(1),
messages.ButtonRequest(code=B.ConfirmOutput),
(is_core(client), messages.ButtonRequest(code=B.ConfirmOutput)),
(is_core(session), messages.ButtonRequest(code=B.ConfirmOutput)),
messages.ButtonRequest(code=B.SignTx),
request_input(0),
request_meta(TXHASH_ac4ca0),
@ -849,7 +849,7 @@ def test_attack_change_outputs(client: Client):
]
)
_, serialized_tx = btc.sign_tx(
client, "Bitcoin", [inp1, inp2], [out1, out2], prev_txes=TX_CACHE_MAINNET
session, "Bitcoin", [inp1, inp2], [out1, out2], prev_txes=TX_CACHE_MAINNET
)
assert_tx_matches(
@ -871,14 +871,14 @@ def test_attack_change_outputs(client: Client):
return msg
with client, pytest.raises(
with session, pytest.raises(
TrezorFailure, match="Transaction has changed during signing"
):
# Set up attack processors
client.set_filter(messages.TxAck, attack_processor)
session.set_filter(messages.TxAck, attack_processor)
btc.sign_tx(
client,
session,
"Bitcoin",
[inp1, inp2],
[out1, out2],
@ -886,7 +886,7 @@ def test_attack_change_outputs(client: Client):
)
def test_attack_modify_change_address(client: Client):
def test_attack_modify_change_address(session: Session):
# Ensure that if the change output is modified after the user confirms the
# transaction, then signing fails.
@ -926,16 +926,18 @@ def test_attack_modify_change_address(client: Client):
return msg
with client, pytest.raises(
with session, pytest.raises(
TrezorFailure, match="Transaction has changed during signing"
):
# Set up attack processors
client.set_filter(messages.TxAck, attack_processor)
session.set_filter(messages.TxAck, attack_processor)
btc.sign_tx(client, "Testnet", [inp1], [out1, out2], prev_txes=TX_CACHE_TESTNET)
btc.sign_tx(
session, "Testnet", [inp1], [out1, out2], prev_txes=TX_CACHE_TESTNET
)
def test_attack_change_input_address(client: Client):
def test_attack_change_input_address(session: Session):
# input tx: d2dcdaf547ea7f57a713c607f15e883ddc4a98167ee2c43ed953c53cb5153e24
inp1 = messages.TxInputType(
@ -960,7 +962,7 @@ def test_attack_change_input_address(client: Client):
# Test if the transaction can be signed normally
_, serialized_tx = btc.sign_tx(
client, "Testnet", [inp1], [out1, out2], prev_txes=TX_CACHE_TESTNET
session, "Testnet", [inp1], [out1, out2], prev_txes=TX_CACHE_TESTNET
)
# Transaction does not exist on the blockchain, not using assert_tx_matches()
@ -982,14 +984,14 @@ def test_attack_change_input_address(client: Client):
return msg
# Now run the attack, must trigger the exception
with client:
client.set_filter(messages.TxAck, attack_processor)
client.set_expected_responses(
with session:
session.set_filter(messages.TxAck, attack_processor)
session.set_expected_responses(
[
request_input(0),
request_output(0),
messages.ButtonRequest(code=B.ConfirmOutput),
(is_core(client), messages.ButtonRequest(code=B.ConfirmOutput)),
(is_core(session), messages.ButtonRequest(code=B.ConfirmOutput)),
request_output(1),
messages.ButtonRequest(code=B.SignTx),
request_input(0),
@ -1004,7 +1006,7 @@ def test_attack_change_input_address(client: Client):
# Now run the attack, must trigger the exception
with pytest.raises(TrezorFailure) as exc:
btc.sign_tx(
client,
session,
"Testnet",
[inp1],
[out1, out2],
@ -1015,7 +1017,7 @@ def test_attack_change_input_address(client: Client):
assert exc.value.message.endswith("Transaction has changed during signing")
def test_spend_coinbase(client: Client):
def test_spend_coinbase(session: Session):
# NOTE: the input transaction is not real
# We did not have any coinbase transaction at connected with `all all` seed,
# so it was artificially created for the test purpose
@ -1033,13 +1035,13 @@ def test_spend_coinbase(client: Client):
script_type=messages.OutputScriptType.PAYTOADDRESS,
)
with client:
client.set_expected_responses(
with session:
session.set_expected_responses(
[
request_input(0),
request_output(0),
messages.ButtonRequest(code=B.ConfirmOutput),
(is_core(client), messages.ButtonRequest(code=B.ConfirmOutput)),
(is_core(session), messages.ButtonRequest(code=B.ConfirmOutput)),
messages.ButtonRequest(code=B.SignTx),
request_input(0),
request_meta(FAKE_TXHASH_005f6f),
@ -1052,7 +1054,7 @@ def test_spend_coinbase(client: Client):
]
)
_, serialized_tx = btc.sign_tx(
client, "Testnet", [inp1], [out1], prev_txes=TX_CACHE_TESTNET
session, "Testnet", [inp1], [out1], prev_txes=TX_CACHE_TESTNET
)
# Transaction does not exist on the blockchain, not using assert_tx_matches()
@ -1062,7 +1064,7 @@ def test_spend_coinbase(client: Client):
)
def test_two_changes(client: Client):
def test_two_changes(session: Session):
# input tx: e5040e1bc1ae7667ffb9e5248e90b2fb93cd9150234151ce90e14ab2f5933bcd
# see 87be0736f202f7c2bff0781b42bad3e0cdcb54761939da69ea793a3735552c56
@ -1091,13 +1093,13 @@ def test_two_changes(client: Client):
script_type=messages.OutputScriptType.PAYTOADDRESS,
)
with client:
client.set_expected_responses(
with session:
session.set_expected_responses(
[
request_input(0),
request_output(0),
messages.ButtonRequest(code=B.ConfirmOutput),
(is_core(client), messages.ButtonRequest(code=B.ConfirmOutput)),
(is_core(session), messages.ButtonRequest(code=B.ConfirmOutput)),
request_output(1),
request_output(2),
messages.ButtonRequest(code=B.SignTx),
@ -1118,7 +1120,7 @@ def test_two_changes(client: Client):
)
btc.sign_tx(
client,
session,
"Testnet",
[inp1],
[out1, out_change1, out_change2],
@ -1126,7 +1128,7 @@ def test_two_changes(client: Client):
)
def test_change_on_main_chain_allowed(client: Client):
def test_change_on_main_chain_allowed(session: Session):
# input tx: e5040e1bc1ae7667ffb9e5248e90b2fb93cd9150234151ce90e14ab2f5933bcd
# see 87be0736f202f7c2bff0781b42bad3e0cdcb54761939da69ea793a3735552c56
@ -1150,13 +1152,13 @@ def test_change_on_main_chain_allowed(client: Client):
script_type=messages.OutputScriptType.PAYTOADDRESS,
)
with client:
client.set_expected_responses(
with session:
session.set_expected_responses(
[
request_input(0),
request_output(0),
messages.ButtonRequest(code=B.ConfirmOutput),
(is_core(client), messages.ButtonRequest(code=B.ConfirmOutput)),
(is_core(session), messages.ButtonRequest(code=B.ConfirmOutput)),
request_output(1),
messages.ButtonRequest(code=B.SignTx),
request_input(0),
@ -1174,7 +1176,7 @@ def test_change_on_main_chain_allowed(client: Client):
)
btc.sign_tx(
client,
session,
"Testnet",
[inp1],
[out1, out_change],
@ -1182,7 +1184,7 @@ def test_change_on_main_chain_allowed(client: Client):
)
def test_not_enough_vouts(client: Client):
def test_not_enough_vouts(session: Session):
# input tx: ac4ca0e7827a1228f44449cb57b4b9a809a667ca044dc43bb124627fed4bc10a
prev_tx = TX_CACHE_MAINNET[TXHASH_ac4ca0]
@ -1222,7 +1224,7 @@ def test_not_enough_vouts(client: Client):
TrezorFailure, match="Not enough outputs in previous transaction."
):
btc.sign_tx(
client,
session,
"Bitcoin",
[inp0, inp1, inp2],
[out1],
@ -1240,7 +1242,7 @@ def test_not_enough_vouts(client: Client):
("branch_id", 13),
),
)
def test_prevtx_forbidden_fields(client: Client, field, value):
def test_prevtx_forbidden_fields(session: Session, field, value):
inp0 = messages.TxInputType(
address_n=parse_path("m/44h/0h/0h/0/0"), # 1JAd7XCBzGudGpJQSDSfpmJhiygtLQWaGL
prev_hash=TXHASH_157041,
@ -1258,7 +1260,7 @@ def test_prevtx_forbidden_fields(client: Client, field, value):
name = field.replace("_", " ")
with pytest.raises(TrezorFailure, match=rf"(?i){name} not enabled on this coin"):
btc.sign_tx(
client, "Bitcoin", [inp0], [out1], prev_txes={TXHASH_157041: prev_tx}
session, "Bitcoin", [inp0], [out1], prev_txes={TXHASH_157041: prev_tx}
)
@ -1266,7 +1268,7 @@ def test_prevtx_forbidden_fields(client: Client, field, value):
"field, value",
(("expiry", 9), ("timestamp", 42), ("version_group_id", 69), ("branch_id", 13)),
)
def test_signtx_forbidden_fields(client: Client, field: str, value: int):
def test_signtx_forbidden_fields(session: Session, field: str, value: int):
inp0 = messages.TxInputType(
address_n=parse_path("m/44h/0h/0h/0/0"), # 1JAd7XCBzGudGpJQSDSfpmJhiygtLQWaGL
prev_hash=TXHASH_157041,
@ -1283,7 +1285,7 @@ def test_signtx_forbidden_fields(client: Client, field: str, value: int):
name = field.replace("_", " ")
with pytest.raises(TrezorFailure, match=rf"(?i){name} not enabled on this coin"):
btc.sign_tx(
client, "Bitcoin", [inp0], [out1], prev_txes=TX_CACHE_MAINNET, **kwargs
session, "Bitcoin", [inp0], [out1], prev_txes=TX_CACHE_MAINNET, **kwargs
)
@ -1291,7 +1293,7 @@ def test_signtx_forbidden_fields(client: Client, field: str, value: int):
"script_type",
(messages.InputScriptType.SPENDADDRESS, messages.InputScriptType.EXTERNAL),
)
def test_incorrect_input_script_type(client: Client, script_type):
def test_incorrect_input_script_type(session: Session, script_type):
address_n = parse_path("m/44h/1h/0h/0/0") # mvbu1Gdy8SUjTenqerxUaZyYjmveZvt33q
attacker_multisig_public_key = bytes.fromhex(
"030e669acac1f280d1ddf441cd2ba5e97417bf2689e4bbec86df4f831bf9f7ffd0"
@ -1300,7 +1302,7 @@ def test_incorrect_input_script_type(client: Client, script_type):
multisig = messages.MultisigRedeemScriptType(
m=1,
nodes=[
btc.get_public_node(client, address_n, coin_name="Testnet").node,
btc.get_public_node(session, address_n, coin_name="Testnet").node,
messages.HDNodeType(
depth=0,
fingerprint=0,
@ -1335,7 +1337,9 @@ def test_incorrect_input_script_type(client: Client, script_type):
with pytest.raises(
TrezorFailure, match="Multisig field provided but not expected."
):
btc.sign_tx(client, "Testnet", [inp1], [out1, out2], prev_txes=TX_CACHE_TESTNET)
btc.sign_tx(
session, "Testnet", [inp1], [out1, out2], prev_txes=TX_CACHE_TESTNET
)
@pytest.mark.parametrize(
@ -1346,7 +1350,7 @@ def test_incorrect_input_script_type(client: Client, script_type):
),
)
def test_incorrect_output_script_type(
client: Client, script_type: messages.OutputScriptType
session: Session, script_type: messages.OutputScriptType
):
address_n = parse_path("m/44h/1h/0h/0/0") # mvbu1Gdy8SUjTenqerxUaZyYjmveZvt33q
attacker_multisig_public_key = bytes.fromhex(
@ -1356,7 +1360,7 @@ def test_incorrect_output_script_type(
multisig = messages.MultisigRedeemScriptType(
m=1,
nodes=[
btc.get_public_node(client, address_n, coin_name="Testnet").node,
btc.get_public_node(session, address_n, coin_name="Testnet").node,
messages.HDNodeType(
depth=0,
fingerprint=0,
@ -1390,14 +1394,16 @@ def test_incorrect_output_script_type(
with pytest.raises(
TrezorFailure, match="Multisig field provided but not expected."
):
btc.sign_tx(client, "Testnet", [inp1], [out1, out2], prev_txes=TX_CACHE_TESTNET)
btc.sign_tx(
session, "Testnet", [inp1], [out1, out2], prev_txes=TX_CACHE_TESTNET
)
@pytest.mark.parametrize(
"lock_time, sequence",
((499_999_999, 0xFFFFFFFE), (500_000_000, 0xFFFFFFFE), (1, 0xFFFFFFFF)),
)
def test_lock_time(client: Client, lock_time: int, sequence: int):
def test_lock_time(session: Session, lock_time: int, sequence: int):
# input tx: 0dac366fd8a67b2a89fbb0d31086e7acded7a5bbf9ef9daa935bc873229ef5b5
inp1 = messages.TxInputType(
@ -1414,13 +1420,13 @@ def test_lock_time(client: Client, lock_time: int, sequence: int):
script_type=messages.OutputScriptType.PAYTOADDRESS,
)
with client:
client.set_expected_responses(
with session:
session.set_expected_responses(
[
request_input(0),
request_output(0),
messages.ButtonRequest(code=B.ConfirmOutput),
(is_core(client), messages.ButtonRequest(code=B.ConfirmOutput)),
(is_core(session), messages.ButtonRequest(code=B.ConfirmOutput)),
messages.ButtonRequest(code=B.SignTx),
messages.ButtonRequest(code=B.SignTx),
request_input(0),
@ -1436,7 +1442,7 @@ def test_lock_time(client: Client, lock_time: int, sequence: int):
)
btc.sign_tx(
client,
session,
"Bitcoin",
[inp1],
[out1],
@ -1446,7 +1452,7 @@ def test_lock_time(client: Client, lock_time: int, sequence: int):
@pytest.mark.models("core", reason="Cannot test layouts on T1")
def test_lock_time_blockheight(client: Client):
def test_lock_time_blockheight(session: Session):
# input tx: 0dac366fd8a67b2a89fbb0d31086e7acded7a5bbf9ef9daa935bc873229ef5b5
inp1 = messages.TxInputType(
@ -1463,12 +1469,12 @@ def test_lock_time_blockheight(client: Client):
script_type=messages.OutputScriptType.PAYTOADDRESS,
)
with client:
with session.client as client:
IF = InputFlowLockTimeBlockHeight(client, "499999999")
client.set_input_flow(IF.get())
btc.sign_tx(
client,
session,
"Bitcoin",
[inp1],
[out1],
@ -1481,7 +1487,7 @@ def test_lock_time_blockheight(client: Client):
@pytest.mark.parametrize(
"lock_time_str", ("1985-11-05 00:53:20", "2048-08-16 22:14:00")
)
def test_lock_time_datetime(client: Client, lock_time_str: str):
def test_lock_time_datetime(session: Session, lock_time_str: str):
# input tx: 0dac366fd8a67b2a89fbb0d31086e7acded7a5bbf9ef9daa935bc873229ef5b5
inp1 = messages.TxInputType(
@ -1502,12 +1508,12 @@ def test_lock_time_datetime(client: Client, lock_time_str: str):
lock_time_utc = lock_time_naive.replace(tzinfo=timezone.utc)
lock_time_timestamp = int(lock_time_utc.timestamp())
with client:
with session.client as client:
IF = InputFlowLockTimeDatetime(client, lock_time_str)
client.set_input_flow(IF.get())
btc.sign_tx(
client,
session,
"Bitcoin",
[inp1],
[out1],
@ -1517,7 +1523,7 @@ def test_lock_time_datetime(client: Client, lock_time_str: str):
@pytest.mark.models("core", reason="Cannot test layouts on T1")
def test_information(client: Client):
def test_information(session: Session):
# input tx: 0dac366fd8a67b2a89fbb0d31086e7acded7a5bbf9ef9daa935bc873229ef5b5
inp1 = messages.TxInputType(
@ -1534,12 +1540,12 @@ def test_information(client: Client):
script_type=messages.OutputScriptType.PAYTOADDRESS,
)
with client:
with session.client as client:
IF = InputFlowSignTxInformation(client)
client.set_input_flow(IF.get())
btc.sign_tx(
client,
session,
"Bitcoin",
[inp1],
[out1],
@ -1548,7 +1554,7 @@ def test_information(client: Client):
@pytest.mark.models("core", reason="Cannot test layouts on T1")
def test_information_mixed(client: Client):
def test_information_mixed(session: Session):
inp1 = messages.TxInputType(
address_n=parse_path("m/44h/1h/0h/0/0"), # mvbu1Gdy8SUjTenqerxUaZyYjmveZvt33q
amount=31_000_000,
@ -1569,12 +1575,12 @@ def test_information_mixed(client: Client):
script_type=messages.OutputScriptType.PAYTOADDRESS,
)
with client:
with session.client as client:
IF = InputFlowSignTxInformationMixed(client)
client.set_input_flow(IF.get())
btc.sign_tx(
client,
session,
"Testnet",
[inp1, inp2],
[out1],
@ -1583,7 +1589,7 @@ def test_information_mixed(client: Client):
@pytest.mark.models("core", reason="Cannot test layouts on T1")
def test_information_cancel(client: Client):
def test_information_cancel(session: Session):
# input tx: 0dac366fd8a67b2a89fbb0d31086e7acded7a5bbf9ef9daa935bc873229ef5b5
inp1 = messages.TxInputType(
@ -1600,12 +1606,12 @@ def test_information_cancel(client: Client):
script_type=messages.OutputScriptType.PAYTOADDRESS,
)
with client, pytest.raises(Cancelled):
with session.client as client, pytest.raises(Cancelled):
IF = InputFlowSignTxInformationCancel(client)
client.set_input_flow(IF.get())
btc.sign_tx(
client,
session,
"Bitcoin",
[inp1],
[out1],
@ -1618,7 +1624,7 @@ def test_information_cancel(client: Client):
skip="mercury",
reason="Cannot test layouts on T1, not implemented in mercury UI",
)
def test_information_replacement(client: Client):
def test_information_replacement(session: Session):
# Use the change output and an external output to bump the fee.
# Originally fee was 3780, now 108060 (94280 from change and 10000 from external).
@ -1650,12 +1656,12 @@ def test_information_replacement(client: Client):
orig_index=0,
)
with client:
with session.client as client:
IF = InputFlowSignTxInformationReplacement(client)
client.set_input_flow(IF.get())
btc.sign_tx(
client,
session,
"Testnet",
[inp1, inp2],
[out1],

View File

@ -17,7 +17,7 @@
import pytest
from trezorlib import btc, messages
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.debuglink import SessionDebugWrapper as Session
from trezorlib.tools import parse_path
from ...tx_cache import TxCache
@ -42,7 +42,7 @@ VECTORS = ( # amount_unit
@pytest.mark.parametrize("amount_unit", VECTORS)
def test_signtx_testnet(client: Client, amount_unit):
def test_signtx_testnet(session: Session, amount_unit):
inp1 = messages.TxInputType(
# tb1qajr3a3y5uz27lkxrmn7ck8lp22dgytvagr5nqy
address_n=parse_path("m/84h/1h/0h/0/87"),
@ -61,9 +61,9 @@ def test_signtx_testnet(client: Client, amount_unit):
script_type=messages.OutputScriptType.PAYTOADDRESS,
amount=100_000 - 40_000 - 10_000,
)
with client:
with session:
_, serialized_tx = btc.sign_tx(
client,
session,
"Testnet",
[inp1],
[out1, out2],
@ -79,7 +79,7 @@ def test_signtx_testnet(client: Client, amount_unit):
@pytest.mark.parametrize("amount_unit", VECTORS)
def test_signtx_btc(client: Client, amount_unit):
def test_signtx_btc(session: Session, amount_unit):
# input tx: 0dac366fd8a67b2a89fbb0d31086e7acded7a5bbf9ef9daa935bc873229ef5b5
inp1 = messages.TxInputType(
@ -95,9 +95,9 @@ def test_signtx_btc(client: Client, amount_unit):
script_type=messages.OutputScriptType.PAYTOADDRESS,
)
with client:
with session:
_, serialized_tx = btc.sign_tx(
client,
session,
"Bitcoin",
[inp1],
[out1],

View File

@ -17,7 +17,7 @@
import pytest
from trezorlib import btc, device, messages, models
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.debuglink import SessionDebugWrapper as Session
from trezorlib.exceptions import TrezorFailure
from trezorlib.messages import SafetyCheckLevel
from trezorlib.tools import parse_path
@ -82,7 +82,7 @@ TXHASH_1010b2 = bytes.fromhex(
@pytest.mark.models("core")
def test_p2pkh_presigned(client: Client):
def test_p2pkh_presigned(session: Session):
inp1 = messages.TxInputType(
# mvbu1Gdy8SUjTenqerxUaZyYjmveZvt33q
address_n=parse_path("m/44h/1h/0h/0/0"),
@ -142,9 +142,9 @@ def test_p2pkh_presigned(client: Client):
)
# Test with first input as pre-signed external.
with client:
with session:
_, serialized_tx = btc.sign_tx(
client,
session,
"Testnet",
[inp1ext, inp2],
[out1, out2],
@ -155,9 +155,9 @@ def test_p2pkh_presigned(client: Client):
assert serialized_tx.hex() == expected_tx
# Test with second input as pre-signed external.
with client:
with session:
_, serialized_tx = btc.sign_tx(
client,
session,
"Testnet",
[inp1, inp2ext],
[out1, out2],
@ -170,7 +170,7 @@ def test_p2pkh_presigned(client: Client):
inp2ext.script_sig[10] ^= 1
with pytest.raises(TrezorFailure, match="Invalid signature"):
_, serialized_tx = btc.sign_tx(
client,
session,
"Testnet",
[inp1, inp2ext],
[out1, out2],
@ -179,7 +179,7 @@ def test_p2pkh_presigned(client: Client):
@pytest.mark.models("core")
def test_p2wpkh_in_p2sh_presigned(client: Client):
def test_p2wpkh_in_p2sh_presigned(session: Session):
inp1 = messages.TxInputType(
# 2N1LGaGg836mqSQqiuUBLfcyGBhyZbremDX
amount=123_456_789,
@ -216,20 +216,20 @@ def test_p2wpkh_in_p2sh_presigned(client: Client):
script_type=messages.OutputScriptType.PAYTOADDRESS,
)
with client:
client.set_expected_responses(
with session:
session.set_expected_responses(
[
request_input(0),
request_input(1),
request_output(0),
messages.ButtonRequest(code=B.ConfirmOutput),
(is_core(client), messages.ButtonRequest(code=B.ConfirmOutput)),
(is_core(session), messages.ButtonRequest(code=B.ConfirmOutput)),
request_output(1),
messages.ButtonRequest(code=B.ConfirmOutput),
(is_core(client), messages.ButtonRequest(code=B.ConfirmOutput)),
(is_core(session), messages.ButtonRequest(code=B.ConfirmOutput)),
request_output(2),
messages.ButtonRequest(code=B.ConfirmOutput),
(is_core(client), messages.ButtonRequest(code=B.ConfirmOutput)),
(is_core(session), messages.ButtonRequest(code=B.ConfirmOutput)),
messages.ButtonRequest(code=B.SignTx),
request_input(0),
request_meta(TXHASH_20912f),
@ -252,7 +252,7 @@ def test_p2wpkh_in_p2sh_presigned(client: Client):
]
)
_, serialized_tx = btc.sign_tx(
client,
session,
"Testnet",
[inp1, inp2],
[out1, out2, out3],
@ -267,20 +267,20 @@ def test_p2wpkh_in_p2sh_presigned(client: Client):
# Test corrupted script hash in scriptsig.
inp1.script_sig[10] ^= 1
with client:
client.set_expected_responses(
with session:
session.set_expected_responses(
[
request_input(0),
request_input(1),
request_output(0),
messages.ButtonRequest(code=B.ConfirmOutput),
(is_core(client), messages.ButtonRequest(code=B.ConfirmOutput)),
(is_core(session), messages.ButtonRequest(code=B.ConfirmOutput)),
request_output(1),
messages.ButtonRequest(code=B.ConfirmOutput),
(is_core(client), messages.ButtonRequest(code=B.ConfirmOutput)),
(is_core(session), messages.ButtonRequest(code=B.ConfirmOutput)),
request_output(2),
messages.ButtonRequest(code=B.ConfirmOutput),
(is_core(client), messages.ButtonRequest(code=B.ConfirmOutput)),
(is_core(session), messages.ButtonRequest(code=B.ConfirmOutput)),
messages.ButtonRequest(code=B.SignTx),
request_input(0),
request_meta(TXHASH_20912f),
@ -293,7 +293,7 @@ def test_p2wpkh_in_p2sh_presigned(client: Client):
with pytest.raises(TrezorFailure, match="Invalid public key hash"):
btc.sign_tx(
client,
session,
"Testnet",
[inp1, inp2],
[out1, out2, out3],
@ -302,7 +302,7 @@ def test_p2wpkh_in_p2sh_presigned(client: Client):
@pytest.mark.models("core")
def test_p2wpkh_presigned(client: Client):
def test_p2wpkh_presigned(session: Session):
inp1 = messages.TxInputType(
# tb1qkvwu9g3k2pdxewfqr7syz89r3gj557l3uuf9r9
address_n=parse_path("m/84h/1h/0h/0/0"),
@ -339,9 +339,9 @@ def test_p2wpkh_presigned(client: Client):
)
# Test with second input as pre-signed external.
with client:
with session:
_, serialized_tx = btc.sign_tx(
client,
session,
"Testnet",
[inp1, inp2],
[out1, out2],
@ -358,7 +358,7 @@ def test_p2wpkh_presigned(client: Client):
inp2.witness[10] ^= 1
with pytest.raises(TrezorFailure, match="Invalid signature"):
btc.sign_tx(
client,
session,
"Testnet",
[inp1, inp2],
[out1, out2],
@ -367,7 +367,7 @@ def test_p2wpkh_presigned(client: Client):
@pytest.mark.models("core")
def test_p2wsh_external_presigned(client: Client):
def test_p2wsh_external_presigned(session: Session):
inp1 = messages.TxInputType(
address_n=parse_path("m/84h/1h/0h/0/0"),
amount=10_000,
@ -399,14 +399,14 @@ def test_p2wsh_external_presigned(client: Client):
script_type=messages.OutputScriptType.PAYTOADDRESS,
)
with client:
client.set_expected_responses(
with session:
session.set_expected_responses(
[
request_input(0),
request_input(1),
request_output(0),
messages.ButtonRequest(code=B.ConfirmOutput),
(is_core(client), messages.ButtonRequest(code=B.ConfirmOutput)),
(is_core(session), messages.ButtonRequest(code=B.ConfirmOutput)),
messages.ButtonRequest(code=B.SignTx),
request_input(0),
request_meta(TXHASH_ec16dc),
@ -429,7 +429,7 @@ def test_p2wsh_external_presigned(client: Client):
)
_, serialized_tx = btc.sign_tx(
client,
session,
"Testnet",
[inp1, inp2],
[out1],
@ -444,14 +444,14 @@ def test_p2wsh_external_presigned(client: Client):
# Test corrupted signature in witness.
inp2.witness[10] ^= 1
with client:
client.set_expected_responses(
with session:
session.set_expected_responses(
[
request_input(0),
request_input(1),
request_output(0),
messages.ButtonRequest(code=B.ConfirmOutput),
(is_core(client), messages.ButtonRequest(code=B.ConfirmOutput)),
(is_core(session), messages.ButtonRequest(code=B.ConfirmOutput)),
messages.ButtonRequest(code=B.SignTx),
request_input(0),
request_meta(TXHASH_ec16dc),
@ -470,12 +470,12 @@ def test_p2wsh_external_presigned(client: Client):
with pytest.raises(TrezorFailure, match="Invalid signature"):
btc.sign_tx(
client, "Testnet", [inp1, inp2], [out1], prev_txes=TX_CACHE_TESTNET
session, "Testnet", [inp1, inp2], [out1], prev_txes=TX_CACHE_TESTNET
)
@pytest.mark.models("core")
def test_p2tr_external_presigned(client: Client):
def test_p2tr_external_presigned(session: Session):
inp1 = messages.TxInputType(
# tb1p8tvmvsvhsee73rhym86wt435qrqm92psfsyhy6a3n5gw455znnpqm8wald
address_n=parse_path("m/86h/1h/0h/0/1"),
@ -509,14 +509,14 @@ def test_p2tr_external_presigned(client: Client):
amount=4_600,
script_type=messages.OutputScriptType.PAYTOTAPROOT,
)
with client:
client.set_expected_responses(
with session:
session.set_expected_responses(
[
request_input(0),
request_input(1),
request_output(0),
messages.ButtonRequest(code=B.ConfirmOutput),
(is_core(client), messages.ButtonRequest(code=B.ConfirmOutput)),
(is_core(session), messages.ButtonRequest(code=B.ConfirmOutput)),
request_output(1),
messages.ButtonRequest(code=B.SignTx),
request_input(1),
@ -530,7 +530,7 @@ def test_p2tr_external_presigned(client: Client):
]
)
_, serialized_tx = btc.sign_tx(
client, "Testnet", [inp1, inp2], [out1, out2], prev_txes=TX_CACHE_TESTNET
session, "Testnet", [inp1, inp2], [out1, out2], prev_txes=TX_CACHE_TESTNET
)
assert_tx_matches(
@ -541,14 +541,14 @@ def test_p2tr_external_presigned(client: Client):
# Test corrupted signature in witness.
inp2.witness[10] ^= 1
with client:
client.set_expected_responses(
with session:
session.set_expected_responses(
[
request_input(0),
request_input(1),
request_output(0),
messages.ButtonRequest(code=B.ConfirmOutput),
(is_core(client), messages.ButtonRequest(code=B.ConfirmOutput)),
(is_core(session), messages.ButtonRequest(code=B.ConfirmOutput)),
request_output(1),
messages.ButtonRequest(code=B.SignTx),
request_input(1),
@ -558,7 +558,7 @@ def test_p2tr_external_presigned(client: Client):
with pytest.raises(TrezorFailure, match="Invalid signature"):
btc.sign_tx(
client,
session,
"Testnet",
[inp1, inp2],
[out1, out2],
@ -567,18 +567,18 @@ def test_p2tr_external_presigned(client: Client):
@pytest.mark.models("core")
def test_p2pkh_with_proof(client: Client):
def test_p2pkh_with_proof(session: Session):
# TODO
pass
@pytest.mark.models("core")
def test_p2wpkh_in_p2sh_with_proof(client: Client):
def test_p2wpkh_in_p2sh_with_proof(session: Session):
# TODO
pass
def test_p2wpkh_with_proof(client: Client):
def test_p2wpkh_with_proof(session: Session):
inp1 = messages.TxInputType(
# seed "alcohol woman abuse must during monitor noble actual mixed trade anger aisle"
# 84'/1'/0'/0/0
@ -610,18 +610,18 @@ def test_p2wpkh_with_proof(client: Client):
script_type=messages.OutputScriptType.PAYTOADDRESS,
)
with client:
is_t1 = client.model is models.T1B1
client.set_expected_responses(
with session:
is_t1 = session.model is models.T1B1
session.set_expected_responses(
[
request_input(0),
request_input(1),
request_output(0),
messages.ButtonRequest(code=B.ConfirmOutput),
(is_core(client), messages.ButtonRequest(code=B.ConfirmOutput)),
(is_core(session), messages.ButtonRequest(code=B.ConfirmOutput)),
request_output(1),
messages.ButtonRequest(code=B.ConfirmOutput),
(is_core(client), messages.ButtonRequest(code=B.ConfirmOutput)),
(is_core(session), messages.ButtonRequest(code=B.ConfirmOutput)),
messages.ButtonRequest(code=B.SignTx),
request_input(0),
request_meta(TXHASH_e5b7e2),
@ -643,7 +643,7 @@ def test_p2wpkh_with_proof(client: Client):
]
)
_, serialized_tx = btc.sign_tx(
client,
session,
"Testnet",
[inp1, inp2],
[out1, out2],
@ -660,7 +660,7 @@ def test_p2wpkh_with_proof(client: Client):
inp1.ownership_proof[10] ^= 1
with pytest.raises(TrezorFailure, match="Invalid signature|Invalid external input"):
btc.sign_tx(
client,
session,
"Testnet",
[inp1, inp2],
[out1, out2],
@ -671,7 +671,7 @@ def test_p2wpkh_with_proof(client: Client):
@pytest.mark.setup_client(
mnemonic="abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about"
)
def test_p2tr_with_proof(client: Client):
def test_p2tr_with_proof(session: Session):
# Resulting TXID 48ec6dc7bb772ff18cbce0135fedda7c0e85212c7b2f85a5d0cc7a917d77c48a
inp1 = messages.TxInputType(
@ -703,15 +703,15 @@ def test_p2tr_with_proof(client: Client):
script_type=messages.OutputScriptType.PAYTOADDRESS,
)
with client:
is_t1 = client.model is models.T1B1
client.set_expected_responses(
with session:
is_t1 = session.model is models.T1B1
session.set_expected_responses(
[
request_input(0),
request_input(1),
request_output(0),
messages.ButtonRequest(code=B.ConfirmOutput),
(is_core(client), messages.ButtonRequest(code=B.ConfirmOutput)),
(is_core(session), messages.ButtonRequest(code=B.ConfirmOutput)),
messages.ButtonRequest(code=B.SignTx),
request_input(0),
request_input(1),
@ -722,7 +722,7 @@ def test_p2tr_with_proof(client: Client):
]
)
_, serialized_tx = btc.sign_tx(
client, "Testnet", [inp1, inp2], [out1], prev_txes=TX_CACHE_TESTNET
session, "Testnet", [inp1, inp2], [out1], prev_txes=TX_CACHE_TESTNET
)
# Transaction does not exist on the blockchain, not using assert_tx_matches()
@ -736,10 +736,12 @@ def test_p2tr_with_proof(client: Client):
# Test corrupted ownership proof.
inp1.ownership_proof[10] ^= 1
with pytest.raises(TrezorFailure, match="Invalid signature|Invalid external input"):
btc.sign_tx(client, "Testnet", [inp1, inp2], [out1], prev_txes=TX_CACHE_TESTNET)
btc.sign_tx(
session, "Testnet", [inp1, inp2], [out1], prev_txes=TX_CACHE_TESTNET
)
def test_p2wpkh_with_false_proof(client: Client):
def test_p2wpkh_with_false_proof(session: Session):
inp1 = messages.TxInputType(
# tb1qkvwu9g3k2pdxewfqr7syz89r3gj557l3uuf9r9
address_n=parse_path("m/84h/1h/0h/0/0"),
@ -768,8 +770,8 @@ def test_p2wpkh_with_false_proof(client: Client):
script_type=messages.OutputScriptType.PAYTOWITNESS,
)
with client:
client.set_expected_responses(
with session:
session.set_expected_responses(
[
request_input(0),
request_input(1),
@ -779,7 +781,7 @@ def test_p2wpkh_with_false_proof(client: Client):
with pytest.raises(TrezorFailure, match="Invalid external input"):
btc.sign_tx(
client,
session,
"Testnet",
[inp1, inp2],
[out1],
@ -787,7 +789,7 @@ def test_p2wpkh_with_false_proof(client: Client):
)
def test_p2tr_external_unverified(client: Client):
def test_p2tr_external_unverified(session: Session):
inp1 = messages.TxInputType(
# tb1pswrqtykue8r89t9u4rprjs0gt4qzkdfuursfnvqaa3f2yql07zmq8s8a5u
address_n=parse_path("m/86h/1h/0h/0/0"),
@ -823,13 +825,13 @@ def test_p2tr_external_unverified(client: Client):
# Unverified external inputs should be rejected when safety checks are enabled.
with pytest.raises(TrezorFailure, match="[Ee]xternal input"):
btc.sign_tx(
client, "Testnet", [inp1, inp2], [out1, out2], prev_txes=TX_CACHE_TESTNET
session, "Testnet", [inp1, inp2], [out1, out2], prev_txes=TX_CACHE_TESTNET
)
# Signing should succeed after disabling safety checks.
device.apply_settings(client, safety_checks=SafetyCheckLevel.PromptTemporarily)
device.apply_settings(session, safety_checks=SafetyCheckLevel.PromptTemporarily)
_, serialized_tx = btc.sign_tx(
client, "Testnet", [inp1, inp2], [out1, out2], prev_txes=TX_CACHE_TESTNET
session, "Testnet", [inp1, inp2], [out1, out2], prev_txes=TX_CACHE_TESTNET
)
# Second witness is missing from the serialized transaction.
@ -840,7 +842,7 @@ def test_p2tr_external_unverified(client: Client):
)
def test_p2wpkh_external_unverified(client: Client):
def test_p2wpkh_external_unverified(session: Session):
inp1 = messages.TxInputType(
# tb1qkvwu9g3k2pdxewfqr7syz89r3gj557l3uuf9r9
address_n=parse_path("m/84h/1h/0h/0/0"),
@ -875,13 +877,13 @@ def test_p2wpkh_external_unverified(client: Client):
# Unverified external inputs should be rejected when safety checks are enabled.
with pytest.raises(TrezorFailure, match="[Ee]xternal input"):
btc.sign_tx(
client, "Testnet", [inp1, inp2], [out1, out2], prev_txes=TX_CACHE_TESTNET
session, "Testnet", [inp1, inp2], [out1, out2], prev_txes=TX_CACHE_TESTNET
)
# Signing should succeed after disabling safety checks.
device.apply_settings(client, safety_checks=SafetyCheckLevel.PromptTemporarily)
device.apply_settings(session, safety_checks=SafetyCheckLevel.PromptTemporarily)
_, serialized_tx = btc.sign_tx(
client, "Testnet", [inp1, inp2], [out1, out2], prev_txes=TX_CACHE_TESTNET
session, "Testnet", [inp1, inp2], [out1, out2], prev_txes=TX_CACHE_TESTNET
)
# Second witness is missing from the serialized transaction.

View File

@ -17,7 +17,7 @@
import pytest
from trezorlib import btc, device, messages
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.debuglink import SessionDebugWrapper as Session
from trezorlib.exceptions import TrezorFailure
from trezorlib.tools import H_, parse_path
@ -36,7 +36,7 @@ PREV_TXES = {PREV_HASH: PREV_TX}
# Litecoin does not have strong replay protection using SIGHASH_FORKID,
# spending from Bitcoin path should fail.
@pytest.mark.altcoin
def test_invalid_path_fail(client: Client):
def test_invalid_path_fail(session: Session):
inp1 = messages.TxInputType(
address_n=parse_path("m/44h/0h/0h/0/0"),
amount=390_000,
@ -52,7 +52,7 @@ def test_invalid_path_fail(client: Client):
)
with pytest.raises(TrezorFailure) as exc:
btc.sign_tx(client, "Litecoin", [inp1], [out1], prev_txes=PREV_TXES)
btc.sign_tx(session, "Litecoin", [inp1], [out1], prev_txes=PREV_TXES)
assert exc.value.code == messages.FailureType.DataError
assert exc.value.message.endswith("Forbidden key path")
@ -61,7 +61,7 @@ def test_invalid_path_fail(client: Client):
# Litecoin does not have strong replay protection using SIGHASH_FORKID, but
# spending from Bitcoin path should pass with safety checks set to prompt.
@pytest.mark.altcoin
def test_invalid_path_prompt(client: Client):
def test_invalid_path_prompt(session: Session):
inp1 = messages.TxInputType(
address_n=parse_path("m/44h/0h/0h/0/0"),
amount=390_000,
@ -77,21 +77,21 @@ def test_invalid_path_prompt(client: Client):
)
device.apply_settings(
client, safety_checks=messages.SafetyCheckLevel.PromptTemporarily
session, safety_checks=messages.SafetyCheckLevel.PromptTemporarily
)
with client:
if is_core(client):
with session.client as client:
if is_core(session):
IF = InputFlowConfirmAllWarnings(client)
client.set_input_flow(IF.get())
btc.sign_tx(client, "Litecoin", [inp1], [out1], prev_txes=PREV_TXES)
btc.sign_tx(session, "Litecoin", [inp1], [out1], prev_txes=PREV_TXES)
# Bcash does have strong replay protection using SIGHASH_FORKID,
# spending from Bitcoin path should work.
@pytest.mark.altcoin
def test_invalid_path_pass_forkid(client: Client):
def test_invalid_path_pass_forkid(session: Session):
inp1 = messages.TxInputType(
address_n=parse_path("m/44h/0h/0h/0/0"),
amount=390_000,
@ -106,32 +106,32 @@ def test_invalid_path_pass_forkid(client: Client):
script_type=messages.OutputScriptType.PAYTOADDRESS,
)
with client:
if is_core(client):
with session.client as client:
if is_core(session):
IF = InputFlowConfirmAllWarnings(client)
client.set_input_flow(IF.get())
btc.sign_tx(client, "Bcash", [inp1], [out1], prev_txes=PREV_TXES)
btc.sign_tx(session, "Bcash", [inp1], [out1], prev_txes=PREV_TXES)
def test_attack_path_segwit(client: Client):
def test_attack_path_segwit(session: Session):
# Scenario: The attacker falsely claims that the transaction uses Testnet paths to
# avoid the path warning dialog, but in step6_sign_segwit_inputs() uses Bitcoin paths
# to get a valid signature.
device.apply_settings(
client, safety_checks=messages.SafetyCheckLevel.PromptTemporarily
session, safety_checks=messages.SafetyCheckLevel.PromptTemporarily
)
# Generate keys
address_a = btc.get_address(
client,
session,
"Testnet",
parse_path("m/84h/0h/0h/0/0"),
script_type=messages.InputScriptType.SPENDWITNESS,
)
address_b = btc.get_address(
client,
session,
"Testnet",
parse_path("m/84h/0h/1h/0/1"),
script_type=messages.InputScriptType.SPENDWITNESS,
@ -178,15 +178,15 @@ def test_attack_path_segwit(client: Client):
return msg
with client:
client.set_filter(messages.TxAck, attack_processor)
with session:
session.set_filter(messages.TxAck, attack_processor)
with pytest.raises(TrezorFailure):
btc.sign_tx(
client, "Testnet", [inp1, inp2], [out1], prev_txes={prev_hash: prev_tx}
session, "Testnet", [inp1, inp2], [out1], prev_txes={prev_hash: prev_tx}
)
def test_invalid_path_fail_asap(client: Client):
def test_invalid_path_fail_asap(session: Session):
inp1 = messages.TxInputType(
address_n=parse_path("m/0"),
amount=1_000_000,
@ -202,14 +202,14 @@ def test_invalid_path_fail_asap(client: Client):
script_type=messages.OutputScriptType.PAYTOWITNESS,
)
with client:
client.set_expected_responses(
with session:
session.set_expected_responses(
[
request_input(0),
messages.Failure(code=messages.FailureType.DataError),
]
)
try:
btc.sign_tx(client, "Testnet", [inp1], [out1])
btc.sign_tx(session, "Testnet", [inp1], [out1])
except TrezorFailure:
pass

View File

@ -15,7 +15,7 @@
# If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.
from trezorlib import btc, messages
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.debuglink import SessionDebugWrapper as Session
from trezorlib.tools import parse_path
from ...tx_cache import TxCache
@ -34,7 +34,7 @@ TXHASH_cf52d7 = bytes.fromhex(
)
def test_non_segwit_segwit_inputs(client: Client):
def test_non_segwit_segwit_inputs(session: Session):
# First is non-segwit, second is segwit.
inp1 = messages.TxInputType(
@ -58,9 +58,9 @@ def test_non_segwit_segwit_inputs(client: Client):
script_type=messages.OutputScriptType.PAYTOADDRESS,
)
with client:
with session:
signatures, serialized_tx = btc.sign_tx(
client, "Testnet", [inp1, inp2], [out1], prev_txes=TX_API
session, "Testnet", [inp1, inp2], [out1], prev_txes=TX_API
)
assert len(signatures) == 2
@ -71,7 +71,7 @@ def test_non_segwit_segwit_inputs(client: Client):
)
def test_segwit_non_segwit_inputs(client: Client):
def test_segwit_non_segwit_inputs(session: Session):
# First is segwit, second is non-segwit.
inp1 = messages.TxInputType(
@ -94,9 +94,9 @@ def test_segwit_non_segwit_inputs(client: Client):
script_type=messages.OutputScriptType.PAYTOADDRESS,
)
with client:
with session:
signatures, serialized_tx = btc.sign_tx(
client, "Testnet", [inp1, inp2], [out1], prev_txes=TX_API
session, "Testnet", [inp1, inp2], [out1], prev_txes=TX_API
)
assert len(signatures) == 2
@ -107,7 +107,7 @@ def test_segwit_non_segwit_inputs(client: Client):
)
def test_segwit_non_segwit_segwit_inputs(client: Client):
def test_segwit_non_segwit_segwit_inputs(session: Session):
# First is segwit, second is non-segwit and third is segwit again.
inp1 = messages.TxInputType(
@ -138,9 +138,9 @@ def test_segwit_non_segwit_segwit_inputs(client: Client):
script_type=messages.OutputScriptType.PAYTOADDRESS,
)
with client:
with session:
signatures, serialized_tx = btc.sign_tx(
client, "Testnet", [inp1, inp2, inp3], [out1], prev_txes=TX_API
session, "Testnet", [inp1, inp2, inp3], [out1], prev_txes=TX_API
)
assert len(signatures) == 3
@ -151,7 +151,7 @@ def test_segwit_non_segwit_segwit_inputs(client: Client):
)
def test_non_segwit_segwit_non_segwit_inputs(client: Client):
def test_non_segwit_segwit_non_segwit_inputs(session: Session):
# First is non-segwit, second is segwit and third is non-segwit again.
inp1 = messages.TxInputType(
@ -180,9 +180,9 @@ def test_non_segwit_segwit_non_segwit_inputs(client: Client):
script_type=messages.OutputScriptType.PAYTOADDRESS,
)
with client:
with session:
signatures, serialized_tx = btc.sign_tx(
client, "Testnet", [inp1, inp2, inp3], [out1], prev_txes=TX_API
session, "Testnet", [inp1, inp2, inp3], [out1], prev_txes=TX_API
)
assert len(signatures) == 3

View File

@ -18,8 +18,8 @@ from collections import namedtuple
import pytest
from trezorlib import btc, messages, misc
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib import btc, messages, misc, models
from trezorlib.debuglink import SessionDebugWrapper as Session
from trezorlib.exceptions import TrezorFailure
from trezorlib.tools import parse_path
@ -138,7 +138,7 @@ SERIALIZED_TX = "01000000000101e29305e85821ea86f2bca1fcfe45e7cb0c8de87b612479ee6
case("out12", (PaymentRequestParams([1, 2], [], get_nonce=True),)),
),
)
def test_payment_request(client: Client, payment_request_params):
def test_payment_request(session: Session, payment_request_params):
for txo in outputs:
txo.payment_req_index = None
@ -148,10 +148,10 @@ def test_payment_request(client: Client, payment_request_params):
for txo_index in params.txo_indices:
outputs[txo_index].payment_req_index = i
request_outputs.append(outputs[txo_index])
nonce = misc.get_nonce(client) if params.get_nonce else None
nonce = misc.get_nonce(session) if params.get_nonce else None
payment_reqs.append(
make_payment_request(
client,
session,
recipient_name="trezor.io",
outputs=request_outputs,
change_addresses=["tb1qkvwu9g3k2pdxewfqr7syz89r3gj557l3uuf9r9"],
@ -161,7 +161,7 @@ def test_payment_request(client: Client, payment_request_params):
)
_, serialized_tx = btc.sign_tx(
client,
session,
"Testnet",
inputs,
outputs,
@ -174,7 +174,7 @@ def test_payment_request(client: Client, payment_request_params):
# Ensure that the nonce has been invalidated.
with pytest.raises(TrezorFailure, match="Invalid nonce in payment request"):
btc.sign_tx(
client,
session,
"Testnet",
inputs,
outputs,
@ -184,15 +184,18 @@ def test_payment_request(client: Client, payment_request_params):
@pytest.mark.models(skip="safe3")
def test_payment_request_details(client: Client):
def test_payment_request_details(session: Session):
if session.model is models.T2B1:
pytest.skip("Details not implemented on T2B1")
# Test that payment request details are shown when requested.
outputs[0].payment_req_index = 0
outputs[1].payment_req_index = 0
outputs[2].payment_req_index = None
nonce = misc.get_nonce(client)
nonce = misc.get_nonce(session)
payment_reqs = [
make_payment_request(
client,
session,
recipient_name="trezor.io",
outputs=outputs[:2],
memos=[TextMemo("Invoice #87654321.")],
@ -200,12 +203,12 @@ def test_payment_request_details(client: Client):
)
]
with client:
with session.client as client:
IF = InputFlowPaymentRequestDetails(client, outputs)
client.set_input_flow(IF.get())
_, serialized_tx = btc.sign_tx(
client,
session,
"Testnet",
inputs,
outputs,
@ -216,16 +219,16 @@ def test_payment_request_details(client: Client):
assert serialized_tx.hex() == SERIALIZED_TX
def test_payment_req_wrong_amount(client: Client):
def test_payment_req_wrong_amount(session: Session):
# Test wrong total amount in payment request.
outputs[0].payment_req_index = 0
outputs[1].payment_req_index = 0
outputs[2].payment_req_index = None
payment_req = make_payment_request(
client,
session,
recipient_name="trezor.io",
outputs=outputs[:2],
nonce=misc.get_nonce(client),
nonce=misc.get_nonce(session),
)
# Decrease the total amount of the payment request.
@ -233,7 +236,7 @@ def test_payment_req_wrong_amount(client: Client):
with pytest.raises(TrezorFailure, match="Invalid amount in payment request"):
btc.sign_tx(
client,
session,
"Testnet",
inputs,
outputs,
@ -242,18 +245,18 @@ def test_payment_req_wrong_amount(client: Client):
)
def test_payment_req_wrong_mac_refund(client: Client):
def test_payment_req_wrong_mac_refund(session: Session):
# Test wrong MAC in payment request memo.
memo = RefundMemo(parse_path("m/44h/1h/0h/1/0"))
outputs[0].payment_req_index = 0
outputs[1].payment_req_index = 0
outputs[2].payment_req_index = None
payment_req = make_payment_request(
client,
session,
recipient_name="trezor.io",
outputs=outputs[:2],
memos=[memo],
nonce=misc.get_nonce(client),
nonce=misc.get_nonce(session),
)
# Corrupt the MAC value.
@ -263,7 +266,7 @@ def test_payment_req_wrong_mac_refund(client: Client):
with pytest.raises(TrezorFailure, match="Invalid address MAC"):
btc.sign_tx(
client,
session,
"Testnet",
inputs,
outputs,
@ -274,7 +277,7 @@ def test_payment_req_wrong_mac_refund(client: Client):
@pytest.mark.altcoin
@pytest.mark.models("t2t1", reason="Dash not supported on Safe family")
def test_payment_req_wrong_mac_purchase(client: Client):
def test_payment_req_wrong_mac_purchase(session: Session):
# Test wrong MAC in payment request memo.
memo = CoinPurchaseMemo(
amount="22.34904 DASH",
@ -286,11 +289,11 @@ def test_payment_req_wrong_mac_purchase(client: Client):
outputs[1].payment_req_index = 0
outputs[2].payment_req_index = None
payment_req = make_payment_request(
client,
session,
recipient_name="trezor.io",
outputs=outputs[:2],
memos=[memo],
nonce=misc.get_nonce(client),
nonce=misc.get_nonce(session),
)
# Corrupt the MAC value.
@ -300,7 +303,7 @@ def test_payment_req_wrong_mac_purchase(client: Client):
with pytest.raises(TrezorFailure, match="Invalid address MAC"):
btc.sign_tx(
client,
session,
"Testnet",
inputs,
outputs,
@ -309,16 +312,16 @@ def test_payment_req_wrong_mac_purchase(client: Client):
)
def test_payment_req_wrong_output(client: Client):
def test_payment_req_wrong_output(session: Session):
# Test wrong output in payment request.
outputs[0].payment_req_index = 0
outputs[1].payment_req_index = 0
outputs[2].payment_req_index = None
payment_req = make_payment_request(
client,
session,
recipient_name="trezor.io",
outputs=outputs[:2],
nonce=misc.get_nonce(client),
nonce=misc.get_nonce(session),
)
# Use a different address in the second output.
@ -335,7 +338,7 @@ def test_payment_req_wrong_output(client: Client):
with pytest.raises(TrezorFailure, match="Invalid signature in payment request"):
btc.sign_tx(
client,
session,
"Testnet",
inputs,
fake_outputs,

View File

@ -5,7 +5,7 @@ from io import BytesIO
import pytest
from trezorlib import btc, messages, models, tools
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.debuglink import SessionDebugWrapper as Session
from trezorlib.exceptions import TrezorFailure
from ...common import is_core
@ -78,7 +78,7 @@ with_bad_prevhashes = pytest.mark.parametrize(
@with_bad_prevhashes
def test_invalid_prev_hash(client: Client, prev_hash):
def test_invalid_prev_hash(session: Session, prev_hash):
inp1 = messages.TxInputType(
address_n=tools.parse_path("m/44h/0h/0h/0/0"),
amount=123_456_789,
@ -93,12 +93,12 @@ def test_invalid_prev_hash(client: Client, prev_hash):
)
with pytest.raises(TrezorFailure) as e:
btc.sign_tx(client, "Testnet", [inp1], [out1], prev_txes={})
_check_error_message(prev_hash, client.model, e.value.message)
btc.sign_tx(session, "Testnet", [inp1], [out1], prev_txes={})
_check_error_message(prev_hash, session.model, e.value.message)
@with_bad_prevhashes
def test_invalid_prev_hash_attack(client: Client, prev_hash):
def test_invalid_prev_hash_attack(session: Session, prev_hash):
# prepare input with a valid prev-hash
inp1 = messages.TxInputType(
address_n=tools.parse_path("m/44h/0h/0h/0/0"),
@ -130,20 +130,20 @@ def test_invalid_prev_hash_attack(client: Client, prev_hash):
msg.tx.inputs[0].prev_hash = prev_hash
return msg
with client, pytest.raises(TrezorFailure) as e:
client.set_filter(messages.TxAck, attack_filter)
if is_core(client):
with session, session.client as client, pytest.raises(TrezorFailure) as e:
session.set_filter(messages.TxAck, attack_filter)
if is_core(session):
IF = InputFlowConfirmAllWarnings(client)
client.set_input_flow(IF.get())
btc.sign_tx(client, "Bitcoin", [inp1], [out1], prev_txes=PREV_TXES)
btc.sign_tx(session, "Bitcoin", [inp1], [out1], prev_txes=PREV_TXES)
# check that injection was performed
assert counter == 0
_check_error_message(prev_hash, client.model, e.value.message)
_check_error_message(prev_hash, session.model, e.value.message)
@with_bad_prevhashes
def test_invalid_prev_hash_in_prevtx(client: Client, prev_hash):
def test_invalid_prev_hash_in_prevtx(session: Session, prev_hash):
prev_tx = copy(PREV_TX)
# smoke check: replace prev_hash with all zeros, reserialize and hash, try to sign
@ -161,16 +161,16 @@ def test_invalid_prev_hash_in_prevtx(client: Client, prev_hash):
amount=99_000_000,
script_type=messages.OutputScriptType.PAYTOADDRESS,
)
btc.sign_tx(client, "Bitcoin", [inp0], [out1], prev_txes={tx_hash: prev_tx})
btc.sign_tx(session, "Bitcoin", [inp0], [out1], prev_txes={tx_hash: prev_tx})
# attack: replace prev_hash with an invalid value
prev_tx.inputs[0].prev_hash = prev_hash
tx_hash = hash_tx(serialize_tx(prev_tx))
inp0.prev_hash = tx_hash
with client, pytest.raises(TrezorFailure) as e:
if client.model is not models.T1B1:
with session, session.client as client, pytest.raises(TrezorFailure) as e:
if session.model is not models.T1B1:
IF = InputFlowConfirmAllWarnings(client)
client.set_input_flow(IF.get())
btc.sign_tx(client, "Bitcoin", [inp0], [out1], prev_txes={tx_hash: prev_tx})
_check_error_message(prev_hash, client.model, e.value.message)
btc.sign_tx(session, "Bitcoin", [inp0], [out1], prev_txes={tx_hash: prev_tx})
_check_error_message(prev_hash, session.model, e.value.message)

View File

@ -17,7 +17,7 @@
import pytest
from trezorlib import btc, messages
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.debuglink import SessionDebugWrapper as Session
from trezorlib.exceptions import TrezorFailure
from trezorlib.tools import parse_path
@ -90,7 +90,7 @@ TXHASH_8e4af7 = bytes.fromhex(
)
def test_p2pkh_fee_bump(client: Client):
def test_p2pkh_fee_bump(session: Session):
inp1 = messages.TxInputType(
address_n=parse_path("m/44h/0h/0h/0/4"),
amount=174_998,
@ -116,8 +116,8 @@ def test_p2pkh_fee_bump(client: Client):
orig_index=1,
)
with client:
client.set_expected_responses(
with session:
session.set_expected_responses(
[
request_input(0),
request_meta(TXHASH_50f6f1),
@ -132,7 +132,7 @@ def test_p2pkh_fee_bump(client: Client):
request_meta(TXHASH_beafc7),
request_input(0, TXHASH_beafc7),
request_output(0, TXHASH_beafc7),
(is_core(client), request_orig_input(0, TXHASH_50f6f1)),
(is_core(session), request_orig_input(0, TXHASH_50f6f1)),
request_orig_input(0, TXHASH_50f6f1),
request_orig_output(0, TXHASH_50f6f1),
request_orig_output(1, TXHASH_50f6f1),
@ -145,7 +145,7 @@ def test_p2pkh_fee_bump(client: Client):
]
)
_, serialized_tx = btc.sign_tx(
client,
session,
"Bitcoin",
[inp1],
[out1, out2],
@ -159,7 +159,7 @@ def test_p2pkh_fee_bump(client: Client):
)
def test_p2wpkh_op_return_fee_bump(client: Client):
def test_p2wpkh_op_return_fee_bump(session: Session):
# Original input.
inp1 = messages.TxInputType(
address_n=parse_path("m/84h/1h/1h/0/14"),
@ -190,9 +190,9 @@ def test_p2wpkh_op_return_fee_bump(client: Client):
orig_index=1,
)
with client:
with session:
_, serialized_tx = btc.sign_tx(
client,
session,
"Testnet",
[inp1],
[out1, out2],
@ -207,7 +207,7 @@ def test_p2wpkh_op_return_fee_bump(client: Client):
# txid 48bc29fc42a64b43d043b0b7b99b21aa39654234754608f791c60bcbd91a8e92
def test_p2tr_fee_bump(client: Client):
def test_p2tr_fee_bump(session: Session):
inp1 = messages.TxInputType(
# tb1p8tvmvsvhsee73rhym86wt435qrqm92psfsyhy6a3n5gw455znnpqm8wald
address_n=parse_path("m/86h/1h/0h/0/1"),
@ -243,8 +243,8 @@ def test_p2tr_fee_bump(client: Client):
orig_index=1,
script_type=messages.OutputScriptType.PAYTOTAPROOT,
)
with client:
client.set_expected_responses(
with session:
session.set_expected_responses(
[
request_input(0),
request_meta(TXHASH_8e4af7),
@ -269,7 +269,7 @@ def test_p2tr_fee_bump(client: Client):
]
)
_, serialized_tx = btc.sign_tx(
client, "Testnet", [inp1, inp2], [out1, out2], prev_txes=TX_CACHE_TESTNET
session, "Testnet", [inp1, inp2], [out1, out2], prev_txes=TX_CACHE_TESTNET
)
# Transaction does not exist on the blockchain, not using assert_tx_matches()
@ -281,7 +281,7 @@ def test_p2tr_fee_bump(client: Client):
)
def test_p2wpkh_finalize(client: Client):
def test_p2wpkh_finalize(session: Session):
# Original input with disabled RBF opt-in, i.e. we finalize the transaction.
inp1 = messages.TxInputType(
address_n=parse_path("m/84h/1h/0h/0/2"),
@ -312,8 +312,8 @@ def test_p2wpkh_finalize(client: Client):
orig_index=1,
)
with client:
client.set_expected_responses(
with session:
session.set_expected_responses(
[
request_input(0),
request_meta(TXHASH_70f987),
@ -339,7 +339,7 @@ def test_p2wpkh_finalize(client: Client):
]
)
_, serialized_tx = btc.sign_tx(
client,
session,
"Testnet",
[inp1],
[out1, out2],
@ -401,7 +401,7 @@ def test_p2wpkh_finalize(client: Client):
),
)
def test_p2wpkh_payjoin(
client, out1_amount, out2_amount, copayer_witness, fee_confirm, expected_tx
session, out1_amount, out2_amount, copayer_witness, fee_confirm, expected_tx
):
# Original input.
inp1 = messages.TxInputType(
@ -444,8 +444,8 @@ def test_p2wpkh_payjoin(
orig_index=1,
)
with client:
client.set_expected_responses(
with session:
session.set_expected_responses(
[
request_input(0),
request_meta(TXHASH_65b768),
@ -478,7 +478,7 @@ def test_p2wpkh_payjoin(
]
)
_, serialized_tx = btc.sign_tx(
client,
session,
"Testnet",
[inp1, inp2],
[out1, out2],
@ -489,7 +489,7 @@ def test_p2wpkh_payjoin(
assert serialized_tx.hex() == expected_tx
def test_p2wpkh_in_p2sh_remove_change(client: Client):
def test_p2wpkh_in_p2sh_remove_change(session: Session):
# Test fee bump with change-output removal. Originally fee was 3780, now 98060.
inp1 = messages.TxInputType(
@ -520,8 +520,8 @@ def test_p2wpkh_in_p2sh_remove_change(client: Client):
orig_index=0,
)
with client:
client.set_expected_responses(
with session:
session.set_expected_responses(
[
request_input(0),
request_meta(TXHASH_334cd7),
@ -553,7 +553,7 @@ def test_p2wpkh_in_p2sh_remove_change(client: Client):
]
)
_, serialized_tx = btc.sign_tx(
client,
session,
"Testnet",
[inp1, inp2],
[out1],
@ -567,7 +567,7 @@ def test_p2wpkh_in_p2sh_remove_change(client: Client):
)
def test_p2wpkh_in_p2sh_fee_bump_from_external(client: Client):
def test_p2wpkh_in_p2sh_fee_bump_from_external(session: Session):
# Use the change output and an external output to bump the fee.
# Originally fee was 3780, now 108060 (94280 from change and 10000 from external).
@ -599,8 +599,8 @@ def test_p2wpkh_in_p2sh_fee_bump_from_external(client: Client):
orig_index=0,
)
with client:
client.set_expected_responses(
with session:
session.set_expected_responses(
[
request_input(0),
request_meta(TXHASH_334cd7),
@ -634,7 +634,7 @@ def test_p2wpkh_in_p2sh_fee_bump_from_external(client: Client):
]
)
_, serialized_tx = btc.sign_tx(
client,
session,
"Testnet",
[inp1, inp2],
[out1],
@ -649,7 +649,7 @@ def test_p2wpkh_in_p2sh_fee_bump_from_external(client: Client):
@pytest.mark.models("core")
def test_tx_meld(client: Client):
def test_tx_meld(session: Session):
# Meld two original transactions into one, joining the change-outputs into a different one.
inp1 = messages.TxInputType(
@ -720,8 +720,8 @@ def test_tx_meld(client: Client):
script_type=messages.OutputScriptType.PAYTOP2SHWITNESS,
)
with client:
client.set_expected_responses(
with session:
session.set_expected_responses(
[
request_input(0),
request_meta(TXHASH_334cd7),
@ -785,7 +785,7 @@ def test_tx_meld(client: Client):
]
)
_, serialized_tx = btc.sign_tx(
client,
session,
"Testnet",
[inp1, inp2, inp3, inp4],
[out1, out2, out3],
@ -799,7 +799,7 @@ def test_tx_meld(client: Client):
)
def test_attack_steal_change(client: Client):
def test_attack_steal_change(session: Session):
# Attempt to steal amount equivalent to the change in the original transaction by
# hiding the fact that an output in the original transaction is a change-output.
@ -860,7 +860,7 @@ def test_attack_steal_change(client: Client):
TrezorFailure, match="Original output is missing change-output parameters"
):
btc.sign_tx(
client,
session,
"Testnet",
[inp1, inp2],
[out1, out2, out3],
@ -870,7 +870,7 @@ def test_attack_steal_change(client: Client):
@pytest.mark.models("core")
def test_attack_false_internal(client: Client):
def test_attack_false_internal(session: Session):
# Falsely claim that an external input is internal in the original transaction.
# If this were possible, it would allow an attacker to make it look like the
# user was spending more in the original than they actually were, making it
@ -914,7 +914,7 @@ def test_attack_false_internal(client: Client):
TrezorFailure, match="Original input does not match current input"
):
btc.sign_tx(
client,
session,
"Testnet",
[inp1, inp2],
[out1],
@ -922,7 +922,7 @@ def test_attack_false_internal(client: Client):
)
def test_attack_fake_int_input_amount(client: Client):
def test_attack_fake_int_input_amount(session: Session):
# Give a fake input amount for an original internal input while giving the correct
# amount for the replacement input. If an attacker could increase the amount of an
# internal input in the original transaction, then they could bump the fee of the
@ -968,7 +968,7 @@ def test_attack_fake_int_input_amount(client: Client):
TrezorFailure, match="Original input does not match current input"
):
btc.sign_tx(
client,
session,
"Bitcoin",
[inp1],
[out1, out2],
@ -977,7 +977,7 @@ def test_attack_fake_int_input_amount(client: Client):
@pytest.mark.models("core")
def test_attack_fake_ext_input_amount(client: Client):
def test_attack_fake_ext_input_amount(session: Session):
# Give a fake input amount for an original external input while giving the correct
# amount for the replacement input. If an attacker could decrease the amount of an
# external input in the original transaction, then they could steal the fee from
@ -1044,7 +1044,7 @@ def test_attack_fake_ext_input_amount(client: Client):
TrezorFailure, match="Original input does not match current input"
):
btc.sign_tx(
client,
session,
"Testnet",
[inp1, inp2],
[out1, out2],
@ -1052,7 +1052,7 @@ def test_attack_fake_ext_input_amount(client: Client):
)
def test_p2wpkh_invalid_signature(client: Client):
def test_p2wpkh_invalid_signature(session: Session):
# Ensure that transaction replacement fails when the original signature is invalid.
# Original input with disabled RBF opt-in, i.e. we finalize the transaction.
@ -1096,7 +1096,7 @@ def test_p2wpkh_invalid_signature(client: Client):
with pytest.raises(TrezorFailure, match="Invalid signature"):
btc.sign_tx(
client,
session,
"Testnet",
[inp1],
[out1, out2],
@ -1105,7 +1105,7 @@ def test_p2wpkh_invalid_signature(client: Client):
)
def test_p2tr_invalid_signature(client: Client):
def test_p2tr_invalid_signature(session: Session):
# Ensure that transaction replacement fails when the original signature is invalid.
inp1 = messages.TxInputType(
@ -1151,4 +1151,4 @@ def test_p2tr_invalid_signature(client: Client):
prev_txes = {TXHASH_8e4af7: prev_tx_invalid}
with pytest.raises(TrezorFailure, match="Invalid signature"):
btc.sign_tx(client, "Testnet", [inp1, inp2], [out1, out2], prev_txes=prev_txes)
btc.sign_tx(session, "Testnet", [inp1, inp2], [out1, out2], prev_txes=prev_txes)

View File

@ -17,7 +17,7 @@
import pytest
from trezorlib import btc, messages, models
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.debuglink import SessionDebugWrapper as Session
from trezorlib.exceptions import TrezorFailure
from trezorlib.tools import H_, parse_path
@ -47,7 +47,7 @@ TXHASH_e5040e = bytes.fromhex(
@pytest.mark.parametrize("chunkify", (True, False))
def test_send_p2sh(client: Client, chunkify: bool):
def test_send_p2sh(session: Session, chunkify: bool):
inp1 = messages.TxInputType(
address_n=parse_path("m/49h/1h/0h/1/0"),
# 2N1LGaGg836mqSQqiuUBLfcyGBhyZbremDX
@ -66,16 +66,16 @@ def test_send_p2sh(client: Client, chunkify: bool):
script_type=messages.OutputScriptType.PAYTOADDRESS,
amount=123_456_789 - 11_000 - 12_300_000,
)
with client:
client.set_expected_responses(
with session:
session.set_expected_responses(
[
request_input(0),
request_output(0),
messages.ButtonRequest(code=B.ConfirmOutput),
(is_core(client), messages.ButtonRequest(code=B.ConfirmOutput)),
(is_core(session), messages.ButtonRequest(code=B.ConfirmOutput)),
request_output(1),
messages.ButtonRequest(code=B.ConfirmOutput),
(is_core(client), messages.ButtonRequest(code=B.ConfirmOutput)),
(is_core(session), messages.ButtonRequest(code=B.ConfirmOutput)),
messages.ButtonRequest(code=B.SignTx),
request_input(0),
request_meta(TXHASH_20912f),
@ -90,7 +90,7 @@ def test_send_p2sh(client: Client, chunkify: bool):
]
)
_, serialized_tx = btc.sign_tx(
client,
session,
"Testnet",
[inp1],
[out1, out2],
@ -105,7 +105,7 @@ def test_send_p2sh(client: Client, chunkify: bool):
)
def test_send_p2sh_change(client: Client):
def test_send_p2sh_change(session: Session):
inp1 = messages.TxInputType(
address_n=parse_path("m/49h/1h/0h/1/0"),
# 2N1LGaGg836mqSQqiuUBLfcyGBhyZbremDX
@ -124,13 +124,13 @@ def test_send_p2sh_change(client: Client):
script_type=messages.OutputScriptType.PAYTOP2SHWITNESS,
amount=123_456_789 - 11_000 - 12_300_000,
)
with client:
client.set_expected_responses(
with session:
session.set_expected_responses(
[
request_input(0),
request_output(0),
messages.ButtonRequest(code=B.ConfirmOutput),
(is_core(client), messages.ButtonRequest(code=B.ConfirmOutput)),
(is_core(session), messages.ButtonRequest(code=B.ConfirmOutput)),
request_output(1),
messages.ButtonRequest(code=B.SignTx),
request_input(0),
@ -146,7 +146,7 @@ def test_send_p2sh_change(client: Client):
]
)
_, serialized_tx = btc.sign_tx(
client, "Testnet", [inp1], [out1, out2], prev_txes=TX_API_TESTNET
session, "Testnet", [inp1], [out1, out2], prev_txes=TX_API_TESTNET
)
# Transaction does not exist on the blockchain, not using assert_tx_matches()
@ -156,11 +156,11 @@ def test_send_p2sh_change(client: Client):
)
def test_testnet_segwit_big_amount(client: Client):
def test_testnet_segwit_big_amount(session: Session):
# This test is testing transaction with amount bigger than fits to uint32
address_n = parse_path("m/49h/1h/0h/0/0")
address = btc.get_address(
client,
session,
"Testnet",
address_n,
script_type=messages.InputScriptType.SPENDP2SHWITNESS,
@ -179,13 +179,13 @@ def test_testnet_segwit_big_amount(client: Client):
amount=2**32 + 1,
script_type=messages.OutputScriptType.PAYTOADDRESS,
)
with client:
client.set_expected_responses(
with session:
session.set_expected_responses(
[
request_input(0),
request_output(0),
messages.ButtonRequest(code=B.ConfirmOutput),
(is_core(client), messages.ButtonRequest(code=B.ConfirmOutput)),
(is_core(session), messages.ButtonRequest(code=B.ConfirmOutput)),
messages.ButtonRequest(code=B.SignTx),
request_input(0),
request_meta(prev_hash),
@ -198,7 +198,7 @@ def test_testnet_segwit_big_amount(client: Client):
]
)
_, serialized_tx = btc.sign_tx(
client, "Testnet", [inp1], [out1], prev_txes={prev_hash: prev_tx}
session, "Testnet", [inp1], [out1], prev_txes={prev_hash: prev_tx}
)
# Transaction does not exist on the blockchain, not using assert_tx_matches()
assert (
@ -208,12 +208,12 @@ def test_testnet_segwit_big_amount(client: Client):
@pytest.mark.multisig
def test_send_multisig_1(client: Client):
def test_send_multisig_1(session: Session):
# input: 338e2d02e0eaf8848e38925904e51546cf22e58db5b1860c4a0e72b69c56afe5
nodes = [
btc.get_public_node(
client, parse_path(f"m/49h/1h/{i}h"), coin_name="Testnet"
session, parse_path(f"m/49h/1h/{i}h"), coin_name="Testnet"
).node
for i in range(1, 4)
]
@ -241,7 +241,7 @@ def test_send_multisig_1(client: Client):
request_input(0),
request_output(0),
messages.ButtonRequest(code=B.ConfirmOutput),
(is_core(client), messages.ButtonRequest(code=B.ConfirmOutput)),
(is_core(session), messages.ButtonRequest(code=B.ConfirmOutput)),
messages.ButtonRequest(code=B.SignTx),
request_input(0),
request_meta(TXHASH_338e2d),
@ -254,10 +254,10 @@ def test_send_multisig_1(client: Client):
request_finished(),
]
with client:
client.set_expected_responses(expected_responses)
with session:
session.set_expected_responses(expected_responses)
signatures, _ = btc.sign_tx(
client, "Testnet", [inp1], [out1], prev_txes=TX_API_TESTNET
session, "Testnet", [inp1], [out1], prev_txes=TX_API_TESTNET
)
# store signature
@ -265,10 +265,10 @@ def test_send_multisig_1(client: Client):
# sign with third key
inp1.address_n[2] = H_(3)
with client:
client.set_expected_responses(expected_responses)
with session:
session.set_expected_responses(expected_responses)
_, serialized_tx = btc.sign_tx(
client, "Testnet", [inp1], [out1], prev_txes=TX_API_TESTNET
session, "Testnet", [inp1], [out1], prev_txes=TX_API_TESTNET
)
assert_tx_matches(
@ -278,7 +278,7 @@ def test_send_multisig_1(client: Client):
)
def test_attack_change_input_address(client: Client):
def test_attack_change_input_address(session: Session):
# Simulates an attack where the user is coerced into unknowingly
# transferring funds from one account to another one of their accounts,
# potentially resulting in privacy issues.
@ -303,17 +303,17 @@ def test_attack_change_input_address(client: Client):
)
# Test if the transaction can be signed normally.
with client:
client.set_expected_responses(
with session:
session.set_expected_responses(
[
request_input(0),
request_output(0),
# The user is required to confirm transfer to another account.
messages.ButtonRequest(code=B.ConfirmOutput),
(is_core(client), messages.ButtonRequest(code=B.ConfirmOutput)),
(is_core(session), messages.ButtonRequest(code=B.ConfirmOutput)),
request_output(1),
messages.ButtonRequest(code=B.ConfirmOutput),
(is_core(client), messages.ButtonRequest(code=B.ConfirmOutput)),
(is_core(session), messages.ButtonRequest(code=B.ConfirmOutput)),
messages.ButtonRequest(code=B.SignTx),
request_input(0),
request_meta(TXHASH_20912f),
@ -328,7 +328,7 @@ def test_attack_change_input_address(client: Client):
]
)
_, serialized_tx = btc.sign_tx(
client, "Testnet", [inp1], [out1, out2], prev_txes=TX_API_TESTNET
session, "Testnet", [inp1], [out1, out2], prev_txes=TX_API_TESTNET
)
# Transaction does not exist on the blockchain, not using assert_tx_matches()
@ -349,15 +349,15 @@ def test_attack_change_input_address(client: Client):
return msg
# Now run the attack, must trigger the exception
with client:
client.set_filter(messages.TxAck, attack_processor)
with session:
session.set_filter(messages.TxAck, attack_processor)
with pytest.raises(TrezorFailure):
btc.sign_tx(
client, "Testnet", [inp1], [out1, out2], prev_txes=TX_API_TESTNET
session, "Testnet", [inp1], [out1, out2], prev_txes=TX_API_TESTNET
)
def test_attack_mixed_inputs(client: Client):
def test_attack_mixed_inputs(session: Session):
TRUE_AMOUNT = 123_456_789
FAKE_AMOUNT = 120_000_000
@ -389,11 +389,11 @@ def test_attack_mixed_inputs(client: Client):
request_output(0),
messages.ButtonRequest(code=messages.ButtonRequestType.ConfirmOutput),
(
is_core(client),
is_core(session),
messages.ButtonRequest(code=messages.ButtonRequestType.ConfirmOutput),
),
(
is_core(client),
is_core(session),
messages.ButtonRequest(code=messages.ButtonRequestType.SignTx),
),
messages.ButtonRequest(code=messages.ButtonRequestType.FeeOverThreshold),
@ -417,16 +417,16 @@ def test_attack_mixed_inputs(client: Client):
request_finished(),
]
if client.model is models.T1B1:
if session.model is models.T1B1:
# T1 asks for first input for witness again
expected_responses.insert(-2, request_input(0))
with client:
with session:
# Sign unmodified transaction.
# "Fee over threshold" warning is displayed - fee is the whole TRUE_AMOUNT
client.set_expected_responses(expected_responses)
session.set_expected_responses(expected_responses)
btc.sign_tx(
client,
session,
"Testnet",
[inp1, inp2],
[out1],
@ -436,7 +436,7 @@ def test_attack_mixed_inputs(client: Client):
# In Phase 1 make the user confirm a lower value of the segwit input.
inp2.amount = FAKE_AMOUNT
if client.model is models.T1B1:
if session.model is models.T1B1:
# T1 fails as soon as it encounters the fake amount.
expected_responses = (
expected_responses[:4] + expected_responses[5:15] + [messages.Failure()]
@ -446,10 +446,10 @@ def test_attack_mixed_inputs(client: Client):
expected_responses[:4] + expected_responses[5:16] + [messages.Failure()]
)
with pytest.raises(TrezorFailure) as e, client:
client.set_expected_responses(expected_responses)
with pytest.raises(TrezorFailure) as e, session:
session.set_expected_responses(expected_responses)
btc.sign_tx(
client,
session,
"Testnet",
[inp1, inp2],
[out1],

View File

@ -17,7 +17,7 @@
import pytest
from trezorlib import btc, messages
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.debuglink import SessionDebugWrapper as Session
from trezorlib.tools import H_, parse_path
from ...bip32 import deserialize
@ -61,7 +61,7 @@ TXHASH_1c022d = bytes.fromhex(
)
def test_send_p2sh(client: Client):
def test_send_p2sh(session: Session):
# input tx: 20912f98ea3ed849042efed0fdac8cb4fc301961c5988cba56902d8ffb61c337
inp1 = messages.TxInputType(
@ -82,16 +82,16 @@ def test_send_p2sh(client: Client):
script_type=messages.OutputScriptType.PAYTOADDRESS,
amount=123_456_789 - 11_000 - 12_300_000,
)
with client:
client.set_expected_responses(
with session:
session.set_expected_responses(
[
request_input(0),
request_output(0),
messages.ButtonRequest(code=B.ConfirmOutput),
(is_core(client), messages.ButtonRequest(code=B.ConfirmOutput)),
(is_core(session), messages.ButtonRequest(code=B.ConfirmOutput)),
request_output(1),
messages.ButtonRequest(code=B.ConfirmOutput),
(is_core(client), messages.ButtonRequest(code=B.ConfirmOutput)),
(is_core(session), messages.ButtonRequest(code=B.ConfirmOutput)),
messages.ButtonRequest(code=B.SignTx),
request_input(0),
request_meta(TXHASH_20912f),
@ -106,7 +106,7 @@ def test_send_p2sh(client: Client):
]
)
_, serialized_tx = btc.sign_tx(
client, "Testnet", [inp1], [out1, out2], prev_txes=TX_API_TESTNET
session, "Testnet", [inp1], [out1, out2], prev_txes=TX_API_TESTNET
)
assert_tx_matches(
@ -116,7 +116,7 @@ def test_send_p2sh(client: Client):
)
def test_send_p2sh_change(client: Client):
def test_send_p2sh_change(session: Session):
# input tx: 20912f98ea3ed849042efed0fdac8cb4fc301961c5988cba56902d8ffb61c337
inp1 = messages.TxInputType(
@ -137,13 +137,13 @@ def test_send_p2sh_change(client: Client):
script_type=messages.OutputScriptType.PAYTOP2SHWITNESS,
amount=123_456_789 - 11_000 - 12_300_000,
)
with client:
client.set_expected_responses(
with session:
session.set_expected_responses(
[
request_input(0),
request_output(0),
messages.ButtonRequest(code=B.ConfirmOutput),
(is_core(client), messages.ButtonRequest(code=B.ConfirmOutput)),
(is_core(session), messages.ButtonRequest(code=B.ConfirmOutput)),
request_output(1),
messages.ButtonRequest(code=B.SignTx),
request_input(0),
@ -159,7 +159,7 @@ def test_send_p2sh_change(client: Client):
]
)
_, serialized_tx = btc.sign_tx(
client, "Testnet", [inp1], [out1, out2], prev_txes=TX_API_TESTNET
session, "Testnet", [inp1], [out1, out2], prev_txes=TX_API_TESTNET
)
# Transaction does not exist on the blockchain, not using assert_tx_matches()
@ -169,7 +169,7 @@ def test_send_p2sh_change(client: Client):
)
def test_send_native(client: Client):
def test_send_native(session: Session):
# input tx: b36780ceb86807ca6e7535a6fd418b1b788cb9b227d2c8a26a0de295e523219e
inp1 = messages.TxInputType(
@ -190,16 +190,16 @@ def test_send_native(client: Client):
script_type=messages.OutputScriptType.PAYTOADDRESS,
amount=100_000 - 40_000 - 10_000,
)
with client:
client.set_expected_responses(
with session:
session.set_expected_responses(
[
request_input(0),
request_output(0),
messages.ButtonRequest(code=B.ConfirmOutput),
(is_core(client), messages.ButtonRequest(code=B.ConfirmOutput)),
(is_core(session), messages.ButtonRequest(code=B.ConfirmOutput)),
request_output(1),
messages.ButtonRequest(code=B.ConfirmOutput),
(is_core(client), messages.ButtonRequest(code=B.ConfirmOutput)),
(is_core(session), messages.ButtonRequest(code=B.ConfirmOutput)),
messages.ButtonRequest(code=B.SignTx),
request_input(0),
request_meta(TXHASH_b36780),
@ -214,7 +214,7 @@ def test_send_native(client: Client):
]
)
_, serialized_tx = btc.sign_tx(
client, "Testnet", [inp1], [out1, out2], prev_txes=TX_API_TESTNET
session, "Testnet", [inp1], [out1, out2], prev_txes=TX_API_TESTNET
)
assert_tx_matches(
@ -224,7 +224,7 @@ def test_send_native(client: Client):
)
def test_send_to_taproot(client: Client):
def test_send_to_taproot(session: Session):
# input tx: ec16dc5a539c5d60001a7471c37dbb0b5294c289c77df8bd07870b30d73e2231
inp1 = messages.TxInputType(
@ -244,9 +244,9 @@ def test_send_to_taproot(client: Client):
script_type=messages.OutputScriptType.PAYTOADDRESS,
amount=10_000 - 7_000 - 200,
)
with client:
with session:
_, serialized_tx = btc.sign_tx(
client, "Testnet", [inp1], [out1, out2], prev_txes=TX_API_TESTNET
session, "Testnet", [inp1], [out1, out2], prev_txes=TX_API_TESTNET
)
assert_tx_matches(
@ -256,7 +256,7 @@ def test_send_to_taproot(client: Client):
)
def test_send_native_change(client: Client):
def test_send_native_change(session: Session):
# input tx: fcb3f5436224900afdba50e9e763d98b920dfed056e552040d99ea9bc03a9d83
inp1 = messages.TxInputType(
@ -277,13 +277,13 @@ def test_send_native_change(client: Client):
script_type=messages.OutputScriptType.PAYTOWITNESS,
amount=100_000 - 40_000 - 10_000,
)
with client:
client.set_expected_responses(
with session:
session.set_expected_responses(
[
request_input(0),
request_output(0),
messages.ButtonRequest(code=B.ConfirmOutput),
(is_core(client), messages.ButtonRequest(code=B.ConfirmOutput)),
(is_core(session), messages.ButtonRequest(code=B.ConfirmOutput)),
request_output(1),
messages.ButtonRequest(code=B.SignTx),
request_input(0),
@ -300,7 +300,7 @@ def test_send_native_change(client: Client):
]
)
_, serialized_tx = btc.sign_tx(
client, "Testnet", [inp1], [out1, out2], prev_txes=TX_API_TESTNET
session, "Testnet", [inp1], [out1, out2], prev_txes=TX_API_TESTNET
)
assert_tx_matches(
@ -310,7 +310,7 @@ def test_send_native_change(client: Client):
)
def test_send_both(client: Client):
def test_send_both(session: Session):
# input 1 tx: 65047a2b107d6301d72d4a1e49e7aea9cf06903fdc4ae74a4a9bba9bc1a414d2
# input 2 tx: d159fd2fcb5854a7c8b275d598765a446f1e2ff510bf077545a404a0c9db65f7
@ -344,21 +344,21 @@ def test_send_both(client: Client):
script_type=messages.OutputScriptType.PAYTOADDRESS,
)
with client:
client.set_expected_responses(
with session:
session.set_expected_responses(
[
request_input(0),
request_input(1),
request_output(0),
messages.ButtonRequest(code=B.ConfirmOutput),
(is_core(client), messages.ButtonRequest(code=B.ConfirmOutput)),
(is_core(session), messages.ButtonRequest(code=B.ConfirmOutput)),
request_output(1),
messages.ButtonRequest(code=B.ConfirmOutput),
(is_core(client), messages.ButtonRequest(code=B.ConfirmOutput)),
(is_core(session), messages.ButtonRequest(code=B.ConfirmOutput)),
request_output(2),
messages.ButtonRequest(code=B.ConfirmOutput),
(is_core(client), messages.ButtonRequest(code=B.ConfirmOutput)),
(is_core(client), messages.ButtonRequest(code=B.SignTx)),
(is_core(session), messages.ButtonRequest(code=B.ConfirmOutput)),
(is_core(session), messages.ButtonRequest(code=B.SignTx)),
messages.ButtonRequest(code=B.SignTx),
request_input(0),
request_meta(TXHASH_65047a),
@ -382,7 +382,7 @@ def test_send_both(client: Client):
]
)
_, serialized_tx = btc.sign_tx(
client,
session,
"Testnet",
[inp1, inp2],
[out1, out2, out3],
@ -397,12 +397,12 @@ def test_send_both(client: Client):
@pytest.mark.multisig
def test_send_multisig_1(client: Client):
def test_send_multisig_1(session: Session):
# input tx: b9abfa0d4a28f6f25e1f6c0f974bfc3f7c5a44c4d381b1796e3fbeef51b560a6
nodes = [
btc.get_public_node(
client, parse_path(f"m/49h/1h/{index}h"), coin_name="Testnet"
session, parse_path(f"m/49h/1h/{index}h"), coin_name="Testnet"
)
for index in range(1, 4)
]
@ -433,7 +433,7 @@ def test_send_multisig_1(client: Client):
request_input(0),
request_output(0),
messages.ButtonRequest(code=B.ConfirmOutput),
(is_core(client), messages.ButtonRequest(code=B.ConfirmOutput)),
(is_core(session), messages.ButtonRequest(code=B.ConfirmOutput)),
messages.ButtonRequest(code=B.SignTx),
request_input(0),
request_meta(TXHASH_b9abfa),
@ -449,10 +449,10 @@ def test_send_multisig_1(client: Client):
request_finished(),
]
with client:
client.set_expected_responses(expected_responses)
with session:
session.set_expected_responses(expected_responses)
signatures, _ = btc.sign_tx(
client, "Testnet", [inp1], [out1], prev_txes=TX_API_TESTNET
session, "Testnet", [inp1], [out1], prev_txes=TX_API_TESTNET
)
# store signature
@ -460,10 +460,10 @@ def test_send_multisig_1(client: Client):
# sign with third key
inp1.address_n[2] = H_(3)
with client:
client.set_expected_responses(expected_responses)
with session:
session.set_expected_responses(expected_responses)
_, serialized_tx = btc.sign_tx(
client, "Testnet", [inp1], [out1], prev_txes=TX_API_TESTNET
session, "Testnet", [inp1], [out1], prev_txes=TX_API_TESTNET
)
assert_tx_matches(
@ -474,12 +474,12 @@ def test_send_multisig_1(client: Client):
@pytest.mark.multisig
def test_send_multisig_2(client: Client):
def test_send_multisig_2(session: Session):
# input tx: b9abfa0d4a28f6f25e1f6c0f974bfc3f7c5a44c4d381b1796e3fbeef51b560a6
nodes = [
btc.get_public_node(
client, parse_path(f"m/84h/1h/{index}h"), coin_name="Testnet"
session, parse_path(f"m/84h/1h/{index}h"), coin_name="Testnet"
)
for index in range(1, 4)
]
@ -510,7 +510,7 @@ def test_send_multisig_2(client: Client):
request_input(0),
request_output(0),
messages.ButtonRequest(code=B.ConfirmOutput),
(is_core(client), messages.ButtonRequest(code=B.ConfirmOutput)),
(is_core(session), messages.ButtonRequest(code=B.ConfirmOutput)),
messages.ButtonRequest(code=B.SignTx),
request_input(0),
request_meta(TXHASH_b9abfa),
@ -526,10 +526,10 @@ def test_send_multisig_2(client: Client):
request_finished(),
]
with client:
client.set_expected_responses(expected_responses)
with session:
session.set_expected_responses(expected_responses)
signatures, _ = btc.sign_tx(
client, "Testnet", [inp1], [out1], prev_txes=TX_API_TESTNET
session, "Testnet", [inp1], [out1], prev_txes=TX_API_TESTNET
)
# store signature
@ -537,10 +537,10 @@ def test_send_multisig_2(client: Client):
# sign with first key
inp1.address_n[2] = H_(1)
with client:
client.set_expected_responses(expected_responses)
with session:
session.set_expected_responses(expected_responses)
_, serialized_tx = btc.sign_tx(
client, "Testnet", [inp1], [out1], prev_txes=TX_API_TESTNET
session, "Testnet", [inp1], [out1], prev_txes=TX_API_TESTNET
)
assert_tx_matches(
@ -551,12 +551,12 @@ def test_send_multisig_2(client: Client):
@pytest.mark.multisig
def test_send_multisig_3_change(client: Client):
def test_send_multisig_3_change(session: Session):
# input tx: b9abfa0d4a28f6f25e1f6c0f974bfc3f7c5a44c4d381b1796e3fbeef51b560a6
nodes = [
btc.get_public_node(
client, parse_path(f"m/84h/1h/{index}h"), coin_name="Testnet"
session, parse_path(f"m/84h/1h/{index}h"), coin_name="Testnet"
)
for index in range(1, 4)
]
@ -595,7 +595,7 @@ def test_send_multisig_3_change(client: Client):
request_output(0),
messages.ButtonRequest(code=B.UnknownDerivationPath),
messages.ButtonRequest(code=B.ConfirmOutput),
(is_core(client), messages.ButtonRequest(code=B.ConfirmOutput)),
(is_core(session), messages.ButtonRequest(code=B.ConfirmOutput)),
messages.ButtonRequest(code=B.SignTx),
request_input(0),
request_meta(TXHASH_b9abfa),
@ -611,13 +611,13 @@ def test_send_multisig_3_change(client: Client):
request_finished(),
]
with client:
client.set_expected_responses(expected_responses)
if is_core(client):
with session, session.client as client:
session.set_expected_responses(expected_responses)
if is_core(session):
IF = InputFlowConfirmAllWarnings(client)
client.set_input_flow(IF.get())
signatures, _ = btc.sign_tx(
client, "Testnet", [inp1], [out1], prev_txes=TX_API_TESTNET
session, "Testnet", [inp1], [out1], prev_txes=TX_API_TESTNET
)
# store signature
@ -626,13 +626,13 @@ def test_send_multisig_3_change(client: Client):
inp1.address_n[2] = H_(3)
out1.address_n[2] = H_(3)
with client:
client.set_expected_responses(expected_responses)
if is_core(client):
with session, session.client as client:
session.set_expected_responses(expected_responses)
if is_core(session):
IF = InputFlowConfirmAllWarnings(client)
client.set_input_flow(IF.get())
_, serialized_tx = btc.sign_tx(
client, "Testnet", [inp1], [out1], prev_txes=TX_API_TESTNET
session, "Testnet", [inp1], [out1], prev_txes=TX_API_TESTNET
)
assert_tx_matches(
@ -643,12 +643,12 @@ def test_send_multisig_3_change(client: Client):
@pytest.mark.multisig
def test_send_multisig_4_change(client: Client):
def test_send_multisig_4_change(session: Session):
# input tx: b9abfa0d4a28f6f25e1f6c0f974bfc3f7c5a44c4d381b1796e3fbeef51b560a6
nodes = [
btc.get_public_node(
client, parse_path(f"m/49h/1h/{index}h"), coin_name="Testnet"
session, parse_path(f"m/49h/1h/{index}h"), coin_name="Testnet"
)
for index in range(1, 4)
]
@ -687,7 +687,7 @@ def test_send_multisig_4_change(client: Client):
request_output(0),
messages.ButtonRequest(code=B.UnknownDerivationPath),
messages.ButtonRequest(code=B.ConfirmOutput),
(is_core(client), messages.ButtonRequest(code=B.ConfirmOutput)),
(is_core(session), messages.ButtonRequest(code=B.ConfirmOutput)),
messages.ButtonRequest(code=B.SignTx),
request_input(0),
request_meta(TXHASH_b9abfa),
@ -703,13 +703,13 @@ def test_send_multisig_4_change(client: Client):
request_finished(),
]
with client:
client.set_expected_responses(expected_responses)
if is_core(client):
with session, session.client as client:
session.set_expected_responses(expected_responses)
if is_core(session):
IF = InputFlowConfirmAllWarnings(client)
client.set_input_flow(IF.get())
signatures, _ = btc.sign_tx(
client, "Testnet", [inp1], [out1], prev_txes=TX_API_TESTNET
session, "Testnet", [inp1], [out1], prev_txes=TX_API_TESTNET
)
# store signature
@ -718,13 +718,13 @@ def test_send_multisig_4_change(client: Client):
inp1.address_n[2] = H_(3)
out1.address_n[2] = H_(3)
with client:
client.set_expected_responses(expected_responses)
if is_core(client):
with session, session.client as client:
session.set_expected_responses(expected_responses)
if is_core(session):
IF = InputFlowConfirmAllWarnings(client)
client.set_input_flow(IF.get())
_, serialized_tx = btc.sign_tx(
client, "Testnet", [inp1], [out1], prev_txes=TX_API_TESTNET
session, "Testnet", [inp1], [out1], prev_txes=TX_API_TESTNET
)
assert_tx_matches(
@ -734,7 +734,7 @@ def test_send_multisig_4_change(client: Client):
)
def test_multisig_mismatch_inputs_single(client: Client):
def test_multisig_mismatch_inputs_single(session: Session):
# Ensure that if there is a non-multisig input, then a multisig output
# will not be identified as a change output.
@ -788,18 +788,18 @@ def test_multisig_mismatch_inputs_single(client: Client):
amount=100_000 + 100_000 - 50_000 - 10_000,
)
with client:
client.set_expected_responses(
with session:
session.set_expected_responses(
[
request_input(0),
request_input(1),
request_output(0),
messages.ButtonRequest(code=B.ConfirmOutput),
(is_core(client), messages.ButtonRequest(code=B.ConfirmOutput)),
(is_core(session), messages.ButtonRequest(code=B.ConfirmOutput)),
request_output(1),
# Ensure that the multisig output is not identified as a change output.
messages.ButtonRequest(code=B.ConfirmOutput),
(is_core(client), messages.ButtonRequest(code=B.ConfirmOutput)),
(is_core(session), messages.ButtonRequest(code=B.ConfirmOutput)),
messages.ButtonRequest(code=B.SignTx),
request_input(0),
request_meta(TXHASH_1c022d),
@ -824,7 +824,7 @@ def test_multisig_mismatch_inputs_single(client: Client):
)
_, serialized_tx = btc.sign_tx(
client, "Testnet", [inp1, inp2], [out1, out2], prev_txes=TX_API_TESTNET
session, "Testnet", [inp1, inp2], [out1, out2], prev_txes=TX_API_TESTNET
)
assert_tx_matches(

View File

@ -17,7 +17,7 @@
import pytest
from trezorlib import btc, messages, models
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.debuglink import SessionDebugWrapper as Session
from trezorlib.exceptions import TrezorFailure
from trezorlib.tools import H_, parse_path
@ -64,7 +64,7 @@ TXHASH_c96621 = bytes.fromhex(
@pytest.mark.parametrize("chunkify", (True, False))
def test_send_p2tr(client: Client, chunkify: bool):
def test_send_p2tr(session: Session, chunkify: bool):
inp1 = messages.TxInputType(
# tb1pn2d0yjeedavnkd8z8lhm566p0f2utm3lgvxrsdehnl94y34txmts5s7t4c
address_n=parse_path("m/86h/1h/0h/1/0"),
@ -79,13 +79,13 @@ def test_send_p2tr(client: Client, chunkify: bool):
amount=4_450,
script_type=messages.OutputScriptType.PAYTOADDRESS,
)
with client:
client.set_expected_responses(
with session:
session.set_expected_responses(
[
request_input(0),
request_output(0),
messages.ButtonRequest(code=B.ConfirmOutput),
(is_core(client), messages.ButtonRequest(code=B.ConfirmOutput)),
(is_core(session), messages.ButtonRequest(code=B.ConfirmOutput)),
messages.ButtonRequest(code=B.SignTx),
request_input(0),
request_output(0),
@ -94,7 +94,7 @@ def test_send_p2tr(client: Client, chunkify: bool):
]
)
_, serialized_tx = btc.sign_tx(
client, "Testnet", [inp1], [out1], prev_txes=TX_API, chunkify=chunkify
session, "Testnet", [inp1], [out1], prev_txes=TX_API, chunkify=chunkify
)
assert_tx_matches(
@ -104,7 +104,7 @@ def test_send_p2tr(client: Client, chunkify: bool):
)
def test_send_two_with_change(client: Client):
def test_send_two_with_change(session: Session):
inp1 = messages.TxInputType(
# tb1pswrqtykue8r89t9u4rprjs0gt4qzkdfuursfnvqaa3f2yql07zmq8s8a5u
address_n=parse_path("m/86h/1h/0h/0/0"),
@ -133,14 +133,14 @@ def test_send_two_with_change(client: Client):
script_type=messages.OutputScriptType.PAYTOTAPROOT,
amount=6_800 + 13_000 - 200 - 15_000,
)
with client:
client.set_expected_responses(
with session:
session.set_expected_responses(
[
request_input(0),
request_input(1),
request_output(0),
messages.ButtonRequest(code=B.ConfirmOutput),
(is_core(client), messages.ButtonRequest(code=B.ConfirmOutput)),
(is_core(session), messages.ButtonRequest(code=B.ConfirmOutput)),
request_output(1),
messages.ButtonRequest(code=B.SignTx),
request_input(0),
@ -153,7 +153,7 @@ def test_send_two_with_change(client: Client):
]
)
_, serialized_tx = btc.sign_tx(
client, "Testnet", [inp1, inp2], [out1, out2], prev_txes=TX_API
session, "Testnet", [inp1, inp2], [out1, out2], prev_txes=TX_API
)
assert_tx_matches(
@ -163,7 +163,7 @@ def test_send_two_with_change(client: Client):
)
def test_send_mixed(client: Client):
def test_send_mixed(session: Session):
inp1 = messages.TxInputType(
# 2MutHjgAXkqo3jxX2DZWorLAckAnwTxSM9V
address_n=parse_path("m/49h/1h/1h/0/0"),
@ -222,8 +222,8 @@ def test_send_mixed(client: Client):
script_type=messages.OutputScriptType.PAYTOTAPROOT,
)
with client:
client.set_expected_responses(
with session:
session.set_expected_responses(
[
# process inputs
request_input(0),
@ -233,19 +233,19 @@ def test_send_mixed(client: Client):
# approve outputs
request_output(0),
messages.ButtonRequest(code=B.ConfirmOutput),
(is_core(client), messages.ButtonRequest(code=B.ConfirmOutput)),
(is_core(session), messages.ButtonRequest(code=B.ConfirmOutput)),
request_output(1),
messages.ButtonRequest(code=B.ConfirmOutput),
(is_core(client), messages.ButtonRequest(code=B.ConfirmOutput)),
(is_core(session), messages.ButtonRequest(code=B.ConfirmOutput)),
request_output(2),
messages.ButtonRequest(code=B.ConfirmOutput),
(is_core(client), messages.ButtonRequest(code=B.ConfirmOutput)),
(is_core(session), messages.ButtonRequest(code=B.ConfirmOutput)),
request_output(3),
messages.ButtonRequest(code=B.ConfirmOutput),
request_output(4),
messages.ButtonRequest(code=B.ConfirmOutput),
(is_core(client), messages.ButtonRequest(code=B.ConfirmOutput)),
(is_core(client), messages.ButtonRequest(code=B.SignTx)),
(is_core(session), messages.ButtonRequest(code=B.ConfirmOutput)),
(is_core(session), messages.ButtonRequest(code=B.SignTx)),
messages.ButtonRequest(code=B.SignTx),
# verify inputs
request_input(0),
@ -293,12 +293,12 @@ def test_send_mixed(client: Client):
request_input(0),
request_input(1),
request_input(2),
(client.model is models.T1B1, request_input(3)),
(session.model is models.T1B1, request_input(3)),
request_finished(),
]
)
_, serialized_tx = btc.sign_tx(
client,
session,
"Testnet",
[inp1, inp2, inp3, inp4],
[out1, out2, out3, out4, out5],
@ -312,13 +312,12 @@ def test_send_mixed(client: Client):
)
def test_attack_script_type(client: Client):
def test_attack_script_type(session: Session):
# Scenario: The attacker falsely claims that the transaction is Taproot-only to
# avoid prev tx streaming and gives a lower amount for one of the inputs. The
# correct input types and amounts are revelaled only in step6_sign_segwit_inputs()
# to get a valid signature. This results in a transaction which pays a fee much
# larger than what the user confirmed.
inp1 = messages.TxInputType(
address_n=parse_path("m/84h/1h/0h/1/0"),
amount=7_289_000,
@ -354,16 +353,16 @@ def test_attack_script_type(client: Client):
return msg
with client:
client.set_filter(messages.TxAck, attack_processor)
client.set_expected_responses(
with session:
session.set_filter(messages.TxAck, attack_processor)
session.set_expected_responses(
[
request_input(0),
request_input(1),
request_output(0),
messages.ButtonRequest(code=B.ConfirmOutput),
(is_core(client), messages.ButtonRequest(code=B.ConfirmOutput)),
(is_core(client), messages.ButtonRequest(code=B.SignTx)),
(is_core(session), messages.ButtonRequest(code=B.ConfirmOutput)),
(is_core(session), messages.ButtonRequest(code=B.SignTx)),
messages.ButtonRequest(code=B.SignTx),
request_input(0),
request_input(1),
@ -374,7 +373,7 @@ def test_attack_script_type(client: Client):
]
)
with pytest.raises(TrezorFailure) as exc:
btc.sign_tx(client, "Testnet", [inp1, inp2], [out1], prev_txes=TX_API)
btc.sign_tx(session, "Testnet", [inp1, inp2], [out1], prev_txes=TX_API)
assert exc.value.code == messages.FailureType.ProcessError
assert exc.value.message.endswith("Transaction has changed during signing")
@ -392,7 +391,7 @@ def test_attack_script_type(client: Client):
"tb1pllllllllllllllllllllllllllllllllllllllllllllallllscqgl4zhn",
),
)
def test_send_invalid_address(client: Client, address: str):
def test_send_invalid_address(session: Session, address: str):
inp1 = messages.TxInputType(
# tb1pn2d0yjeedavnkd8z8lhm566p0f2utm3lgvxrsdehnl94y34txmts5s7t4c
address_n=parse_path("m/86h/1h/0h/1/0"),
@ -407,12 +406,12 @@ def test_send_invalid_address(client: Client, address: str):
script_type=messages.OutputScriptType.PAYTOADDRESS,
)
with client, pytest.raises(TrezorFailure):
client.set_expected_responses(
with session, pytest.raises(TrezorFailure):
session.set_expected_responses(
[
request_input(0),
request_output(0),
messages.Failure,
]
)
btc.sign_tx(client, "Testnet", [inp1], [out1], prev_txes=TX_API)
btc.sign_tx(session, "Testnet", [inp1], [out1], prev_txes=TX_API)

View File

@ -19,12 +19,12 @@ import base64
import pytest
from trezorlib import btc
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.debuglink import SessionDebugWrapper as Session
def test_message_long(client: Client):
def test_message_long(session: Session):
ret = btc.verify_message(
client,
session,
"Bitcoin",
"14LmW5k4ssUrtbAB4255zdqv3b4w1TuX9e",
bytes.fromhex(
@ -35,9 +35,9 @@ def test_message_long(client: Client):
assert ret is True
def test_message_testnet(client: Client):
def test_message_testnet(session: Session):
ret = btc.verify_message(
client,
session,
"Testnet",
"mirio8q3gtv7fhdnmb3TpZ4EuafdzSs7zL",
bytes.fromhex(
@ -49,9 +49,9 @@ def test_message_testnet(client: Client):
@pytest.mark.altcoin
def test_message_grs(client: Client):
def test_message_grs(session: Session):
ret = btc.verify_message(
client,
session,
"Groestlcoin",
"Fj62rBJi8LvbmWu2jzkaUX1NFXLEqDLoZM",
base64.b64decode(
@ -62,9 +62,9 @@ def test_message_grs(client: Client):
assert ret is True
def test_message_verify(client: Client):
def test_message_verify(session: Session):
res = btc.verify_message(
client,
session,
"Bitcoin",
"1JwSSubhmg6iPtRjtyqhUYYH7bZg3Lfy1T",
bytes.fromhex(
@ -76,7 +76,7 @@ def test_message_verify(client: Client):
# uncompressed pubkey - FAIL - wrong sig
res = btc.verify_message(
client,
session,
"Bitcoin",
"1JwSSubhmg6iPtRjtyqhUYYH7bZg3Lfy1T",
bytes.fromhex(
@ -88,7 +88,7 @@ def test_message_verify(client: Client):
# uncompressed pubkey - FAIL - wrong msg
res = btc.verify_message(
client,
session,
"Bitcoin",
"1JwSSubhmg6iPtRjtyqhUYYH7bZg3Lfy1T",
bytes.fromhex(
@ -100,7 +100,7 @@ def test_message_verify(client: Client):
# compressed pubkey - OK
res = btc.verify_message(
client,
session,
"Bitcoin",
"1C7zdTfnkzmr13HfA2vNm5SJYRK6nEKyq8",
bytes.fromhex(
@ -112,7 +112,7 @@ def test_message_verify(client: Client):
# compressed pubkey - FAIL - wrong sig
res = btc.verify_message(
client,
session,
"Bitcoin",
"1C7zdTfnkzmr13HfA2vNm5SJYRK6nEKyq8",
bytes.fromhex(
@ -124,7 +124,7 @@ def test_message_verify(client: Client):
# compressed pubkey - FAIL - wrong msg
res = btc.verify_message(
client,
session,
"Bitcoin",
"1C7zdTfnkzmr13HfA2vNm5SJYRK6nEKyq8",
bytes.fromhex(
@ -136,7 +136,7 @@ def test_message_verify(client: Client):
# trezor pubkey - OK
res = btc.verify_message(
client,
session,
"Bitcoin",
"14LmW5k4ssUrtbAB4255zdqv3b4w1TuX9e",
bytes.fromhex(
@ -148,7 +148,7 @@ def test_message_verify(client: Client):
# trezor pubkey - FAIL - wrong sig
res = btc.verify_message(
client,
session,
"Bitcoin",
"14LmW5k4ssUrtbAB4255zdqv3b4w1TuX9e",
bytes.fromhex(
@ -160,7 +160,7 @@ def test_message_verify(client: Client):
# trezor pubkey - FAIL - wrong msg
res = btc.verify_message(
client,
session,
"Bitcoin",
"14LmW5k4ssUrtbAB4255zdqv3b4w1TuX9e",
bytes.fromhex(
@ -172,9 +172,9 @@ def test_message_verify(client: Client):
@pytest.mark.altcoin
def test_message_verify_bcash(client: Client):
def test_message_verify_bcash(session: Session):
res = btc.verify_message(
client,
session,
"Bcash",
"bitcoincash:qqj22md58nm09vpwsw82fyletkxkq36zxyxh322pru",
bytes.fromhex(
@ -185,9 +185,9 @@ def test_message_verify_bcash(client: Client):
assert res is True
def test_verify_bitcoind(client: Client):
def test_verify_bitcoind(session: Session):
res = btc.verify_message(
client,
session,
"Bitcoin",
"1KzXE97kV7DrpxCViCN3HbGbiKhzzPM7TQ",
bytes.fromhex(
@ -199,12 +199,12 @@ def test_verify_bitcoind(client: Client):
assert res is True
def test_verify_utf(client: Client):
def test_verify_utf(session: Session):
words_nfkd = "Pr\u030ci\u0301s\u030cerne\u030c z\u030clut\u030couc\u030cky\u0301 ku\u030an\u030c u\u0301pe\u030cl d\u030ca\u0301belske\u0301 o\u0301dy za\u0301ker\u030cny\u0301 uc\u030cen\u030c be\u030cz\u030ci\u0301 pode\u0301l zo\u0301ny u\u0301lu\u030a"
words_nfc = "P\u0159\xed\u0161ern\u011b \u017elu\u0165ou\u010dk\xfd k\u016f\u0148 \xfap\u011bl \u010f\xe1belsk\xe9 \xf3dy z\xe1ke\u0159n\xfd u\u010de\u0148 b\u011b\u017e\xed pod\xe9l z\xf3ny \xfal\u016f"
res_nfkd = btc.verify_message(
client,
session,
"Bitcoin",
"14LmW5k4ssUrtbAB4255zdqv3b4w1TuX9e",
bytes.fromhex(
@ -214,7 +214,7 @@ def test_verify_utf(client: Client):
)
res_nfc = btc.verify_message(
client,
session,
"Bitcoin",
"14LmW5k4ssUrtbAB4255zdqv3b4w1TuX9e",
bytes.fromhex(

View File

@ -15,12 +15,12 @@
# If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.
from trezorlib import btc
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.debuglink import SessionDebugWrapper as Session
def test_message_long(client: Client):
def test_message_long(session: Session):
ret = btc.verify_message(
client,
session,
"Bitcoin",
"3CwYaeWxhpXXiHue3ciQez1DLaTEAXcKa1",
bytes.fromhex(
@ -31,9 +31,9 @@ def test_message_long(client: Client):
assert ret is True
def test_message_testnet(client: Client):
def test_message_testnet(session: Session):
ret = btc.verify_message(
client,
session,
"Testnet",
"2N4VkePSzKH2sv5YBikLHGvzUYvfPxV6zS9",
bytes.fromhex(
@ -44,9 +44,9 @@ def test_message_testnet(client: Client):
assert ret is True
def test_message_verify(client: Client):
def test_message_verify(session: Session):
res = btc.verify_message(
client,
session,
"Bitcoin",
"3CwYaeWxhpXXiHue3ciQez1DLaTEAXcKa1",
bytes.fromhex(
@ -58,7 +58,7 @@ def test_message_verify(client: Client):
# no script type
res = btc.verify_message(
client,
session,
"Bitcoin",
"3L6TyTisPBmrDAj6RoKmDzNnj4eQi54gD2",
bytes.fromhex(
@ -70,7 +70,7 @@ def test_message_verify(client: Client):
# trezor pubkey - FAIL - wrong sig
res = btc.verify_message(
client,
session,
"Bitcoin",
"3CwYaeWxhpXXiHue3ciQez1DLaTEAXcKa1",
bytes.fromhex(
@ -82,7 +82,7 @@ def test_message_verify(client: Client):
# trezor pubkey - FAIL - wrong msg
res = btc.verify_message(
client,
session,
"Bitcoin",
"3CwYaeWxhpXXiHue3ciQez1DLaTEAXcKa1",
bytes.fromhex(
@ -93,12 +93,12 @@ def test_message_verify(client: Client):
assert res is False
def test_verify_utf(client: Client):
def test_verify_utf(session: Session):
words_nfkd = "Pr\u030ci\u0301s\u030cerne\u030c z\u030clut\u030couc\u030cky\u0301 ku\u030an\u030c u\u0301pe\u030cl d\u030ca\u0301belske\u0301 o\u0301dy za\u0301ker\u030cny\u0301 uc\u030cen\u030c be\u030cz\u030ci\u0301 pode\u0301l zo\u0301ny u\u0301lu\u030a"
words_nfc = "P\u0159\xed\u0161ern\u011b \u017elu\u0165ou\u010dk\xfd k\u016f\u0148 \xfap\u011bl \u010f\xe1belsk\xe9 \xf3dy z\xe1ke\u0159n\xfd u\u010de\u0148 b\u011b\u017e\xed pod\xe9l z\xf3ny \xfal\u016f"
res_nfkd = btc.verify_message(
client,
session,
"Bitcoin",
"3CwYaeWxhpXXiHue3ciQez1DLaTEAXcKa1",
bytes.fromhex(
@ -108,7 +108,7 @@ def test_verify_utf(client: Client):
)
res_nfc = btc.verify_message(
client,
session,
"Bitcoin",
"3CwYaeWxhpXXiHue3ciQez1DLaTEAXcKa1",
bytes.fromhex(

View File

@ -15,12 +15,12 @@
# If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.
from trezorlib import btc
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.debuglink import SessionDebugWrapper as Session
def test_message_long(client: Client):
def test_message_long(session: Session):
ret = btc.verify_message(
client,
session,
"Bitcoin",
"bc1qyjjkmdpu7metqt5r36jf872a34syws33s82q2j",
bytes.fromhex(
@ -31,9 +31,9 @@ def test_message_long(client: Client):
assert ret is True
def test_message_testnet(client: Client):
def test_message_testnet(session: Session):
ret = btc.verify_message(
client,
session,
"Testnet",
"tb1qyjjkmdpu7metqt5r36jf872a34syws336p3n3p",
bytes.fromhex(
@ -44,9 +44,9 @@ def test_message_testnet(client: Client):
assert ret is True
def test_message_verify(client: Client):
def test_message_verify(session: Session):
res = btc.verify_message(
client,
session,
"Bitcoin",
"bc1qyjjkmdpu7metqt5r36jf872a34syws33s82q2j",
bytes.fromhex(
@ -58,7 +58,7 @@ def test_message_verify(client: Client):
# no script type
res = btc.verify_message(
client,
session,
"Bitcoin",
"bc1qannfxke2tfd4l7vhepehpvt05y83v3qsf6nfkk",
bytes.fromhex(
@ -70,7 +70,7 @@ def test_message_verify(client: Client):
# trezor pubkey - FAIL - wrong sig
res = btc.verify_message(
client,
session,
"Bitcoin",
"bc1qyjjkmdpu7metqt5r36jf872a34syws33s82q2j",
bytes.fromhex(
@ -82,7 +82,7 @@ def test_message_verify(client: Client):
# trezor pubkey - FAIL - wrong msg
res = btc.verify_message(
client,
session,
"Bitcoin",
"bc1qyjjkmdpu7metqt5r36jf872a34syws33s82q2j",
bytes.fromhex(
@ -93,12 +93,12 @@ def test_message_verify(client: Client):
assert res is False
def test_verify_utf(client: Client):
def test_verify_utf(session: Session):
words_nfkd = "Pr\u030ci\u0301s\u030cerne\u030c z\u030clut\u030couc\u030cky\u0301 ku\u030an\u030c u\u0301pe\u030cl d\u030ca\u0301belske\u0301 o\u0301dy za\u0301ker\u030cny\u0301 uc\u030cen\u030c be\u030cz\u030ci\u0301 pode\u0301l zo\u0301ny u\u0301lu\u030a"
words_nfc = "P\u0159\xed\u0161ern\u011b \u017elu\u0165ou\u010dk\xfd k\u016f\u0148 \xfap\u011bl \u010f\xe1belsk\xe9 \xf3dy z\xe1ke\u0159n\xfd u\u010de\u0148 b\u011b\u017e\xed pod\xe9l z\xf3ny \xfal\u016f"
res_nfkd = btc.verify_message(
client,
session,
"Bitcoin",
"bc1qyjjkmdpu7metqt5r36jf872a34syws33s82q2j",
bytes.fromhex(
@ -108,7 +108,7 @@ def test_verify_utf(client: Client):
)
res_nfc = btc.verify_message(
client,
session,
"Bitcoin",
"bc1qyjjkmdpu7metqt5r36jf872a34syws33s82q2j",
bytes.fromhex(

View File

@ -17,7 +17,7 @@
import pytest
from trezorlib import btc, messages
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.debuglink import SessionDebugWrapper as Session
from trezorlib.exceptions import TrezorFailure
from trezorlib.tools import parse_path
@ -57,7 +57,7 @@ FAKE_TXHASH_v4 = bytes.fromhex(
pytestmark = [pytest.mark.altcoin, pytest.mark.zcash]
def test_v3_not_supported(client: Client):
def test_v3_not_supported(session: Session):
# prevout: aaf51e4606c264e47e5c42c958fe4cf1539c5172684721e38e69f4ef634d75dc:1
# input 1: 3.0 TAZ
@ -75,9 +75,9 @@ def test_v3_not_supported(client: Client):
script_type=messages.OutputScriptType.PAYTOADDRESS,
)
with client, pytest.raises(TrezorFailure, match="DataError"):
with session, pytest.raises(TrezorFailure, match="DataError"):
btc.sign_tx(
client,
session,
"Zcash Testnet",
[inp1],
[out1],
@ -88,7 +88,7 @@ def test_v3_not_supported(client: Client):
)
def test_one_one_fee_sapling(client: Client):
def test_one_one_fee_sapling(session: Session):
# prevout: e3820602226974b1dd87b7113cc8aea8c63e5ae29293991e7bfa80c126930368:0
# input 1: 3.0 TAZ
@ -106,13 +106,13 @@ def test_one_one_fee_sapling(client: Client):
script_type=messages.OutputScriptType.PAYTOADDRESS,
)
with client:
client.set_expected_responses(
with session:
session.set_expected_responses(
[
request_input(0),
request_output(0),
messages.ButtonRequest(code=B.ConfirmOutput),
(is_core(client), messages.ButtonRequest(code=B.ConfirmOutput)),
(is_core(session), messages.ButtonRequest(code=B.ConfirmOutput)),
messages.ButtonRequest(code=B.SignTx),
request_input(0),
request_meta(TXHASH_e38206),
@ -128,7 +128,7 @@ def test_one_one_fee_sapling(client: Client):
)
_, serialized_tx = btc.sign_tx(
client,
session,
"Zcash Testnet",
[inp1],
[out1],
@ -145,7 +145,7 @@ def test_one_one_fee_sapling(client: Client):
)
def test_version_group_id_missing(client: Client):
def test_version_group_id_missing(session: Session):
inp1 = messages.TxInputType(
# tmQoJ3PTXgQLaRRZZYT6xk8XtjRbr2kCqwu
address_n=parse_path("m/44h/1h/0h/0/0"),
@ -161,7 +161,7 @@ def test_version_group_id_missing(client: Client):
with pytest.raises(TrezorFailure, match="Version group ID must be set."):
btc.sign_tx(
client,
session,
"Zcash Testnet",
[inp1],
[out1],
@ -170,7 +170,7 @@ def test_version_group_id_missing(client: Client):
)
def test_spend_old_versions(client: Client):
def test_spend_old_versions(session: Session):
# NOTE: fake input tx used
input_v1 = messages.TxInputType(
@ -210,9 +210,9 @@ def test_spend_old_versions(client: Client):
script_type=messages.OutputScriptType.PAYTOADDRESS,
)
with client:
with session:
_, serialized_tx = btc.sign_tx(
client,
session,
"Zcash Testnet",
inputs,
[output],
@ -229,7 +229,7 @@ def test_spend_old_versions(client: Client):
@pytest.mark.models("core")
def test_external_presigned(client: Client):
def test_external_presigned(session: Session):
inp1 = messages.TxInputType(
# tmQoJ3PTXgQLaRRZZYT6xk8XtjRbr2kCqwu
address_n=parse_path("m/44h/1h/0h/0/0"),
@ -259,14 +259,14 @@ def test_external_presigned(client: Client):
script_type=messages.OutputScriptType.PAYTOADDRESS,
)
with client:
client.set_expected_responses(
with session:
session.set_expected_responses(
[
request_input(0),
request_input(1),
request_output(0),
messages.ButtonRequest(code=B.ConfirmOutput),
(is_core(client), messages.ButtonRequest(code=B.ConfirmOutput)),
(is_core(session), messages.ButtonRequest(code=B.ConfirmOutput)),
messages.ButtonRequest(code=B.SignTx),
request_input(0),
request_meta(TXHASH_e38206),
@ -289,7 +289,7 @@ def test_external_presigned(client: Client):
)
_, serialized_tx = btc.sign_tx(
client,
session,
"Zcash Testnet",
[inp1, inp2],
[out1],

View File

@ -22,7 +22,7 @@ from trezorlib.cardano import (
get_public_key,
parse_optional_bytes,
)
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.debuglink import SessionDebugWrapper as Session
from trezorlib.messages import CardanoAddressType, CardanoDerivationType
from trezorlib.tools import parse_path
@ -48,15 +48,15 @@ pytestmark = [
"cardano/get_base_address.derivations.json",
)
@pytest.mark.parametrize("chunkify", (True, False))
def test_cardano_get_address(client: Client, chunkify: bool, parameters, result):
client.init_device(new_session=True, derive_cardano=True)
def test_cardano_get_address(session: Session, chunkify: bool, parameters, result):
# session.init_device(new_session=True, derive_cardano=True)
derivation_type = CardanoDerivationType.__members__[
parameters.get("derivation_type", "ICARUS_TREZOR")
]
address = get_address(
client,
session,
address_parameters=create_address_parameters(
address_type=getattr(
CardanoAddressType, parameters["address_type"].upper()
@ -94,17 +94,17 @@ def test_cardano_get_address(client: Client, chunkify: bool, parameters, result)
"cardano/get_public_key.slip39.json",
"cardano/get_public_key.derivations.json",
)
def test_cardano_get_public_key(client: Client, parameters, result):
with client:
IF = InputFlowShowXpubQRCode(client, passphrase=bool(client.ui.passphrase))
def test_cardano_get_public_key(session: Session, parameters, result):
with session, session.client as client:
IF = InputFlowShowXpubQRCode(client, passphrase=bool(session.passphrase))
client.set_input_flow(IF.get())
client.init_device(new_session=True, derive_cardano=True)
# session.init_device(new_session=True, derive_cardano=True)
derivation_type = CardanoDerivationType.__members__[
parameters.get("derivation_type", "ICARUS_TREZOR")
]
key = get_public_key(
client, parse_path(parameters["path"]), derivation_type, show_display=True
session, parse_path(parameters["path"]), derivation_type, show_display=True
)
assert key.node.public_key.hex() == result["public_key"]

View File

@ -17,7 +17,7 @@
import pytest
from trezorlib.cardano import get_public_key
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.debuglink import SessionDebugWrapper as Session
from trezorlib.exceptions import TrezorFailure
from trezorlib.messages import CardanoDerivationType as D
from trezorlib.tools import parse_path
@ -26,35 +26,29 @@ from ...common import MNEMONIC_SLIP39_BASIC_20_3of6
pytestmark = [
pytest.mark.altcoin,
pytest.mark.cardano,
pytest.mark.models("core"),
]
ADDRESS_N = parse_path("m/1852h/1815h/0h")
def test_bad_session(client: Client):
client.init_device(new_session=True)
def test_bad_session(session: Session):
with pytest.raises(TrezorFailure, match="not enabled"):
get_public_key(client, ADDRESS_N, derivation_type=D.ICARUS)
client.init_device(new_session=True, derive_cardano=False)
with pytest.raises(TrezorFailure, match="not enabled"):
get_public_key(client, ADDRESS_N, derivation_type=D.ICARUS)
get_public_key(session, ADDRESS_N, derivation_type=D.ICARUS)
def test_ledger_available_always(client: Client):
client.init_device(new_session=True, derive_cardano=False)
get_public_key(client, ADDRESS_N, derivation_type=D.LEDGER)
def test_ledger_available_without_cardano(session: Session):
get_public_key(session, ADDRESS_N, derivation_type=D.LEDGER)
client.init_device(new_session=True, derive_cardano=True)
get_public_key(client, ADDRESS_N, derivation_type=D.LEDGER)
@pytest.mark.cardano # derive_cardano=True
def test_ledger_available_with_cardano(session: Session):
get_public_key(session, ADDRESS_N, derivation_type=D.LEDGER)
@pytest.mark.setup_client(mnemonic=MNEMONIC_SLIP39_BASIC_20_3of6)
@pytest.mark.parametrize("derivation_type", D) # try ALL derivation types
def test_derivation_irrelevant_on_slip39(client: Client, derivation_type):
client.init_device(new_session=True, derive_cardano=False)
pubkey = get_public_key(client, ADDRESS_N, derivation_type=D.ICARUS)
test_pubkey = get_public_key(client, ADDRESS_N, derivation_type=derivation_type)
def test_derivation_irrelevant_on_slip39(session: Session, derivation_type):
pubkey = get_public_key(session, ADDRESS_N, derivation_type=D.ICARUS)
test_pubkey = get_public_key(session, ADDRESS_N, derivation_type=derivation_type)
assert pubkey == test_pubkey

View File

@ -18,7 +18,7 @@ import pytest
from trezorlib import messages
from trezorlib.cardano import get_native_script_hash, parse_native_script
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.debuglink import SessionDebugWrapper as Session
from ...common import parametrize_using_common_fixtures
@ -32,11 +32,9 @@ pytestmark = [
@parametrize_using_common_fixtures(
"cardano/get_native_script_hash.json",
)
def test_cardano_get_native_script_hash(client: Client, parameters, result):
client.init_device(new_session=True, derive_cardano=True)
def test_cardano_get_native_script_hash(session: Session, parameters, result):
native_script_hash = get_native_script_hash(
client,
session,
native_script=parse_native_script(parameters["native_script"]),
display_format=messages.CardanoNativeScriptHashDisplayFormat.__members__[
parameters["display_format"]

View File

@ -18,6 +18,7 @@ import pytest
from trezorlib import cardano, device, messages
from trezorlib.debuglink import LayoutType
from trezorlib.debuglink import SessionDebugWrapper as Session
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.exceptions import TrezorFailure
@ -58,9 +59,9 @@ def show_details_input_flow(client: Client):
"cardano/sign_tx.plutus.json",
"cardano/sign_tx.slip39.json",
)
def test_cardano_sign_tx(client: Client, parameters, result):
def test_cardano_sign_tx(session: Session, parameters, result):
response = call_sign_tx(
client,
session,
parameters,
input_flow=lambda client: InputFlowConfirmAllWarnings(client).get(),
)
@ -68,8 +69,8 @@ def test_cardano_sign_tx(client: Client, parameters, result):
@parametrize_using_common_fixtures("cardano/sign_tx.show_details.json")
def test_cardano_sign_tx_show_details(client: Client, parameters, result):
response = call_sign_tx(client, parameters, show_details_input_flow, chunkify=True)
def test_cardano_sign_tx_show_details(session: Session, parameters, result):
response = call_sign_tx(session, parameters, show_details_input_flow, chunkify=True)
assert response == _transform_expected_result(result)
@ -79,13 +80,13 @@ def test_cardano_sign_tx_show_details(client: Client, parameters, result):
"cardano/sign_tx.multisig.failed.json",
"cardano/sign_tx.plutus.failed.json",
)
def test_cardano_sign_tx_failed(client: Client, parameters, result):
def test_cardano_sign_tx_failed(session: Session, parameters, result):
with pytest.raises(TrezorFailure, match=result["error_message"]):
call_sign_tx(client, parameters, None)
call_sign_tx(session, parameters, None)
def call_sign_tx(client: Client, parameters, input_flow=None, chunkify: bool = False):
client.init_device(new_session=True, derive_cardano=True)
def call_sign_tx(session: Session, parameters, input_flow=None, chunkify: bool = False):
# session.init_device(new_session=True, derive_cardano=True)
signing_mode = messages.CardanoTxSigningMode.__members__[parameters["signing_mode"]]
inputs = [cardano.parse_input(i) for i in parameters["inputs"]]
@ -116,18 +117,18 @@ def call_sign_tx(client: Client, parameters, input_flow=None, chunkify: bool = F
if parameters.get("security_checks") == "prompt":
device.apply_settings(
client, safety_checks=messages.SafetyCheckLevel.PromptTemporarily
session, safety_checks=messages.SafetyCheckLevel.PromptTemporarily
)
else:
device.apply_settings(client, safety_checks=messages.SafetyCheckLevel.Strict)
device.apply_settings(session, safety_checks=messages.SafetyCheckLevel.Strict)
with client:
with session.client as client:
if input_flow is not None:
client.watch_layout()
client.set_input_flow(input_flow(client))
return cardano.sign_tx(
client=client,
session=session,
signing_mode=signing_mode,
inputs=inputs,
outputs=outputs,

View File

@ -16,7 +16,7 @@
import pytest
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.debuglink import SessionDebugWrapper as Session
from trezorlib.eos import get_public_key
from trezorlib.tools import parse_path
@ -28,12 +28,12 @@ from ...input_flows import InputFlowShowXpubQRCode
@pytest.mark.eos
@pytest.mark.models("t2t1")
@pytest.mark.setup_client(mnemonic=MNEMONIC12)
def test_eos_get_public_key(client: Client):
with client:
def test_eos_get_public_key(session: Session):
with session.client as client:
IF = InputFlowShowXpubQRCode(client)
client.set_input_flow(IF.get())
public_key = get_public_key(
client, parse_path("m/44h/194h/0h/0/0"), show_display=True
session, parse_path("m/44h/194h/0h/0/0"), show_display=True
)
assert (
public_key.wif_public_key
@ -43,7 +43,7 @@ def test_eos_get_public_key(client: Client):
public_key.raw_public_key.hex()
== "02015fabe197c955036bab25f4e7c16558f9f672f9f625314ab1ec8f64f7b1198e"
)
public_key = get_public_key(client, parse_path("m/44h/194h/0h/0/1"))
public_key = get_public_key(session, parse_path("m/44h/194h/0h/0/1"))
assert (
public_key.wif_public_key
== "EOS5d1VP15RKxT4dSakWu2TFuEgnmaGC2ckfSvQwND7pZC1tXkfLP"
@ -52,7 +52,7 @@ def test_eos_get_public_key(client: Client):
public_key.raw_public_key.hex()
== "02608bc2c431521dee0b9d5f2fe34053e15fc3b20d2895e0abda857b9ed8e77a78"
)
public_key = get_public_key(client, parse_path("m/44h/194h/1h/0/0"))
public_key = get_public_key(session, parse_path("m/44h/194h/1h/0/0"))
assert (
public_key.wif_public_key
== "EOS7UuNeTf13nfcG85rDB7AHGugZi4C4wJ4ft12QRotqNfxdV2NvP"

View File

@ -17,7 +17,7 @@
import pytest
from trezorlib import eos
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.debuglink import SessionDebugWrapper as Session
from trezorlib.messages import EosSignedTx
from trezorlib.tools import parse_path
@ -35,7 +35,7 @@ pytestmark = [
@pytest.mark.parametrize("chunkify", (True, False))
def test_eos_signtx_transfer_token(client: Client, chunkify: bool):
def test_eos_signtx_transfer_token(session: Session, chunkify: bool):
transaction = {
"expiration": "2018-07-14T10:43:28",
"ref_block_num": 6439,
@ -60,8 +60,8 @@ def test_eos_signtx_transfer_token(client: Client, chunkify: bool):
"transaction_extensions": [],
}
with client:
resp = eos.sign_tx(client, ADDRESS_N, transaction, CHAIN_ID, chunkify=chunkify)
with session:
resp = eos.sign_tx(session, ADDRESS_N, transaction, CHAIN_ID, chunkify=chunkify)
assert isinstance(resp, EosSignedTx)
assert (
resp.signature
@ -69,7 +69,7 @@ def test_eos_signtx_transfer_token(client: Client, chunkify: bool):
)
def test_eos_signtx_buyram(client: Client):
def test_eos_signtx_buyram(session: Session):
transaction = {
"expiration": "2018-07-14T10:43:28",
"ref_block_num": 6439,
@ -93,8 +93,8 @@ def test_eos_signtx_buyram(client: Client):
"transaction_extensions": [],
}
with client:
resp = eos.sign_tx(client, ADDRESS_N, transaction, CHAIN_ID)
with session:
resp = eos.sign_tx(session, ADDRESS_N, transaction, CHAIN_ID)
assert isinstance(resp, EosSignedTx)
assert (
resp.signature
@ -102,7 +102,7 @@ def test_eos_signtx_buyram(client: Client):
)
def test_eos_signtx_buyrambytes(client: Client):
def test_eos_signtx_buyrambytes(session: Session):
transaction = {
"expiration": "2018-07-14T10:43:28",
"ref_block_num": 6439,
@ -126,8 +126,8 @@ def test_eos_signtx_buyrambytes(client: Client):
"transaction_extensions": [],
}
with client:
resp = eos.sign_tx(client, ADDRESS_N, transaction, CHAIN_ID)
with session:
resp = eos.sign_tx(session, ADDRESS_N, transaction, CHAIN_ID)
assert isinstance(resp, EosSignedTx)
assert (
resp.signature
@ -135,7 +135,7 @@ def test_eos_signtx_buyrambytes(client: Client):
)
def test_eos_signtx_sellram(client: Client):
def test_eos_signtx_sellram(session: Session):
transaction = {
"expiration": "2018-07-14T10:43:28",
"ref_block_num": 6439,
@ -155,8 +155,8 @@ def test_eos_signtx_sellram(client: Client):
"transaction_extensions": [],
}
with client:
resp = eos.sign_tx(client, ADDRESS_N, transaction, CHAIN_ID)
with session:
resp = eos.sign_tx(session, ADDRESS_N, transaction, CHAIN_ID)
assert isinstance(resp, EosSignedTx)
assert (
resp.signature
@ -164,7 +164,7 @@ def test_eos_signtx_sellram(client: Client):
)
def test_eos_signtx_delegate(client: Client):
def test_eos_signtx_delegate(session: Session):
transaction = {
"expiration": "2018-07-14T10:43:28",
"ref_block_num": 6439,
@ -190,8 +190,8 @@ def test_eos_signtx_delegate(client: Client):
"transaction_extensions": [],
}
with client:
resp = eos.sign_tx(client, ADDRESS_N, transaction, CHAIN_ID)
with session:
resp = eos.sign_tx(session, ADDRESS_N, transaction, CHAIN_ID)
assert isinstance(resp, EosSignedTx)
assert (
resp.signature
@ -199,7 +199,7 @@ def test_eos_signtx_delegate(client: Client):
)
def test_eos_signtx_undelegate(client: Client):
def test_eos_signtx_undelegate(session: Session):
transaction = {
"expiration": "2018-07-14T10:43:28",
"ref_block_num": 6439,
@ -224,8 +224,8 @@ def test_eos_signtx_undelegate(client: Client):
"transaction_extensions": [],
}
with client:
resp = eos.sign_tx(client, ADDRESS_N, transaction, CHAIN_ID)
with session:
resp = eos.sign_tx(session, ADDRESS_N, transaction, CHAIN_ID)
assert isinstance(resp, EosSignedTx)
assert (
resp.signature
@ -233,7 +233,7 @@ def test_eos_signtx_undelegate(client: Client):
)
def test_eos_signtx_refund(client: Client):
def test_eos_signtx_refund(session: Session):
transaction = {
"expiration": "2018-07-14T10:43:28",
"ref_block_num": 6439,
@ -253,8 +253,8 @@ def test_eos_signtx_refund(client: Client):
"transaction_extensions": [],
}
with client:
resp = eos.sign_tx(client, ADDRESS_N, transaction, CHAIN_ID)
with session:
resp = eos.sign_tx(session, ADDRESS_N, transaction, CHAIN_ID)
assert isinstance(resp, EosSignedTx)
assert (
resp.signature
@ -262,7 +262,7 @@ def test_eos_signtx_refund(client: Client):
)
def test_eos_signtx_linkauth(client: Client):
def test_eos_signtx_linkauth(session: Session):
transaction = {
"expiration": "2018-07-14T10:43:28",
"ref_block_num": 6439,
@ -287,8 +287,8 @@ def test_eos_signtx_linkauth(client: Client):
"transaction_extensions": [],
}
with client:
resp = eos.sign_tx(client, ADDRESS_N, transaction, CHAIN_ID)
with session:
resp = eos.sign_tx(session, ADDRESS_N, transaction, CHAIN_ID)
assert isinstance(resp, EosSignedTx)
assert (
resp.signature
@ -296,7 +296,7 @@ def test_eos_signtx_linkauth(client: Client):
)
def test_eos_signtx_unlinkauth(client: Client):
def test_eos_signtx_unlinkauth(session: Session):
transaction = {
"expiration": "2018-07-14T10:43:28",
"ref_block_num": 6439,
@ -320,8 +320,8 @@ def test_eos_signtx_unlinkauth(client: Client):
"transaction_extensions": [],
}
with client:
resp = eos.sign_tx(client, ADDRESS_N, transaction, CHAIN_ID)
with session:
resp = eos.sign_tx(session, ADDRESS_N, transaction, CHAIN_ID)
assert isinstance(resp, EosSignedTx)
assert (
resp.signature
@ -329,7 +329,7 @@ def test_eos_signtx_unlinkauth(client: Client):
)
def test_eos_signtx_updateauth(client: Client):
def test_eos_signtx_updateauth(session: Session):
transaction = {
"expiration": "2018-07-14T10:43:28",
"ref_block_num": 6439,
@ -376,8 +376,8 @@ def test_eos_signtx_updateauth(client: Client):
"transaction_extensions": [],
}
with client:
resp = eos.sign_tx(client, ADDRESS_N, transaction, CHAIN_ID)
with session:
resp = eos.sign_tx(session, ADDRESS_N, transaction, CHAIN_ID)
assert isinstance(resp, EosSignedTx)
assert (
resp.signature
@ -385,7 +385,7 @@ def test_eos_signtx_updateauth(client: Client):
)
def test_eos_signtx_deleteauth(client: Client):
def test_eos_signtx_deleteauth(session: Session):
transaction = {
"expiration": "2018-07-14T10:43:28",
"ref_block_num": 6439,
@ -405,8 +405,8 @@ def test_eos_signtx_deleteauth(client: Client):
"transaction_extensions": [],
}
with client:
resp = eos.sign_tx(client, ADDRESS_N, transaction, CHAIN_ID)
with session:
resp = eos.sign_tx(session, ADDRESS_N, transaction, CHAIN_ID)
assert isinstance(resp, EosSignedTx)
assert (
resp.signature
@ -414,7 +414,7 @@ def test_eos_signtx_deleteauth(client: Client):
)
def test_eos_signtx_vote(client: Client):
def test_eos_signtx_vote(session: Session):
transaction = {
"expiration": "2018-07-14T10:43:28",
"ref_block_num": 6439,
@ -468,8 +468,8 @@ def test_eos_signtx_vote(client: Client):
"transaction_extensions": [],
}
with client:
resp = eos.sign_tx(client, ADDRESS_N, transaction, CHAIN_ID)
with session:
resp = eos.sign_tx(session, ADDRESS_N, transaction, CHAIN_ID)
assert isinstance(resp, EosSignedTx)
assert (
resp.signature
@ -477,7 +477,7 @@ def test_eos_signtx_vote(client: Client):
)
def test_eos_signtx_vote_proxy(client: Client):
def test_eos_signtx_vote_proxy(session: Session):
transaction = {
"expiration": "2018-07-14T10:43:28",
"ref_block_num": 6439,
@ -497,8 +497,8 @@ def test_eos_signtx_vote_proxy(client: Client):
"transaction_extensions": [],
}
with client:
resp = eos.sign_tx(client, ADDRESS_N, transaction, CHAIN_ID)
with session:
resp = eos.sign_tx(session, ADDRESS_N, transaction, CHAIN_ID)
assert isinstance(resp, EosSignedTx)
assert (
resp.signature
@ -506,7 +506,7 @@ def test_eos_signtx_vote_proxy(client: Client):
)
def test_eos_signtx_unknown(client: Client):
def test_eos_signtx_unknown(session: Session):
transaction = {
"expiration": "2018-07-14T10:43:28",
"ref_block_num": 6439,
@ -526,8 +526,8 @@ def test_eos_signtx_unknown(client: Client):
"transaction_extensions": [],
}
with client:
resp = eos.sign_tx(client, ADDRESS_N, transaction, CHAIN_ID)
with session:
resp = eos.sign_tx(session, ADDRESS_N, transaction, CHAIN_ID)
assert isinstance(resp, EosSignedTx)
assert (
resp.signature
@ -535,7 +535,7 @@ def test_eos_signtx_unknown(client: Client):
)
def test_eos_signtx_newaccount(client: Client):
def test_eos_signtx_newaccount(session: Session):
transaction = {
"expiration": "2018-07-14T10:43:28",
"ref_block_num": 6439,
@ -602,8 +602,8 @@ def test_eos_signtx_newaccount(client: Client):
"transaction_extensions": [],
}
with client:
resp = eos.sign_tx(client, ADDRESS_N, transaction, CHAIN_ID)
with session:
resp = eos.sign_tx(session, ADDRESS_N, transaction, CHAIN_ID)
assert isinstance(resp, EosSignedTx)
assert (
resp.signature
@ -611,7 +611,7 @@ def test_eos_signtx_newaccount(client: Client):
)
def test_eos_signtx_setcontract(client: Client):
def test_eos_signtx_setcontract(session: Session):
transaction = {
"expiration": "2018-06-19T13:29:53",
"ref_block_num": 30587,
@ -638,8 +638,8 @@ def test_eos_signtx_setcontract(client: Client):
"context_free_data": [],
}
with client:
resp = eos.sign_tx(client, ADDRESS_N, transaction, CHAIN_ID)
with session:
resp = eos.sign_tx(session, ADDRESS_N, transaction, CHAIN_ID)
assert isinstance(resp, EosSignedTx)
assert (
resp.signature

View File

@ -5,7 +5,7 @@ from typing import Callable
import pytest
from trezorlib import ethereum
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.debuglink import SessionDebugWrapper as Session
from trezorlib.exceptions import TrezorFailure
from trezorlib.tools import parse_path
@ -40,60 +40,60 @@ DEFAULT_ERC20_PARAMS = {
}
def test_builtin(client: Client) -> None:
def test_builtin(session: Session) -> None:
# Ethereum (SLIP-44 60, chain_id 1) will sign without any definitions provided
ethereum.sign_tx(client, **DEFAULT_TX_PARAMS)
ethereum.sign_tx(session, **DEFAULT_TX_PARAMS)
def test_chain_id_allowed(client: Client) -> None:
def test_chain_id_allowed(session: Session) -> None:
# Any chain id is allowed as long as the SLIP44 stays the same
params = DEFAULT_TX_PARAMS.copy()
params.update(chain_id=222222)
ethereum.sign_tx(client, **params)
ethereum.sign_tx(session, **params)
def test_slip44_disallowed(client: Client) -> None:
def test_slip44_disallowed(session: Session) -> None:
# SLIP44 is not allowed without a valid network definition
params = DEFAULT_TX_PARAMS.copy()
params.update(n=parse_path("m/44h/66666h/0h/0/0"))
with pytest.raises(TrezorFailure, match="Forbidden key path"):
ethereum.sign_tx(client, **params)
ethereum.sign_tx(session, **params)
def test_slip44_external(client: Client) -> None:
def test_slip44_external(session: Session) -> None:
# to use a non-default SLIP44, a valid network definition must be provided
network = common.encode_network(chain_id=66666, slip44=66666)
params = DEFAULT_TX_PARAMS.copy()
params.update(n=parse_path("m/44h/66666h/0h/0/0"), chain_id=66666)
ethereum.sign_tx(client, **params, definitions=common.make_defs(network, None))
ethereum.sign_tx(session, **params, definitions=common.make_defs(network, None))
def test_slip44_external_disallowed(client: Client) -> None:
def test_slip44_external_disallowed(session: Session) -> None:
# network definition does not allow a different SLIP44
network = common.encode_network(chain_id=66666, slip44=66666)
params = DEFAULT_TX_PARAMS.copy()
params.update(n=parse_path("m/44h/55555h/0h/0/0"), chain_id=66666)
with pytest.raises(TrezorFailure, match="Forbidden key path"):
ethereum.sign_tx(client, **params, definitions=common.make_defs(network, None))
ethereum.sign_tx(session, **params, definitions=common.make_defs(network, None))
def test_chain_id_mismatch(client: Client) -> None:
def test_chain_id_mismatch(session: Session) -> None:
# network definition for a different chain id will be rejected
network = common.encode_network(chain_id=66666, slip44=60)
params = DEFAULT_TX_PARAMS.copy()
params.update(chain_id=55555)
with pytest.raises(TrezorFailure, match="Network definition mismatch"):
ethereum.sign_tx(client, **params, definitions=common.make_defs(network, None))
ethereum.sign_tx(session, **params, definitions=common.make_defs(network, None))
def test_definition_does_not_override_builtin(client: Client) -> None:
def test_definition_does_not_override_builtin(session: Session) -> None:
# The builtin definition for Ethereum (SLIP44 60, chain_id 1) will be used
# even if a valid definition with a different SLIP44 is provided
network = common.encode_network(chain_id=1, slip44=66666)
params = DEFAULT_TX_PARAMS.copy()
params.update(n=parse_path("m/44h/66666h/0h/0/0"), chain_id=1)
with pytest.raises(TrezorFailure, match="Forbidden key path"):
ethereum.sign_tx(client, **params, definitions=common.make_defs(network, None))
ethereum.sign_tx(session, **params, definitions=common.make_defs(network, None))
# TODO: test that the builtin definition will not show different symbol
@ -102,50 +102,50 @@ def test_definition_does_not_override_builtin(client: Client) -> None:
# all tokens are currently accepted, we would need to check the screenshots
def test_builtin_token(client: Client) -> None:
def test_builtin_token(session: Session) -> None:
# The builtin definition for USDT (ERC20) will be used even if not provided
params = DEFAULT_ERC20_PARAMS.copy()
params.update(to=ERC20_BUILTIN_TOKEN)
ethereum.sign_tx(client, **params)
ethereum.sign_tx(session, **params)
# TODO check that USDT symbol is shown
# TODO: test_builtin_token_not_overriden (builtin definition is used even if a custom one is provided)
def test_external_token(client: Client) -> None:
def test_external_token(session: Session) -> None:
# A valid token definition must be provided to use a non-builtin token
token = common.encode_token(address=ERC20_FAKE_ADDRESS, chain_id=1, decimals=8)
params = DEFAULT_ERC20_PARAMS.copy()
params.update(to=ERC20_FAKE_ADDRESS)
ethereum.sign_tx(client, **params, definitions=common.make_defs(None, token))
ethereum.sign_tx(session, **params, definitions=common.make_defs(None, token))
# TODO check that FakeTok symbol is shown
def test_external_chain_without_token(client: Client) -> None:
with client:
def test_external_chain_without_token(session: Session) -> None:
with session, session.client as client:
if not client.debug.legacy_debug:
client.set_input_flow(InputFlowConfirmAllWarnings(client).get())
# when using an external chains, unknown tokens are allowed
network = common.encode_network(chain_id=66666, slip44=60)
params = DEFAULT_ERC20_PARAMS.copy()
params.update(to=ERC20_BUILTIN_TOKEN, chain_id=66666)
ethereum.sign_tx(client, **params, definitions=common.make_defs(network, None))
ethereum.sign_tx(session, **params, definitions=common.make_defs(network, None))
# TODO check that UNKN token is used, FAKE network
def test_external_chain_token_ok(client: Client) -> None:
def test_external_chain_token_ok(session: Session) -> None:
# when providing an external chain and matching token, everything works
network = common.encode_network(chain_id=66666, slip44=60)
token = common.encode_token(address=ERC20_FAKE_ADDRESS, chain_id=66666, decimals=8)
params = DEFAULT_ERC20_PARAMS.copy()
params.update(to=ERC20_FAKE_ADDRESS, chain_id=66666)
ethereum.sign_tx(client, **params, definitions=common.make_defs(network, token))
ethereum.sign_tx(session, **params, definitions=common.make_defs(network, token))
# TODO check that FakeTok is used, FAKE network
def test_external_chain_token_mismatch(client: Client) -> None:
with client:
def test_external_chain_token_mismatch(session: Session) -> None:
with session, session.client as client:
if not client.debug.legacy_debug:
client.set_input_flow(InputFlowConfirmAllWarnings(client).get())
# when providing external defs, we explicitly allow, but not use, tokens
@ -156,31 +156,33 @@ def test_external_chain_token_mismatch(client: Client) -> None:
)
params = DEFAULT_ERC20_PARAMS.copy()
params.update(to=ERC20_FAKE_ADDRESS, chain_id=66666)
ethereum.sign_tx(client, **params, definitions=common.make_defs(network, token))
ethereum.sign_tx(
session, **params, definitions=common.make_defs(network, token)
)
# TODO check that UNKN is used for token, FAKE for network
def _call_getaddress(client: Client, slip44: int, network: bytes | None) -> None:
def _call_getaddress(session: Session, slip44: int, network: bytes | None) -> None:
ethereum.get_address(
client,
session,
parse_path(f"m/44h/{slip44}h/0h"),
show_display=False,
encoded_network=network,
)
def _call_signmessage(client: Client, slip44: int, network: bytes | None) -> None:
def _call_signmessage(session: Session, slip44: int, network: bytes | None) -> None:
ethereum.sign_message(
client,
session,
parse_path(f"m/44h/{slip44}h/0h"),
b"hello",
encoded_network=network,
)
def _call_sign_typed_data(client: Client, slip44: int, network: bytes | None) -> None:
def _call_sign_typed_data(session: Session, slip44: int, network: bytes | None) -> None:
ethereum.sign_typed_data(
client,
session,
parse_path(f"m/44h/{slip44}h/0h/0/0"),
TYPED_DATA,
metamask_v4_compat=True,
@ -189,10 +191,10 @@ def _call_sign_typed_data(client: Client, slip44: int, network: bytes | None) ->
def _call_sign_typed_data_hash(
client: Client, slip44: int, network: bytes | None
session: Session, slip44: int, network: bytes | None
) -> None:
ethereum.sign_typed_data_hash(
client,
session,
parse_path(f"m/44h/{slip44}h/0h/0/0"),
b"\x00" * 32,
b"\xff" * 32,
@ -200,7 +202,7 @@ def _call_sign_typed_data_hash(
)
MethodType = Callable[[Client, int, "bytes | None"], None]
MethodType = Callable[[Session, int, "bytes | None"], None]
METHODS = (
@ -212,29 +214,29 @@ METHODS = (
@pytest.mark.parametrize("method", METHODS)
def test_method_builtin(client: Client, method: MethodType) -> None:
def test_method_builtin(session: Session, method: MethodType) -> None:
# calling a method with a builtin slip44 will work
method(client, 60, None)
method(session, 60, None)
@pytest.mark.parametrize("method", METHODS)
def test_method_def_missing(client: Client, method: MethodType) -> None:
def test_method_def_missing(session: Session, method: MethodType) -> None:
# calling a method with a slip44 that has no definition will fail
with pytest.raises(TrezorFailure, match="Forbidden key path"):
method(client, 66666, None)
method(session, 66666, None)
@pytest.mark.parametrize("method", METHODS)
def test_method_external(client: Client, method: MethodType) -> None:
def test_method_external(session: Session, method: MethodType) -> None:
# calling a method with a slip44 that has an external definition will work
network = common.encode_network(slip44=66666)
method(client, 66666, network)
method(session, 66666, network)
@pytest.mark.parametrize("method", METHODS)
def test_method_external_mismatch(client: Client, method: MethodType) -> None:
def test_method_external_mismatch(session: Session, method: MethodType) -> None:
# calling a method with a slip44 that has an external definition that does not match
# the slip44 will fail
network = common.encode_network(slip44=77777)
with pytest.raises(TrezorFailure, match="Network definition mismatch"):
method(client, 66666, network)
method(session, 66666, network)

View File

@ -5,7 +5,7 @@ from hashlib import sha256
import pytest
from trezorlib import ethereum
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.debuglink import SessionDebugWrapper as Session
from trezorlib.exceptions import TrezorFailure
from trezorlib.messages import EthereumDefinitionType
from trezorlib.tools import parse_path
@ -16,99 +16,99 @@ from .test_definitions import DEFAULT_ERC20_PARAMS, ERC20_FAKE_ADDRESS
pytestmark = [pytest.mark.altcoin, pytest.mark.ethereum]
def fails(client: Client, network: bytes, match: str) -> None:
def fails(session: Session, network: bytes, match: str) -> None:
with pytest.raises(TrezorFailure, match=match):
ethereum.get_address(
client,
session,
parse_path("m/44h/666666h/0h"),
show_display=False,
encoded_network=network,
)
def test_short_message(client: Client) -> None:
fails(client, b"\x00", "Invalid Ethereum definition")
def test_short_message(session: Session) -> None:
fails(session, b"\x00", "Invalid Ethereum definition")
def test_mangled_signature(client: Client) -> None:
def test_mangled_signature(session: Session) -> None:
payload = make_payload()
proof, signature = sign_payload(payload, [])
bad_signature = signature[:-1] + b"\xff"
fails(client, payload + proof + bad_signature, "Invalid definition signature")
fails(session, payload + proof + bad_signature, "Invalid definition signature")
def test_not_enough_signatures(client: Client) -> None:
def test_not_enough_signatures(session: Session) -> None:
payload = make_payload()
proof, signature = sign_payload(payload, [], threshold=1)
fails(client, payload + proof + signature, "Invalid definition signature")
fails(session, payload + proof + signature, "Invalid definition signature")
def test_missing_signature(client: Client) -> None:
def test_missing_signature(session: Session) -> None:
payload = make_payload()
proof, _ = sign_payload(payload, [])
fails(client, payload + proof, "Invalid Ethereum definition")
fails(session, payload + proof, "Invalid Ethereum definition")
def test_mangled_payload(client: Client) -> None:
def test_mangled_payload(session: Session) -> None:
payload = make_payload()
proof, signature = sign_payload(payload, [])
bad_payload = payload[:-1] + b"\xff"
fails(client, bad_payload + proof + signature, "Invalid definition signature")
fails(session, bad_payload + proof + signature, "Invalid definition signature")
def test_proof_length_mismatch(client: Client) -> None:
def test_proof_length_mismatch(session: Session) -> None:
payload = make_payload()
_, signature = sign_payload(payload, [])
bad_proof = b"\x01"
fails(client, payload + bad_proof + signature, "Invalid Ethereum definition")
fails(session, payload + bad_proof + signature, "Invalid Ethereum definition")
def test_bad_proof(client: Client) -> None:
def test_bad_proof(session: Session) -> None:
payload = make_payload()
proof, signature = sign_payload(payload, [sha256(b"x").digest()])
bad_proof = proof[:-1] + b"\xff"
fails(client, payload + bad_proof + signature, "Invalid definition signature")
fails(session, payload + bad_proof + signature, "Invalid definition signature")
def test_trimmed_proof(client: Client) -> None:
def test_trimmed_proof(session: Session) -> None:
payload = make_payload()
proof, signature = sign_payload(payload, [])
bad_proof = proof[:-1]
fails(client, payload + bad_proof + signature, "Invalid Ethereum definition")
fails(session, payload + bad_proof + signature, "Invalid Ethereum definition")
def test_bad_prefix(client: Client) -> None:
def test_bad_prefix(session: Session) -> None:
payload = make_payload()
payload = b"trzd2" + payload[5:]
proof, signature = sign_payload(payload, [])
fails(client, payload + proof + signature, "Invalid Ethereum definition")
fails(session, payload + proof + signature, "Invalid Ethereum definition")
def test_bad_type(client: Client) -> None:
def test_bad_type(session: Session) -> None:
# assuming we expect a network definition
payload = make_payload(data_type=EthereumDefinitionType.TOKEN, message=make_token())
proof, signature = sign_payload(payload, [])
fails(client, payload + proof + signature, "Definition type mismatch")
fails(session, payload + proof + signature, "Definition type mismatch")
def test_outdated(client: Client) -> None:
def test_outdated(session: Session) -> None:
payload = make_payload(timestamp=0)
proof, signature = sign_payload(payload, [])
fails(client, payload + proof + signature, "Definition is outdated")
fails(session, payload + proof + signature, "Definition is outdated")
def test_malformed_protobuf(client: Client) -> None:
def test_malformed_protobuf(session: Session) -> None:
payload = make_payload(message=b"\x00")
proof, signature = sign_payload(payload, [])
fails(client, payload + proof + signature, "Invalid Ethereum definition")
fails(session, payload + proof + signature, "Invalid Ethereum definition")
def test_protobuf_mismatch(client: Client) -> None:
def test_protobuf_mismatch(session: Session) -> None:
payload = make_payload(
data_type=EthereumDefinitionType.NETWORK, message=make_token()
)
proof, signature = sign_payload(payload, [])
fails(client, payload + proof + signature, "Invalid Ethereum definition")
fails(session, payload + proof + signature, "Invalid Ethereum definition")
payload = make_payload(
data_type=EthereumDefinitionType.TOKEN, message=make_network()
@ -119,13 +119,13 @@ def test_protobuf_mismatch(client: Client) -> None:
params = DEFAULT_ERC20_PARAMS.copy()
params.update(to=ERC20_FAKE_ADDRESS)
ethereum.sign_tx(
client,
session,
**params,
definitions=make_defs(None, payload + proof + signature),
)
def test_trailing_garbage(client: Client) -> None:
def test_trailing_garbage(session: Session) -> None:
payload = make_payload()
proof, signature = sign_payload(payload, [])
fails(client, payload + proof + signature + b"\x00", "Invalid Ethereum definition")
fails(session, payload + proof + signature + b"\x00", "Invalid Ethereum definition")

View File

@ -17,7 +17,7 @@
import pytest
from trezorlib import ethereum
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.debuglink import SessionDebugWrapper as Session
from trezorlib.tools import parse_path
from ...common import parametrize_using_common_fixtures
@ -27,21 +27,21 @@ pytestmark = [pytest.mark.altcoin, pytest.mark.ethereum]
@parametrize_using_common_fixtures("ethereum/getaddress.json")
def test_getaddress(client: Client, parameters, result):
def test_getaddress(session: Session, parameters, result):
address_n = parse_path(parameters["path"])
assert (
ethereum.get_address(client, address_n, show_display=True) == result["address"]
ethereum.get_address(session, address_n, show_display=True) == result["address"]
)
@pytest.mark.models("core", reason="No input flow for T1")
@parametrize_using_common_fixtures("ethereum/getaddress.json")
def test_getaddress_chunkify_details(client: Client, parameters, result):
with client:
def test_getaddress_chunkify_details(session: Session, parameters, result):
with session.client as client:
IF = InputFlowShowAddressQRCode(client)
client.set_input_flow(IF.get())
address_n = parse_path(parameters["path"])
assert (
ethereum.get_address(client, address_n, show_display=True, chunkify=True)
ethereum.get_address(session, address_n, show_display=True, chunkify=True)
== result["address"]
)

View File

@ -17,7 +17,7 @@
import pytest
from trezorlib import ethereum
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.debuglink import SessionDebugWrapper as Session
from trezorlib.exceptions import TrezorFailure
from trezorlib.tools import parse_path
@ -27,9 +27,9 @@ pytestmark = [pytest.mark.altcoin, pytest.mark.ethereum]
@parametrize_using_common_fixtures("ethereum/getpublickey.json")
def test_ethereum_getpublickey(client: Client, parameters, result):
def test_ethereum_getpublickey(session: Session, parameters, result):
path = parse_path(parameters["path"])
res = ethereum.get_public_node(client, path)
res = ethereum.get_public_node(session, path)
assert res.node.depth == len(path)
assert res.node.fingerprint == result["fingerprint"]
assert res.node.child_num == result["child_num"]
@ -38,14 +38,14 @@ def test_ethereum_getpublickey(client: Client, parameters, result):
assert res.xpub == result["xpub"]
def test_slip25_disallowed(client: Client):
def test_slip25_disallowed(session: Session):
path = parse_path("m/10025'/60'/0'/0/0")
with pytest.raises(TrezorFailure):
ethereum.get_public_node(client, path)
ethereum.get_public_node(session, path)
@pytest.mark.models("legacy")
def test_legacy_restrictions(client: Client):
def test_legacy_restrictions(session: Session):
path = parse_path("m/46'")
with pytest.raises(TrezorFailure, match="Invalid path for EthereumGetPublicKey"):
ethereum.get_public_node(client, path)
ethereum.get_public_node(session, path)

View File

@ -17,7 +17,7 @@
import pytest
from trezorlib import ethereum, exceptions
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.debuglink import SessionDebugWrapper as Session
from trezorlib.tools import parse_path
from ...common import parametrize_using_common_fixtures
@ -28,11 +28,11 @@ pytestmark = [pytest.mark.altcoin, pytest.mark.ethereum]
@pytest.mark.models("core")
@parametrize_using_common_fixtures("ethereum/sign_typed_data.json")
def test_ethereum_sign_typed_data(client: Client, parameters, result):
with client:
def test_ethereum_sign_typed_data(session: Session, parameters, result):
with session:
address_n = parse_path(parameters["path"])
ret = ethereum.sign_typed_data(
client,
session,
address_n,
parameters["data"],
metamask_v4_compat=parameters["metamask_v4_compat"],
@ -43,11 +43,11 @@ def test_ethereum_sign_typed_data(client: Client, parameters, result):
@pytest.mark.models("legacy")
@parametrize_using_common_fixtures("ethereum/sign_typed_data.json")
def test_ethereum_sign_typed_data_blind(client: Client, parameters, result):
with client:
def test_ethereum_sign_typed_data_blind(session: Session, parameters, result):
with session:
address_n = parse_path(parameters["path"])
ret = ethereum.sign_typed_data_hash(
client,
session,
address_n,
ethereum.decode_hex(parameters["domain_separator_hash"]),
# message hash is empty for domain-only hashes
@ -96,13 +96,13 @@ DATA = {
@pytest.mark.models("core", skip="mercury", reason="Not yet implemented in new UI")
def test_ethereum_sign_typed_data_show_more_button(client: Client):
with client:
def test_ethereum_sign_typed_data_show_more_button(session: Session):
with session.client as client:
client.watch_layout()
IF = InputFlowEIP712ShowMore(client)
client.set_input_flow(IF.get())
ethereum.sign_typed_data(
client,
session,
parse_path("m/44h/60h/0h/0/0"),
DATA,
metamask_v4_compat=True,
@ -110,13 +110,13 @@ def test_ethereum_sign_typed_data_show_more_button(client: Client):
@pytest.mark.models("core")
def test_ethereum_sign_typed_data_cancel(client: Client):
with client, pytest.raises(exceptions.Cancelled):
def test_ethereum_sign_typed_data_cancel(session: Session):
with session.client as client, pytest.raises(exceptions.Cancelled):
client.watch_layout()
IF = InputFlowEIP712Cancel(client)
client.set_input_flow(IF.get())
ethereum.sign_typed_data(
client,
session,
parse_path("m/44h/60h/0h/0/0"),
DATA,
metamask_v4_compat=True,

View File

@ -17,7 +17,7 @@
import pytest
from trezorlib import ethereum
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.debuglink import SessionDebugWrapper as Session
from trezorlib.tools import parse_path
from ...common import parametrize_using_common_fixtures
@ -26,18 +26,18 @@ pytestmark = [pytest.mark.altcoin, pytest.mark.ethereum]
@parametrize_using_common_fixtures("ethereum/signmessage.json")
def test_signmessage(client: Client, parameters, result):
def test_signmessage(session: Session, parameters, result):
res = ethereum.sign_message(
client, parse_path(parameters["path"]), parameters["msg"]
session, parse_path(parameters["path"]), parameters["msg"]
)
assert res.address == result["address"]
assert res.signature.hex() == result["sig"]
@parametrize_using_common_fixtures("ethereum/verifymessage.json")
def test_verify(client: Client, parameters, result):
def test_verify(session: Session, parameters, result):
res = ethereum.verify_message(
client,
session,
parameters["address"],
bytes.fromhex(parameters["sig"]),
parameters["msg"],
@ -45,7 +45,7 @@ def test_verify(client: Client, parameters, result):
assert res is True
def test_verify_invalid(client: Client):
def test_verify_invalid(session: Session):
# First vector from the verifymessage JSON fixture
msg = "This is an example of a signed message."
address = "0xEa53AF85525B1779eE99ece1a5560C0b78537C3b"
@ -54,7 +54,7 @@ def test_verify_invalid(client: Client):
)
res = ethereum.verify_message(
client,
session,
address,
sig,
msg,
@ -63,7 +63,7 @@ def test_verify_invalid(client: Client):
# Changing the signature, expecting failure
res = ethereum.verify_message(
client,
session,
address,
sig[:-1] + b"\x00",
msg,
@ -72,7 +72,7 @@ def test_verify_invalid(client: Client):
# Changing the message, expecting failure
res = ethereum.verify_message(
client,
session,
address,
sig,
msg + "abc",
@ -81,7 +81,7 @@ def test_verify_invalid(client: Client):
# Changing the address, expecting failure
res = ethereum.verify_message(
client,
session,
address[:-1] + "a",
sig,
msg,

View File

@ -17,6 +17,7 @@
import pytest
from trezorlib import ethereum, exceptions, messages, models
from trezorlib.debuglink import SessionDebugWrapper as Session
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.debuglink import message_filters
from trezorlib.exceptions import TrezorFailure
@ -56,28 +57,28 @@ def make_defs(parameters: dict) -> messages.EthereumDefinitions:
"ethereum/sign_tx_eip155.json",
)
@pytest.mark.parametrize("chunkify", (True, False))
def test_signtx(client: Client, chunkify: bool, parameters: dict, result: dict):
def test_signtx(session: Session, chunkify: bool, parameters: dict, result: dict):
input_flow = (
InputFlowConfirmAllWarnings(client).get()
if not client.debug.legacy_debug
InputFlowConfirmAllWarnings(session.client).get()
if not session.client.debug.legacy_debug
else None
)
_do_test_signtx(client, parameters, result, input_flow, chunkify=chunkify)
_do_test_signtx(session, parameters, result, input_flow, chunkify=chunkify)
def _do_test_signtx(
client: Client,
session: Session,
parameters: dict,
result: dict,
input_flow=None,
chunkify: bool = False,
):
with client:
with session.client as client:
if input_flow:
client.watch_layout()
client.set_input_flow(input_flow)
sig_v, sig_r, sig_s = ethereum.sign_tx(
client,
session,
n=parse_path(parameters["path"]),
nonce=int(parameters["nonce"], 16),
gas_price=int(parameters["gas_price"], 16),
@ -120,10 +121,10 @@ example_input_data = {
@pytest.mark.models("core", reason="T1 does not support input flows")
def test_signtx_fee_info(client: Client):
input_flow = InputFlowEthereumSignTxShowFeeInfo(client).get()
def test_signtx_fee_info(session: Session):
input_flow = InputFlowEthereumSignTxShowFeeInfo(session.client).get()
_do_test_signtx(
client,
session,
example_input_data["parameters"],
example_input_data["result"],
input_flow,
@ -135,10 +136,10 @@ def test_signtx_fee_info(client: Client):
skip="mercury",
reason="T1 does not support input flows; Mercury can't send Cancel on Summary",
)
def test_signtx_go_back_from_summary(client: Client):
input_flow = InputFlowEthereumSignTxGoBackFromSummary(client).get()
def test_signtx_go_back_from_summary(session: Session):
input_flow = InputFlowEthereumSignTxGoBackFromSummary(session.client).get()
_do_test_signtx(
client,
session,
example_input_data["parameters"],
example_input_data["result"],
input_flow,
@ -147,12 +148,14 @@ def test_signtx_go_back_from_summary(client: Client):
@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:
def test_signtx_eip1559(
session: Session, chunkify: bool, parameters: dict, result: dict
):
with session, session.client as client:
if not client.debug.legacy_debug:
client.set_input_flow(InputFlowConfirmAllWarnings(client).get())
sig_v, sig_r, sig_s = ethereum.sign_tx_eip1559(
client,
session,
n=parse_path(parameters["path"]),
nonce=int(parameters["nonce"], 16),
gas_limit=int(parameters["gas_limit"], 16),
@ -171,14 +174,14 @@ def test_signtx_eip1559(client: Client, chunkify: bool, parameters: dict, result
assert sig_v == result["sig_v"]
def test_sanity_checks(client: Client):
def test_sanity_checks(session: Session):
"""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,
session,
n=parse_path("m/44h/60h/0h/0/0"),
nonce=123_456,
gas_price=20_000,
@ -191,7 +194,7 @@ def test_sanity_checks(client: Client):
# gas overflow
with pytest.raises(TrezorFailure, match=r"DataError"):
ethereum.sign_tx(
client,
session,
n=parse_path("m/44h/60h/0h/0/0"),
nonce=123_456,
gas_price=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF,
@ -204,7 +207,7 @@ def test_sanity_checks(client: Client):
# bad chain ID
with pytest.raises(TrezorFailure, match=r"Chain ID out of bounds"):
ethereum.sign_tx(
client,
session,
n=parse_path("m/44h/60h/0h/0/0"),
nonce=123_456,
gas_price=20_000,
@ -215,13 +218,13 @@ def test_sanity_checks(client: Client):
)
def test_data_streaming(client: Client):
def test_data_streaming(session: Session):
"""Only verifying the expected responses, the signatures are
checked in vectorized function above.
"""
with client:
is_t1 = client.model is models.T1B1
client.set_expected_responses(
with session:
is_t1 = session.model is models.T1B1
session.set_expected_responses(
[
messages.ButtonRequest(code=messages.ButtonRequestType.SignTx),
(is_t1, messages.ButtonRequest(code=messages.ButtonRequestType.SignTx)),
@ -259,7 +262,7 @@ def test_data_streaming(client: Client):
)
ethereum.sign_tx(
client,
session,
n=parse_path("m/44h/60h/0h/0/0"),
nonce=0,
gas_price=20_000,
@ -271,11 +274,11 @@ def test_data_streaming(client: Client):
)
def test_signtx_eip1559_access_list(client: Client):
with client:
def test_signtx_eip1559_access_list(session: Session):
with session:
sig_v, sig_r, sig_s = ethereum.sign_tx_eip1559(
client,
session,
n=parse_path("m/44h/60h/0h/0/100"),
nonce=0,
gas_limit=20,
@ -310,11 +313,11 @@ def test_signtx_eip1559_access_list(client: Client):
)
def test_signtx_eip1559_access_list_larger(client: Client):
with client:
def test_signtx_eip1559_access_list_larger(session: Session):
with session:
sig_v, sig_r, sig_s = ethereum.sign_tx_eip1559(
client,
session,
n=parse_path("m/44h/60h/0h/0/100"),
nonce=0,
gas_limit=20,
@ -363,14 +366,14 @@ def test_signtx_eip1559_access_list_larger(client: Client):
)
def test_sanity_checks_eip1559(client: Client):
def test_sanity_checks_eip1559(session: Session):
"""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,
session,
n=parse_path("m/44h/60h/0h/0/100"),
nonce=0,
gas_limit=20,
@ -384,7 +387,7 @@ def test_sanity_checks_eip1559(client: Client):
# max fee overflow
with pytest.raises(TrezorFailure, match=r"DataError"):
ethereum.sign_tx_eip1559(
client,
session,
n=parse_path("m/44h/60h/0h/0/100"),
nonce=0,
gas_limit=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF,
@ -398,7 +401,7 @@ def test_sanity_checks_eip1559(client: Client):
# priority fee overflow
with pytest.raises(TrezorFailure, match=r"DataError"):
ethereum.sign_tx_eip1559(
client,
session,
n=parse_path("m/44h/60h/0h/0/100"),
nonce=0,
gas_limit=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF,
@ -412,7 +415,7 @@ def test_sanity_checks_eip1559(client: Client):
# bad chain ID
with pytest.raises(TrezorFailure, match=r"Chain ID out of bounds"):
ethereum.sign_tx_eip1559(
client,
session,
n=parse_path("m/44h/60h/0h/0/100"),
nonce=0,
gas_limit=20,
@ -443,10 +446,10 @@ HEXDATA = "0123456789abcd000023456789abcd010003456789abcd020000456789abcd0300000
"flow", (input_flow_data_skip, input_flow_data_scroll_down, input_flow_data_go_back)
)
@pytest.mark.models("core", skip="mercury", reason="Not yet implemented in new UI")
def test_signtx_data_pagination(client: Client, flow):
def test_signtx_data_pagination(session: Session, flow):
def _sign_tx_call():
ethereum.sign_tx(
client,
session,
n=parse_path("m/44h/60h/0h/0/0"),
nonce=0x0,
gas_price=0x14,
@ -458,13 +461,13 @@ def test_signtx_data_pagination(client: Client, flow):
data=bytes.fromhex(HEXDATA),
)
with client:
with session, session.client as client:
client.watch_layout()
client.set_input_flow(flow(client))
_sign_tx_call()
if flow is not input_flow_data_scroll_down:
with client, pytest.raises(exceptions.Cancelled):
with session, session.client as client, pytest.raises(exceptions.Cancelled):
client.watch_layout()
client.set_input_flow(flow(client, cancel=True))
_sign_tx_call()
@ -473,20 +476,22 @@ def test_signtx_data_pagination(client: Client, flow):
@pytest.mark.models("core")
@parametrize_using_common_fixtures("ethereum/sign_tx_staking.json")
@pytest.mark.parametrize("chunkify", (True, False))
def test_signtx_staking(client: Client, chunkify: bool, parameters: dict, result: dict):
input_flow = InputFlowEthereumSignTxStaking(client).get()
def test_signtx_staking(
session: Session, chunkify: bool, parameters: dict, result: dict
):
input_flow = InputFlowEthereumSignTxStaking(session.client).get()
_do_test_signtx(
client, parameters, result, input_flow=input_flow, chunkify=chunkify
session, parameters, result, input_flow=input_flow, chunkify=chunkify
)
@pytest.mark.models("core")
@parametrize_using_common_fixtures("ethereum/sign_tx_staking_data_error.json")
def test_signtx_staking_bad_inputs(client: Client, parameters: dict, result: dict):
def test_signtx_staking_bad_inputs(session: Session, parameters: dict, result: dict):
# result not needed
with pytest.raises(TrezorFailure, match=r"DataError"):
ethereum.sign_tx(
client,
session,
n=parse_path(parameters["path"]),
nonce=int(parameters["nonce"], 16),
gas_price=int(parameters["gas_price"], 16),
@ -503,10 +508,10 @@ def test_signtx_staking_bad_inputs(client: Client, parameters: dict, result: dic
@pytest.mark.models("core")
@parametrize_using_common_fixtures("ethereum/sign_tx_staking_eip1559.json")
def test_signtx_staking_eip1559(client: Client, parameters: dict, result: dict):
with client:
def test_signtx_staking_eip1559(session: Session, parameters: dict, result: dict):
with session:
sig_v, sig_r, sig_s = ethereum.sign_tx_eip1559(
client,
session,
n=parse_path(parameters["path"]),
nonce=int(parameters["nonce"], 16),
max_gas_fee=int(parameters["max_gas_fee"], 16),

View File

@ -17,15 +17,15 @@
import pytest
from trezorlib import misc
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.debuglink import SessionDebugWrapper as Session
from ...common import MNEMONIC12
@pytest.mark.setup_client(mnemonic=MNEMONIC12)
def test_encrypt(client: Client):
def test_encrypt(session: Session):
res = misc.encrypt_keyvalue(
client,
session,
[0, 1, 2],
"test",
b"testing message!",
@ -35,7 +35,7 @@ def test_encrypt(client: Client):
assert res.hex() == "676faf8f13272af601776bc31bc14e8f"
res = misc.encrypt_keyvalue(
client,
session,
[0, 1, 2],
"test",
b"testing message!",
@ -45,7 +45,7 @@ def test_encrypt(client: Client):
assert res.hex() == "5aa0fbcb9d7fa669880745479d80c622"
res = misc.encrypt_keyvalue(
client,
session,
[0, 1, 2],
"test",
b"testing message!",
@ -55,7 +55,7 @@ def test_encrypt(client: Client):
assert res.hex() == "958d4f63269b61044aaedc900c8d6208"
res = misc.encrypt_keyvalue(
client,
session,
[0, 1, 2],
"test",
b"testing message!",
@ -66,7 +66,7 @@ def test_encrypt(client: Client):
# different key
res = misc.encrypt_keyvalue(
client,
session,
[0, 1, 2],
"test2",
b"testing message!",
@ -77,7 +77,7 @@ def test_encrypt(client: Client):
# different message
res = misc.encrypt_keyvalue(
client,
session,
[0, 1, 2],
"test",
b"testing message! it is different",
@ -90,7 +90,7 @@ def test_encrypt(client: Client):
# different path
res = misc.encrypt_keyvalue(
client,
session,
[0, 1, 3],
"test",
b"testing message!",
@ -101,9 +101,9 @@ def test_encrypt(client: Client):
@pytest.mark.setup_client(mnemonic=MNEMONIC12)
def test_decrypt(client: Client):
def test_decrypt(session: Session):
res = misc.decrypt_keyvalue(
client,
session,
[0, 1, 2],
"test",
bytes.fromhex("676faf8f13272af601776bc31bc14e8f"),
@ -113,7 +113,7 @@ def test_decrypt(client: Client):
assert res == b"testing message!"
res = misc.decrypt_keyvalue(
client,
session,
[0, 1, 2],
"test",
bytes.fromhex("5aa0fbcb9d7fa669880745479d80c622"),
@ -123,7 +123,7 @@ def test_decrypt(client: Client):
assert res == b"testing message!"
res = misc.decrypt_keyvalue(
client,
session,
[0, 1, 2],
"test",
bytes.fromhex("958d4f63269b61044aaedc900c8d6208"),
@ -133,7 +133,7 @@ def test_decrypt(client: Client):
assert res == b"testing message!"
res = misc.decrypt_keyvalue(
client,
session,
[0, 1, 2],
"test",
bytes.fromhex("e0cf0eb0425947000eb546cc3994bc6c"),
@ -144,7 +144,7 @@ def test_decrypt(client: Client):
# different key
res = misc.decrypt_keyvalue(
client,
session,
[0, 1, 2],
"test2",
bytes.fromhex("de247a6aa6be77a134bb3f3f925f13af"),
@ -155,7 +155,7 @@ def test_decrypt(client: Client):
# different message
res = misc.decrypt_keyvalue(
client,
session,
[0, 1, 2],
"test",
bytes.fromhex(
@ -168,7 +168,7 @@ def test_decrypt(client: Client):
# different path
res = misc.decrypt_keyvalue(
client,
session,
[0, 1, 3],
"test",
bytes.fromhex("b4811a9d492f5355a5186ddbfccaae7b"),
@ -178,11 +178,11 @@ def test_decrypt(client: Client):
assert res == b"testing message!"
def test_encrypt_badlen(client: Client):
def test_encrypt_badlen(session: Session):
with pytest.raises(Exception):
misc.encrypt_keyvalue(client, [0, 1, 2], "test", b"testing")
misc.encrypt_keyvalue(session, [0, 1, 2], "test", b"testing")
def test_decrypt_badlen(client: Client):
def test_decrypt_badlen(session: Session):
with pytest.raises(Exception):
misc.decrypt_keyvalue(client, [0, 1, 2], "test", b"testing")
misc.decrypt_keyvalue(session, [0, 1, 2], "test", b"testing")

View File

@ -17,6 +17,7 @@
import pytest
from trezorlib import misc
from trezorlib.debuglink import SessionDebugWrapper as Session
from trezorlib.debuglink import TrezorClientDebugLink as Client
from ... import translations as TR
@ -32,10 +33,11 @@ def test_encrypt(client: Client):
client.debug.swipe_up()
client.debug.press_yes()
with client:
session = Session(client.get_management_session())
with client, session:
client.set_input_flow(input_flow())
misc.encrypt_keyvalue(
client,
session,
[],
"Enable labeling?",
b"",

View File

@ -17,13 +17,13 @@
import pytest
from trezorlib import messages, misc
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.debuglink import SessionDebugWrapper as Session
from ...common import MNEMONIC12
@pytest.mark.setup_client(mnemonic=MNEMONIC12)
def test_ecdh(client: Client):
def test_ecdh(session: Session):
identity = messages.IdentityType(
proto="gpg",
user="",
@ -37,7 +37,7 @@ def test_ecdh(client: Client):
"0407f2c6e5becf3213c1d07df0cfbe8e39f70a8c643df7575e5c56859ec52c45ca950499c019719dae0fda04248d851e52cf9d66eeb211d89a77be40de22b6c89d"
)
result = misc.get_ecdh_session_key(
client,
session,
identity=identity,
peer_public_key=peer_public_key,
ecdsa_curve_name="secp256k1",
@ -55,7 +55,7 @@ def test_ecdh(client: Client):
"04811a6c2bd2a547d0dd84747297fec47719e7c3f9b0024f027c2b237be99aac39a9230acbd163d0cb1524a0f5ea4bfed6058cec6f18368f72a12aa0c4d083ff64"
)
result = misc.get_ecdh_session_key(
client,
session,
identity=identity,
peer_public_key=peer_public_key,
ecdsa_curve_name="nist256p1",
@ -73,7 +73,7 @@ def test_ecdh(client: Client):
"40a8cf4b6a64c4314e80f15a8ea55812bd735fbb365936a48b2d78807b575fa17a"
)
result = misc.get_ecdh_session_key(
client,
session,
identity=identity,
peer_public_key=peer_public_key,
ecdsa_curve_name="curve25519",

View File

@ -20,7 +20,7 @@ import pytest
from trezorlib import messages as m
from trezorlib import misc
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.debuglink import SessionDebugWrapper as Session
ENTROPY_LENGTHS_POW2 = [2**l for l in range(10)]
ENTROPY_LENGTHS_POW2_1 = [2**l + 1 for l in range(10)]
@ -40,11 +40,11 @@ def entropy(data):
@pytest.mark.parametrize("entropy_length", ENTROPY_LENGTHS)
def test_entropy(client: Client, entropy_length):
with client:
client.set_expected_responses(
def test_entropy(session: Session, entropy_length):
with session:
session.set_expected_responses(
[m.ButtonRequest(code=m.ButtonRequestType.ProtectCall), m.Entropy]
)
ent = misc.get_entropy(client, entropy_length)
ent = misc.get_entropy(session, entropy_length)
assert len(ent) == entropy_length
print(f"{entropy_length} bytes: entropy = {entropy(ent)}")

View File

@ -17,13 +17,13 @@
import pytest
from trezorlib import messages, misc
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.debuglink import SessionDebugWrapper as Session
from ...common import MNEMONIC12
@pytest.mark.setup_client(mnemonic=MNEMONIC12)
def test_sign(client: Client):
def test_sign(session: Session):
hidden = bytes.fromhex(
"cd8552569d6e4509266ef137584d1e62c7579b5b8ed69bbafa4b864c6521e7c2"
)
@ -40,7 +40,7 @@ def test_sign(client: Client):
path="/login",
index=0,
)
sig = misc.sign_identity(client, identity, hidden, visual)
sig = misc.sign_identity(session, identity, hidden, visual)
assert sig.address == "17F17smBTX9VTZA9Mj8LM5QGYNZnmziCjL"
assert (
sig.public_key.hex()
@ -62,7 +62,7 @@ def test_sign(client: Client):
path="/pub",
index=3,
)
sig = misc.sign_identity(client, identity, hidden, visual)
sig = misc.sign_identity(session, identity, hidden, visual)
assert sig.address == "1KAr6r5qF2kADL8bAaRQBjGKYEGxn9WrbS"
assert (
sig.public_key.hex()
@ -80,7 +80,7 @@ def test_sign(client: Client):
proto="ssh", user="satoshi", host="bitcoin.org", port="", path="", index=47
)
sig = misc.sign_identity(
client, identity, hidden, visual, ecdsa_curve_name="nist256p1"
session, identity, hidden, visual, ecdsa_curve_name="nist256p1"
)
assert sig.address is None
assert (
@ -99,7 +99,7 @@ def test_sign(client: Client):
proto="ssh", user="satoshi", host="bitcoin.org", port="", path="", index=47
)
sig = misc.sign_identity(
client, identity, hidden, visual, ecdsa_curve_name="ed25519"
session, identity, hidden, visual, ecdsa_curve_name="ed25519"
)
assert sig.address is None
assert (
@ -116,7 +116,7 @@ def test_sign(client: Client):
proto="gpg", user="satoshi", host="bitcoin.org", port="", path=""
)
sig = misc.sign_identity(
client, identity, hidden, visual, ecdsa_curve_name="ed25519"
session, identity, hidden, visual, ecdsa_curve_name="ed25519"
)
assert sig.address is None
assert (
@ -133,7 +133,7 @@ def test_sign(client: Client):
proto="signify", user="satoshi", host="bitcoin.org", port="", path=""
)
sig = misc.sign_identity(
client, identity, hidden, visual, ecdsa_curve_name="ed25519"
session, identity, hidden, visual, ecdsa_curve_name="ed25519"
)
assert sig.address is None
assert (

View File

@ -17,7 +17,7 @@
import pytest
from trezorlib import monero
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.debuglink import SessionDebugWrapper as Session
from trezorlib.tools import parse_path
from ...common import MNEMONIC12
@ -47,19 +47,19 @@ pytestmark = [
@pytest.mark.parametrize("path, expected_address", TEST_VECTORS)
def test_monero_getaddress(client: Client, path: str, expected_address: bytes):
address = monero.get_address(client, parse_path(path), show_display=True)
def test_monero_getaddress(session: Session, path: str, expected_address: bytes):
address = monero.get_address(session, parse_path(path), show_display=True)
assert address == expected_address
@pytest.mark.parametrize("path, expected_address", TEST_VECTORS)
def test_monero_getaddress_chunkify_details(
client: Client, path: str, expected_address: bytes
session: Session, path: str, expected_address: bytes
):
with client:
with session.client as client:
IF = InputFlowShowAddressQRCode(client)
client.set_input_flow(IF.get())
address = monero.get_address(
client, parse_path(path), show_display=True, chunkify=True
session, parse_path(path), show_display=True, chunkify=True
)
assert address == expected_address

View File

@ -17,7 +17,7 @@
import pytest
from trezorlib import monero
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.debuglink import SessionDebugWrapper as Session
from trezorlib.tools import parse_path
from ...common import MNEMONIC12
@ -27,8 +27,8 @@ from ...common import MNEMONIC12
@pytest.mark.monero
@pytest.mark.models("core")
@pytest.mark.setup_client(mnemonic=MNEMONIC12)
def test_monero_getwatchkey(client: Client):
res = monero.get_watch_key(client, parse_path("m/44h/128h/0h"))
def test_monero_getwatchkey(session: Session):
res = monero.get_watch_key(session, parse_path("m/44h/128h/0h"))
assert (
res.address
== b"4Ahp23WfMrMFK3wYL2hLWQFGt87ZTeRkufS6JoQZu6MEFDokAQeGWmu9MA3GFq1yVLSJQbKJqVAn9F9DLYGpRzRAEXqAXKM"
@ -37,7 +37,7 @@ def test_monero_getwatchkey(client: Client):
res.watch_key.hex()
== "8722520a581e2a50cc1adab4a1692401effd37b0d63b9d9b60fd7f34ea2b950e"
)
res = monero.get_watch_key(client, parse_path("m/44h/128h/1h"))
res = monero.get_watch_key(session, parse_path("m/44h/128h/1h"))
assert (
res.address
== b"44iAazhoAkv5a5RqLNVyh82a1n3ceNggmN4Ho7bUBJ14WkEVR8uFTe9f7v5rNnJ2kEbVXxfXiRzsD5Jtc6NvBi4D6WNHPie"
@ -46,7 +46,7 @@ def test_monero_getwatchkey(client: Client):
res.watch_key.hex()
== "1f70b7d9e86c11b7a5bee883b75c43d6be189c8f812726ea1ecd94b06bb7db04"
)
res = monero.get_watch_key(client, parse_path("m/44h/128h/2h"))
res = monero.get_watch_key(session, parse_path("m/44h/128h/2h"))
assert (
res.address
== b"47ejhmbZ4wHUhXaqA4b7PN667oPMkokf4ZkNdWrMSPy9TNaLVr7vLqVUQHh2MnmaAEiyrvLsX8xUf99q3j1iAeMV8YvSFcH"

View File

@ -17,7 +17,7 @@
import pytest
from trezorlib import nem
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.debuglink import SessionDebugWrapper as Session
from trezorlib.tools import parse_path
from ...common import MNEMONIC12
@ -28,10 +28,10 @@ from ...common import MNEMONIC12
@pytest.mark.models("t1b1", "t2t1")
@pytest.mark.setup_client(mnemonic=MNEMONIC12)
@pytest.mark.parametrize("chunkify", (True, False))
def test_nem_getaddress(client: Client, chunkify: bool):
def test_nem_getaddress(session: Session, chunkify: bool):
assert (
nem.get_address(
client,
session,
parse_path("m/44h/1h/0h/0h/0h"),
0x68,
show_display=True,
@ -41,7 +41,7 @@ def test_nem_getaddress(client: Client, chunkify: bool):
)
assert (
nem.get_address(
client,
session,
parse_path("m/44h/1h/0h/0h/0h"),
0x98,
show_display=True,

View File

@ -17,7 +17,7 @@
import pytest
from trezorlib import nem
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.debuglink import SessionDebugWrapper as Session
from trezorlib.tools import parse_path
from ...common import MNEMONIC12
@ -32,9 +32,9 @@ pytestmark = [
]
def test_nem_signtx_mosaic_supply_change(client: Client):
def test_nem_signtx_mosaic_supply_change(session: Session):
tx = nem.sign_tx(
client,
session,
ADDRESS_N,
{
"timeStamp": 74649215,
@ -61,9 +61,9 @@ def test_nem_signtx_mosaic_supply_change(client: Client):
)
def test_nem_signtx_mosaic_creation(client: Client):
def test_nem_signtx_mosaic_creation(session: Session):
tx = nem.sign_tx(
client,
session,
ADDRESS_N,
{
"timeStamp": 74649215,
@ -93,9 +93,9 @@ def test_nem_signtx_mosaic_creation(client: Client):
)
def test_nem_signtx_mosaic_creation_properties(client: Client):
def test_nem_signtx_mosaic_creation_properties(session: Session):
tx = nem.sign_tx(
client,
session,
ADDRESS_N,
{
"timeStamp": 74649215,
@ -130,9 +130,9 @@ def test_nem_signtx_mosaic_creation_properties(client: Client):
)
def test_nem_signtx_mosaic_creation_levy(client: Client):
def test_nem_signtx_mosaic_creation_levy(session: Session):
tx = nem.sign_tx(
client,
session,
ADDRESS_N,
{
"timeStamp": 74649215,

View File

@ -17,7 +17,7 @@
import pytest
from trezorlib import nem
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.debuglink import SessionDebugWrapper as Session
from trezorlib.tools import parse_path
from ...common import MNEMONIC12
@ -31,9 +31,9 @@ pytestmark = [
# assertion data from T1
def test_nem_signtx_aggregate_modification(client: Client):
def test_nem_signtx_aggregate_modification(session: Session):
tx = nem.sign_tx(
client,
session,
parse_path("m/44h/1h/0h/0h/0h"),
{
"timeStamp": 74649215,
@ -61,9 +61,9 @@ def test_nem_signtx_aggregate_modification(client: Client):
)
def test_nem_signtx_multisig(client: Client):
def test_nem_signtx_multisig(session: Session):
tx = nem.sign_tx(
client,
session,
parse_path("m/44h/1h/0h/0h/0h"),
{
"timeStamp": 1,
@ -98,7 +98,7 @@ def test_nem_signtx_multisig(client: Client):
)
tx = nem.sign_tx(
client,
session,
parse_path("m/44h/1h/0h/0h/0h"),
{
"timeStamp": 74649215,
@ -132,9 +132,9 @@ def test_nem_signtx_multisig(client: Client):
)
def test_nem_signtx_multisig_signer(client: Client):
def test_nem_signtx_multisig_signer(session: Session):
tx = nem.sign_tx(
client,
session,
parse_path("m/44h/1h/0h/0h/0h"),
{
"timeStamp": 333,
@ -169,7 +169,7 @@ def test_nem_signtx_multisig_signer(client: Client):
)
tx = nem.sign_tx(
client,
session,
parse_path("m/44h/1h/0h/0h/0h"),
{
"timeStamp": 900000,

View File

@ -17,7 +17,7 @@
import pytest
from trezorlib import nem
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.debuglink import SessionDebugWrapper as Session
from trezorlib.tools import parse_path
from ...common import MNEMONIC12
@ -31,10 +31,10 @@ pytestmark = [
# assertion data from T1
def test_nem_signtx_importance_transfer(client: Client):
with client:
def test_nem_signtx_importance_transfer(session: Session):
with session:
tx = nem.sign_tx(
client,
session,
parse_path("m/44h/1h/0h/0h/0h"),
{
"timeStamp": 12349215,
@ -60,9 +60,9 @@ def test_nem_signtx_importance_transfer(client: Client):
)
def test_nem_signtx_provision_namespace(client: Client):
def test_nem_signtx_provision_namespace(session: Session):
tx = nem.sign_tx(
client,
session,
parse_path("m/44h/1h/0h/0h/0h"),
{
"timeStamp": 74649215,

View File

@ -17,7 +17,7 @@
import pytest
from trezorlib import messages, nem
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.debuglink import SessionDebugWrapper as Session
from trezorlib.tools import parse_path
from ...common import MNEMONIC12, is_core
@ -32,16 +32,16 @@ pytestmark = [
# assertion data from T1
@pytest.mark.parametrize("chunkify", (True, False))
def test_nem_signtx_simple(client: Client, chunkify: bool):
with client:
client.set_expected_responses(
def test_nem_signtx_simple(session: Session, chunkify: bool):
with session:
session.set_expected_responses(
[
# Confirm transfer and network fee
messages.ButtonRequest(code=messages.ButtonRequestType.ConfirmOutput),
# Unencrypted message
messages.ButtonRequest(code=messages.ButtonRequestType.ConfirmOutput),
(
is_core(client),
is_core(session),
messages.ButtonRequest(
code=messages.ButtonRequestType.ConfirmOutput
),
@ -53,7 +53,7 @@ def test_nem_signtx_simple(client: Client, chunkify: bool):
)
tx = nem.sign_tx(
client,
session,
parse_path("m/44h/1h/0h/0h/0h"),
{
"timeStamp": 74649215,
@ -82,16 +82,16 @@ def test_nem_signtx_simple(client: Client, chunkify: bool):
@pytest.mark.setup_client(mnemonic=MNEMONIC12)
def test_nem_signtx_encrypted_payload(client: Client):
with client:
client.set_expected_responses(
def test_nem_signtx_encrypted_payload(session: Session):
with session:
session.set_expected_responses(
[
# Confirm transfer and network fee
messages.ButtonRequest(code=messages.ButtonRequestType.ConfirmOutput),
# Ask for encryption
messages.ButtonRequest(code=messages.ButtonRequestType.ConfirmOutput),
(
is_core(client),
is_core(session),
messages.ButtonRequest(
code=messages.ButtonRequestType.ConfirmOutput
),
@ -103,7 +103,7 @@ def test_nem_signtx_encrypted_payload(client: Client):
)
tx = nem.sign_tx(
client,
session,
parse_path("m/44h/1h/0h/0h/0h"),
{
"timeStamp": 74649215,
@ -134,9 +134,9 @@ def test_nem_signtx_encrypted_payload(client: Client):
@pytest.mark.setup_client(mnemonic=MNEMONIC12)
def test_nem_signtx_xem_as_mosaic(client: Client):
def test_nem_signtx_xem_as_mosaic(session: Session):
tx = nem.sign_tx(
client,
session,
parse_path("m/44h/1h/0h/0h/0h"),
{
"timeStamp": 76809215,
@ -168,9 +168,9 @@ def test_nem_signtx_xem_as_mosaic(client: Client):
@pytest.mark.setup_client(mnemonic=MNEMONIC12)
def test_nem_signtx_unknown_mosaic(client: Client):
def test_nem_signtx_unknown_mosaic(session: Session):
tx = nem.sign_tx(
client,
session,
parse_path("m/44h/1h/0h/0h/0h"),
{
"timeStamp": 76809215,
@ -202,9 +202,9 @@ def test_nem_signtx_unknown_mosaic(client: Client):
@pytest.mark.setup_client(mnemonic=MNEMONIC12)
def test_nem_signtx_known_mosaic(client: Client):
def test_nem_signtx_known_mosaic(session: Session):
tx = nem.sign_tx(
client,
session,
parse_path("m/44h/1h/0h/0h/0h"),
{
"timeStamp": 76809215,
@ -236,9 +236,9 @@ def test_nem_signtx_known_mosaic(client: Client):
@pytest.mark.setup_client(mnemonic=MNEMONIC12)
def test_nem_signtx_known_mosaic_with_levy(client: Client):
def test_nem_signtx_known_mosaic_with_levy(session: Session):
tx = nem.sign_tx(
client,
session,
parse_path("m/44h/1h/0h/0h/0h"),
{
"timeStamp": 76809215,
@ -270,9 +270,9 @@ def test_nem_signtx_known_mosaic_with_levy(client: Client):
@pytest.mark.setup_client(mnemonic=MNEMONIC12)
def test_nem_signtx_multiple_mosaics(client: Client):
def test_nem_signtx_multiple_mosaics(session: Session):
tx = nem.sign_tx(
client,
session,
parse_path("m/44h/1h/0h/0h/0h"),
{
"timeStamp": 76809215,

View File

@ -19,7 +19,7 @@ from typing import Any
import pytest
from trezorlib import device, exceptions, messages, models
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.debuglink import SessionDebugWrapper as Session
from ...common import MNEMONIC12
from ...input_flows import (
@ -28,9 +28,9 @@ from ...input_flows import (
)
def do_recover_legacy(client: Client, mnemonic: list[str]):
def do_recover_legacy(session: Session, mnemonic: list[str]):
def input_callback(_):
word, pos = client.debug.read_recovery_word()
word, pos = session.client.debug.read_recovery_word()
if pos != 0 and pos is not None:
word = mnemonic[pos - 1]
mnemonic[pos - 1] = None
@ -39,7 +39,7 @@ def do_recover_legacy(client: Client, mnemonic: list[str]):
return word
ret = device.recover(
client,
session,
type=messages.RecoveryType.DryRun,
word_count=len(mnemonic),
input_method=messages.RecoveryDeviceInputMethod.ScrambledWords,
@ -50,58 +50,59 @@ def do_recover_legacy(client: Client, mnemonic: list[str]):
return ret
def do_recover_core(client: Client, mnemonic: list[str], mismatch: bool = False):
with client:
def do_recover_core(session: Session, mnemonic: list[str], mismatch: bool = False):
with session.client as client:
client.watch_layout()
IF = InputFlowBip39RecoveryDryRun(client, mnemonic, mismatch=mismatch)
client.set_input_flow(IF.get())
return device.recover(client, type=messages.RecoveryType.DryRun)
return device.recover(session, type=messages.RecoveryType.DryRun)
def do_recover(client: Client, mnemonic: list[str], mismatch: bool = False):
if client.model is models.T1B1:
return do_recover_legacy(client, mnemonic)
def do_recover(session: Session, mnemonic: list[str], mismatch: bool = False):
if session.model is models.T1B1:
return do_recover_legacy(session, mnemonic)
else:
return do_recover_core(client, mnemonic, mismatch)
return do_recover_core(session, mnemonic, mismatch)
@pytest.mark.setup_client(mnemonic=MNEMONIC12)
def test_dry_run(client: Client):
ret = do_recover(client, MNEMONIC12.split(" "))
def test_dry_run(session: Session):
ret = do_recover(session, MNEMONIC12.split(" "))
assert isinstance(ret, messages.Success)
@pytest.mark.setup_client(mnemonic=MNEMONIC12)
def test_seed_mismatch(client: Client):
def test_seed_mismatch(session: Session):
with pytest.raises(
exceptions.TrezorFailure, match="does not match the one in the device"
):
do_recover(client, ["all"] * 12, mismatch=True)
do_recover(session, ["all"] * 12, mismatch=True)
@pytest.mark.models("legacy")
def test_invalid_seed_t1(client: Client):
def test_invalid_seed_t1(session: Session):
with pytest.raises(exceptions.TrezorFailure, match="Invalid seed"):
do_recover(client, ["stick"] * 12)
do_recover(session, ["stick"] * 12)
@pytest.mark.models("core")
def test_invalid_seed_core(client: Client):
with client:
def test_invalid_seed_core(session: Session):
with session, session.client as client:
client.watch_layout()
IF = InputFlowBip39RecoveryDryRunInvalid(client)
IF = InputFlowBip39RecoveryDryRunInvalid(session)
client.set_input_flow(IF.get())
with pytest.raises(exceptions.Cancelled):
return device.recover(
client,
session,
type=messages.RecoveryType.DryRun,
)
@pytest.mark.setup_client(uninitialized=True)
def test_uninitialized(client: Client):
@pytest.mark.uninitialized_session
def test_uninitialized(session: Session):
with pytest.raises(exceptions.TrezorFailure, match="not initialized"):
do_recover(client, ["all"] * 12)
do_recover(session, ["all"] * 12)
DRY_RUN_ALLOWED_FIELDS = (
@ -140,7 +141,7 @@ def _make_bad_params():
@pytest.mark.parametrize("field_name, field_value", _make_bad_params())
def test_bad_parameters(client: Client, field_name: str, field_value: Any):
def test_bad_parameters(session: Session, field_name: str, field_value: Any):
msg = messages.RecoveryDevice(
type=messages.RecoveryType.DryRun,
word_count=12,
@ -152,4 +153,4 @@ def test_bad_parameters(client: Client, field_name: str, field_value: Any):
exceptions.TrezorFailure,
match="Forbidden field set in dry-run",
):
client.call(msg)
session.call(msg)

View File

@ -17,7 +17,7 @@
import pytest
from trezorlib import device, messages
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.debuglink import SessionDebugWrapper as Session
from trezorlib.tools import parse_path
from ...common import MNEMONIC12
@ -29,9 +29,10 @@ pytestmark = pytest.mark.models("legacy")
@pytest.mark.setup_client(uninitialized=True)
def test_pin_passphrase(client: Client):
def test_pin_passphrase(session: Session):
debug = session.client.debug
mnemonic = MNEMONIC12.split(" ")
ret = client.call_raw(
ret = session.call_raw(
messages.RecoveryDevice(
word_count=12,
passphrase_protection=True,
@ -43,30 +44,30 @@ def test_pin_passphrase(client: Client):
# click through confirmation
assert isinstance(ret, messages.ButtonRequest)
client.debug.press_yes()
ret = client.call_raw(messages.ButtonAck())
debug.press_yes()
ret = session.call_raw(messages.ButtonAck())
assert isinstance(ret, messages.PinMatrixRequest)
# Enter PIN for first time
pin_encoded = client.debug.encode_pin(PIN6)
ret = client.call_raw(messages.PinMatrixAck(pin=pin_encoded))
pin_encoded = debug.encode_pin(PIN6)
ret = session.call_raw(messages.PinMatrixAck(pin=pin_encoded))
assert isinstance(ret, messages.PinMatrixRequest)
# Enter PIN for second time
pin_encoded = client.debug.encode_pin(PIN6)
ret = client.call_raw(messages.PinMatrixAck(pin=pin_encoded))
pin_encoded = debug.encode_pin(PIN6)
ret = session.call_raw(messages.PinMatrixAck(pin=pin_encoded))
fakes = 0
for _ in range(int(12 * 2)):
assert isinstance(ret, messages.WordRequest)
(word, pos) = client.debug.read_recovery_word()
(word, pos) = debug.read_recovery_word()
if pos != 0:
ret = client.call_raw(messages.WordAck(word=mnemonic[pos - 1]))
ret = session.call_raw(messages.WordAck(word=mnemonic[pos - 1]))
mnemonic[pos - 1] = None
else:
ret = client.call_raw(messages.WordAck(word=word))
ret = session.call_raw(messages.WordAck(word=word))
fakes += 1
# Workflow succesfully ended
@ -76,23 +77,26 @@ def test_pin_passphrase(client: Client):
assert fakes == 12
assert mnemonic == [None] * 12
raise Exception("TEST IS USING INIT MESSAGE - TODO CHANGE")
# Mnemonic is the same
client.init_device()
assert client.debug.state().mnemonic_secret == MNEMONIC12.encode()
session.init_device()
assert debug.state().mnemonic_secret == MNEMONIC12.encode()
assert client.features.pin_protection is True
assert client.features.passphrase_protection is True
assert session.features.pin_protection is True
assert session.features.passphrase_protection is True
# Do passphrase-protected action, PassphraseRequest should be raised
resp = client.call_raw(messages.GetAddress(address_n=parse_path("m/44'/0'/0'/0/0")))
resp = session.call_raw(
messages.GetAddress(address_n=parse_path("m/44'/0'/0'/0/0"))
)
assert isinstance(resp, messages.PassphraseRequest)
client.call_raw(messages.Cancel())
session.call_raw(messages.Cancel())
@pytest.mark.setup_client(uninitialized=True)
def test_nopin_nopassphrase(client: Client):
def test_nopin_nopassphrase(session: Session):
mnemonic = MNEMONIC12.split(" ")
ret = client.call_raw(
ret = session.call_raw(
messages.RecoveryDevice(
word_count=12,
passphrase_protection=False,
@ -104,19 +108,20 @@ def test_nopin_nopassphrase(client: Client):
# click through confirmation
assert isinstance(ret, messages.ButtonRequest)
client.debug.press_yes()
ret = client.call_raw(messages.ButtonAck())
debug = session.client.debug
debug.press_yes()
ret = session.call_raw(messages.ButtonAck())
fakes = 0
for _ in range(int(12 * 2)):
assert isinstance(ret, messages.WordRequest)
(word, pos) = client.debug.read_recovery_word()
(word, pos) = debug.read_recovery_word()
if pos != 0:
ret = client.call_raw(messages.WordAck(word=mnemonic[pos - 1]))
ret = session.call_raw(messages.WordAck(word=mnemonic[pos - 1]))
mnemonic[pos - 1] = None
else:
ret = client.call_raw(messages.WordAck(word=word))
ret = session.call_raw(messages.WordAck(word=word))
fakes += 1
# Workflow succesfully ended
@ -126,21 +131,26 @@ def test_nopin_nopassphrase(client: Client):
assert fakes == 12
assert mnemonic == [None] * 12
# Mnemonic is the same
client.init_device()
assert client.debug.state().mnemonic_secret == MNEMONIC12.encode()
raise Exception("TEST IS USING INIT MESSAGE - TODO CHANGE")
assert client.features.pin_protection is False
assert client.features.passphrase_protection is False
# Mnemonic is the same
# session.init_device()
assert debug.state().mnemonic_secret == MNEMONIC12.encode()
assert session.features.pin_protection is False
assert session.features.passphrase_protection is False
# Do pin & passphrase-protected action, PassphraseRequest should NOT be raised
resp = client.call_raw(messages.GetAddress(address_n=parse_path("m/44'/0'/0'/0/0")))
resp = session.call_raw(
messages.GetAddress(address_n=parse_path("m/44'/0'/0'/0/0"))
)
assert isinstance(resp, messages.Address)
@pytest.mark.setup_client(uninitialized=True)
def test_word_fail(client: Client):
ret = client.call_raw(
def test_word_fail(session: Session):
debug = session.client.debug
ret = session.call_raw(
messages.RecoveryDevice(
word_count=12,
passphrase_protection=False,
@ -152,23 +162,24 @@ def test_word_fail(client: Client):
# click through confirmation
assert isinstance(ret, messages.ButtonRequest)
client.debug.press_yes()
ret = client.call_raw(messages.ButtonAck())
debug.press_yes()
ret = session.call_raw(messages.ButtonAck())
assert isinstance(ret, messages.WordRequest)
for _ in range(int(12 * 2)):
(word, pos) = client.debug.read_recovery_word()
(word, pos) = debug.read_recovery_word()
if pos != 0:
ret = client.call_raw(messages.WordAck(word="kwyjibo"))
ret = session.call_raw(messages.WordAck(word="kwyjibo"))
assert isinstance(ret, messages.Failure)
break
else:
client.call_raw(messages.WordAck(word=word))
session.call_raw(messages.WordAck(word=word))
@pytest.mark.setup_client(uninitialized=True)
def test_pin_fail(client: Client):
ret = client.call_raw(
def test_pin_fail(session: Session):
debug = session.client.debug
ret = session.call_raw(
messages.RecoveryDevice(
word_count=12,
passphrase_protection=True,
@ -180,36 +191,36 @@ def test_pin_fail(client: Client):
# click through confirmation
assert isinstance(ret, messages.ButtonRequest)
client.debug.press_yes()
ret = client.call_raw(messages.ButtonAck())
debug.press_yes()
ret = session.call_raw(messages.ButtonAck())
assert isinstance(ret, messages.PinMatrixRequest)
# Enter PIN for first time
pin_encoded = client.debug.encode_pin(PIN4)
ret = client.call_raw(messages.PinMatrixAck(pin=pin_encoded))
pin_encoded = debug.encode_pin(PIN4)
ret = session.call_raw(messages.PinMatrixAck(pin=pin_encoded))
assert isinstance(ret, messages.PinMatrixRequest)
# Enter PIN for second time, but different one
pin_encoded = client.debug.encode_pin(PIN6)
ret = client.call_raw(messages.PinMatrixAck(pin=pin_encoded))
pin_encoded = debug.encode_pin(PIN6)
ret = session.call_raw(messages.PinMatrixAck(pin=pin_encoded))
# Failure should be raised
assert isinstance(ret, messages.Failure)
def test_already_initialized(client: Client):
def test_already_initialized(session: Session):
with pytest.raises(RuntimeError):
device.recover(
client,
session,
word_count=12,
pin_protection=False,
passphrase_protection=False,
label="label",
input_callback=client.mnemonic_callback,
input_callback=session.client.mnemonic_callback,
)
ret = client.call_raw(
ret = session.call_raw(
messages.RecoveryDevice(
word_count=12,
input_method=messages.RecoveryDeviceInputMethod.ScrambledWords,

View File

@ -17,7 +17,7 @@
import pytest
from trezorlib import device, exceptions, messages
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.debuglink import SessionDebugWrapper as Session
from ...common import MNEMONIC12
from ...input_flows import InputFlowBip39Recovery
@ -26,47 +26,49 @@ pytestmark = pytest.mark.models("core")
@pytest.mark.setup_client(uninitialized=True)
def test_tt_pin_passphrase(client: Client):
with client:
@pytest.mark.uninitialized_session
def test_tt_pin_passphrase(session: Session):
with session.client as client:
IF = InputFlowBip39Recovery(client, MNEMONIC12.split(" "), pin="654")
client.set_input_flow(IF.get())
device.recover(
client,
session,
pin_protection=True,
passphrase_protection=True,
label="hello",
)
assert client.debug.state().mnemonic_secret.decode() == MNEMONIC12
assert session.client.debug.state().mnemonic_secret.decode() == MNEMONIC12
assert client.features.pin_protection is True
assert client.features.passphrase_protection is True
assert client.features.backup_type is messages.BackupType.Bip39
assert client.features.label == "hello"
assert session.features.pin_protection is True
assert session.features.passphrase_protection is True
assert session.features.backup_type is messages.BackupType.Bip39
assert session.features.label == "hello"
@pytest.mark.setup_client(uninitialized=True)
def test_tt_nopin_nopassphrase(client: Client):
with client:
@pytest.mark.uninitialized_session
def test_tt_nopin_nopassphrase(session: Session):
with session.client as client:
IF = InputFlowBip39Recovery(client, MNEMONIC12.split(" "))
client.set_input_flow(IF.get())
device.recover(
client,
session,
pin_protection=False,
passphrase_protection=False,
label="hello",
)
assert client.debug.state().mnemonic_secret.decode() == MNEMONIC12
assert client.features.pin_protection is False
assert client.features.passphrase_protection is False
assert client.features.backup_type is messages.BackupType.Bip39
assert client.features.label == "hello"
assert session.client.debug.state().mnemonic_secret.decode() == MNEMONIC12
assert session.features.pin_protection is False
assert session.features.passphrase_protection is False
assert session.features.backup_type is messages.BackupType.Bip39
assert session.features.label == "hello"
def test_already_initialized(client: Client):
def test_already_initialized(session: Session):
with pytest.raises(RuntimeError):
device.recover(client)
device.recover(session)
with pytest.raises(exceptions.TrezorFailure, match="Already initialized"):
client.call(messages.RecoveryDevice())
session.call(messages.RecoveryDevice())

View File

@ -17,7 +17,7 @@
import pytest
from trezorlib import device, exceptions, messages
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.debuglink import SessionDebugWrapper as Session
from ...common import MNEMONIC_SLIP39_ADVANCED_20, MNEMONIC_SLIP39_ADVANCED_33
from ...input_flows import (
@ -28,7 +28,7 @@ from ...input_flows import (
InputFlowSlip39AdvancedRecoveryThresholdReached,
)
pytestmark = pytest.mark.models("core")
pytestmark = [pytest.mark.models("core"), pytest.mark.uninitialized_session]
EXTRA_GROUP_SHARE = [
"eraser senior decision smug corner ruin rescue cubic angel tackle skin skunk program roster trash rumor slush angel flea amazing"
@ -46,13 +46,13 @@ VECTORS = (
# To allow reusing functionality for multiple tests
def _test_secret(
client: Client, shares: list[str], secret: str, click_info: bool = False
session: Session, shares: list[str], secret: str, click_info: bool = False
):
with client:
with session.client as client:
IF = InputFlowSlip39AdvancedRecovery(client, shares, click_info=click_info)
client.set_input_flow(IF.get())
ret = device.recover(
client,
session,
pin_protection=False,
passphrase_protection=False,
label="label",
@ -60,86 +60,86 @@ def _test_secret(
# Workflow succesfully ended
assert ret == messages.Success(message="Device recovered")
assert client.features.initialized is True
assert client.features.pin_protection is False
assert client.features.passphrase_protection is False
assert client.features.backup_type is messages.BackupType.Slip39_Advanced
assert client.debug.state().mnemonic_secret.hex() == secret
assert session.features.initialized is True
assert session.features.pin_protection is False
assert session.features.passphrase_protection is False
assert session.features.backup_type is messages.BackupType.Slip39_Advanced
assert session.client.debug.state().mnemonic_secret.hex() == secret
@pytest.mark.parametrize("shares, secret", VECTORS)
@pytest.mark.setup_client(uninitialized=True)
def test_secret(client: Client, shares: list[str], secret: str):
_test_secret(client, shares, secret)
def test_secret(session: Session, shares: list[str], secret: str):
_test_secret(session, shares, secret)
@pytest.mark.parametrize("shares, secret", VECTORS)
@pytest.mark.setup_client(uninitialized=True)
@pytest.mark.models(skip="safe3", reason="safe3 does not have info button")
def test_secret_click_info_button(client: Client, shares: list[str], secret: str):
_test_secret(client, shares, secret, click_info=True)
def test_secret_click_info_button(session: Session, shares: list[str], secret: str):
_test_secret(session, shares, secret, click_info=True)
@pytest.mark.setup_client(uninitialized=True)
def test_extra_share_entered(client: Client):
def test_extra_share_entered(session: Session):
_test_secret(
client,
session,
shares=EXTRA_GROUP_SHARE + MNEMONIC_SLIP39_ADVANCED_20,
secret=VECTORS[0][1],
)
@pytest.mark.setup_client(uninitialized=True)
def test_abort(client: Client):
with client:
def test_abort(session: Session):
with session.client as client:
IF = InputFlowSlip39AdvancedRecoveryAbort(client)
client.set_input_flow(IF.get())
with pytest.raises(exceptions.Cancelled):
device.recover(client, pin_protection=False, label="label")
client.init_device()
assert client.features.initialized is False
device.recover(session, pin_protection=False, label="label")
# TODO remove? session.init_device()
assert session.features.initialized is False
@pytest.mark.setup_client(uninitialized=True)
def test_noabort(client: Client):
with client:
def test_noabort(session: Session):
with session.client as client:
IF = InputFlowSlip39AdvancedRecoveryNoAbort(
client, EXTRA_GROUP_SHARE + MNEMONIC_SLIP39_ADVANCED_20
)
client.set_input_flow(IF.get())
device.recover(client, pin_protection=False, label="label")
client.init_device()
assert client.features.initialized is True
device.recover(session, pin_protection=False, label="label")
# TODO remove? session.init_device()
assert session.features.initialized is True
@pytest.mark.setup_client(uninitialized=True)
def test_same_share(client: Client):
def test_same_share(session: Session):
# we choose the second share from the fixture because
# the 1st is 1of1 and group threshold condition is reached first
first_share = MNEMONIC_SLIP39_ADVANCED_20[1].split(" ")
# second share is first 4 words of first
second_share = MNEMONIC_SLIP39_ADVANCED_20[1].split(" ")[:4]
with client:
with session, session.client as client:
IF = InputFlowSlip39AdvancedRecoveryShareAlreadyEntered(
client, first_share, second_share
session, first_share, second_share
)
client.set_input_flow(IF.get())
with pytest.raises(exceptions.Cancelled):
device.recover(client, pin_protection=False, label="label")
device.recover(session, pin_protection=False, label="label")
@pytest.mark.setup_client(uninitialized=True)
def test_group_threshold_reached(client: Client):
def test_group_threshold_reached(session: Session):
# first share in the fixture is 1of1 so we choose that
first_share = MNEMONIC_SLIP39_ADVANCED_20[0].split(" ")
# second share is first 3 words of first
second_share = MNEMONIC_SLIP39_ADVANCED_20[0].split(" ")[:3]
with client:
with session, session.client as client:
IF = InputFlowSlip39AdvancedRecoveryThresholdReached(
client, first_share, second_share
session, first_share, second_share
)
client.set_input_flow(IF.get())
with pytest.raises(exceptions.Cancelled):
device.recover(client, pin_protection=False, label="label")
device.recover(session, pin_protection=False, label="label")

View File

@ -17,7 +17,7 @@
import pytest
from trezorlib import device, messages
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.debuglink import SessionDebugWrapper as Session
from trezorlib.exceptions import TrezorFailure
from ...common import MNEMONIC_SLIP39_ADVANCED_20
@ -39,14 +39,14 @@ EXTRA_GROUP_SHARE = [
@pytest.mark.setup_client(mnemonic=MNEMONIC_SLIP39_ADVANCED_20, passphrase=False)
def test_2of3_dryrun(client: Client):
with client:
def test_2of3_dryrun(session: Session):
with session.client as client:
IF = InputFlowSlip39AdvancedRecoveryDryRun(
client, EXTRA_GROUP_SHARE + MNEMONIC_SLIP39_ADVANCED_20
)
client.set_input_flow(IF.get())
ret = device.recover(
client,
session,
passphrase_protection=False,
pin_protection=False,
label="label",
@ -60,9 +60,9 @@ def test_2of3_dryrun(client: Client):
@pytest.mark.setup_client(mnemonic=MNEMONIC_SLIP39_ADVANCED_20)
def test_2of3_invalid_seed_dryrun(client: Client):
def test_2of3_invalid_seed_dryrun(session: Session):
# test fails because of different seed on device
with client, pytest.raises(
with session.client as client, pytest.raises(
TrezorFailure, match=r"The seed does not match the one in the device"
):
IF = InputFlowSlip39AdvancedRecoveryDryRun(
@ -70,7 +70,7 @@ def test_2of3_invalid_seed_dryrun(client: Client):
)
client.set_input_flow(IF.get())
device.recover(
client,
session,
passphrase_protection=False,
pin_protection=False,
label="label",

View File

@ -17,7 +17,7 @@
import pytest
from trezorlib import device, exceptions, messages
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.debuglink import SessionDebugWrapper as Session
from ...common import (
MNEMONIC_SLIP39_BASIC_20_3of6,
@ -36,7 +36,7 @@ from ...input_flows import (
InputFlowSlip39BasicRecoveryWrongNthWord,
)
pytestmark = pytest.mark.models("core")
pytestmark = [pytest.mark.models("core"), pytest.mark.uninitialized_session]
MNEMONIC_SLIP39_BASIC_20_1of1 = [
"academic academic academic academic academic academic academic academic academic academic academic academic academic academic academic academic academic rebuild aquatic spew"
@ -70,32 +70,32 @@ VECTORS = (
@pytest.mark.setup_client(uninitialized=True)
@pytest.mark.parametrize("shares, secret, backup_type", VECTORS)
def test_secret(
client: Client, shares: list[str], secret: str, backup_type: messages.BackupType
session: Session, shares: list[str], secret: str, backup_type: messages.BackupType
):
with client:
with session.client as client:
IF = InputFlowSlip39BasicRecovery(client, shares)
client.set_input_flow(IF.get())
ret = device.recover(client, pin_protection=False, label="label")
ret = device.recover(session, pin_protection=False, label="label")
# Workflow successfully ended
assert ret == messages.Success(message="Device recovered")
assert client.features.pin_protection is False
assert client.features.passphrase_protection is False
assert client.features.backup_type is backup_type
assert session.features.pin_protection is False
assert session.features.passphrase_protection is False
assert session.features.backup_type is backup_type
# Check mnemonic
assert client.debug.state().mnemonic_secret.hex() == secret
assert session.client.debug.state().mnemonic_secret.hex() == secret
@pytest.mark.setup_client(uninitialized=True)
def test_recover_with_pin_passphrase(client: Client):
with client:
def test_recover_with_pin_passphrase(session: Session):
with session.client as client:
IF = InputFlowSlip39BasicRecovery(
client, MNEMONIC_SLIP39_BASIC_20_3of6, pin="654"
)
client.set_input_flow(IF.get())
ret = device.recover(
client,
session,
pin_protection=True,
passphrase_protection=True,
label="label",
@ -103,99 +103,99 @@ def test_recover_with_pin_passphrase(client: Client):
# Workflow successfully ended
assert ret == messages.Success(message="Device recovered")
assert client.features.pin_protection is True
assert client.features.passphrase_protection is True
assert client.features.backup_type is messages.BackupType.Slip39_Basic
assert session.features.pin_protection is True
assert session.features.passphrase_protection is True
assert session.features.backup_type is messages.BackupType.Slip39_Basic
@pytest.mark.setup_client(uninitialized=True)
def test_abort(client: Client):
with client:
def test_abort(session: Session):
with session.client as client:
IF = InputFlowSlip39BasicRecoveryAbort(client)
client.set_input_flow(IF.get())
with pytest.raises(exceptions.Cancelled):
device.recover(client, pin_protection=False, label="label")
client.init_device()
assert client.features.initialized is False
assert client.features.recovery_status is messages.RecoveryStatus.Nothing
device.recover(session, pin_protection=False, label="label")
# TODO remove? session.init_device()
assert session.features.initialized is False
assert session.features.recovery_status is messages.RecoveryStatus.Nothing
@pytest.mark.setup_client(uninitialized=True)
def test_abort_between_shares(client: Client):
with client:
def test_abort_between_shares(session: Session):
with session.client as client:
IF = InputFlowSlip39BasicRecoveryAbortBetweenShares(
client, MNEMONIC_SLIP39_BASIC_20_3of6
)
client.set_input_flow(IF.get())
with pytest.raises(exceptions.Cancelled):
device.recover(client, pin_protection=False, label="label")
client.init_device()
assert client.features.initialized is False
assert client.features.recovery_status is messages.RecoveryStatus.Nothing
device.recover(session, pin_protection=False, label="label")
# TODO remove? session.init_device()
assert session.features.initialized is False
assert session.features.recovery_status is messages.RecoveryStatus.Nothing
@pytest.mark.setup_client(uninitialized=True)
def test_noabort(client: Client):
with client:
def test_noabort(session: Session):
with session.client as client:
IF = InputFlowSlip39BasicRecoveryNoAbort(client, MNEMONIC_SLIP39_BASIC_20_3of6)
client.set_input_flow(IF.get())
device.recover(client, pin_protection=False, label="label")
client.init_device()
assert client.features.initialized is True
device.recover(session, pin_protection=False, label="label")
# TODO remove? session.init_device()
assert session.features.initialized is True
@pytest.mark.setup_client(uninitialized=True)
def test_invalid_mnemonic_first_share(client: Client):
with client:
IF = InputFlowSlip39BasicRecoveryInvalidFirstShare(client)
def test_invalid_mnemonic_first_share(session: Session):
with session, session.client as client:
IF = InputFlowSlip39BasicRecoveryInvalidFirstShare(session)
client.set_input_flow(IF.get())
with pytest.raises(exceptions.Cancelled):
device.recover(client, pin_protection=False, label="label")
client.init_device()
assert client.features.initialized is False
device.recover(session, pin_protection=False, label="label")
# TODO remove? session.init_device()
assert session.features.initialized is False
@pytest.mark.setup_client(uninitialized=True)
def test_invalid_mnemonic_second_share(client: Client):
with client:
def test_invalid_mnemonic_second_share(session: Session):
with session, session.client as client:
IF = InputFlowSlip39BasicRecoveryInvalidSecondShare(
client, MNEMONIC_SLIP39_BASIC_20_3of6
session, MNEMONIC_SLIP39_BASIC_20_3of6
)
client.set_input_flow(IF.get())
with pytest.raises(exceptions.Cancelled):
device.recover(client, pin_protection=False, label="label")
client.init_device()
assert client.features.initialized is False
device.recover(session, pin_protection=False, label="label")
# TODO remove? session.init_device()
assert session.features.initialized is False
@pytest.mark.setup_client(uninitialized=True)
@pytest.mark.parametrize("nth_word", range(3))
def test_wrong_nth_word(client: Client, nth_word: int):
def test_wrong_nth_word(session: Session, nth_word: int):
share = MNEMONIC_SLIP39_BASIC_20_3of6[0].split(" ")
with client:
IF = InputFlowSlip39BasicRecoveryWrongNthWord(client, share, nth_word)
with session, session.client as client:
IF = InputFlowSlip39BasicRecoveryWrongNthWord(session, share, nth_word)
client.set_input_flow(IF.get())
with pytest.raises(exceptions.Cancelled):
device.recover(client, pin_protection=False, label="label")
device.recover(session, pin_protection=False, label="label")
@pytest.mark.setup_client(uninitialized=True)
def test_same_share(client: Client):
def test_same_share(session: Session):
share = MNEMONIC_SLIP39_BASIC_20_3of6[0].split(" ")
with client:
IF = InputFlowSlip39BasicRecoverySameShare(client, share)
with session, session.client as client:
IF = InputFlowSlip39BasicRecoverySameShare(session, share)
client.set_input_flow(IF.get())
with pytest.raises(exceptions.Cancelled):
device.recover(client, pin_protection=False, label="label")
device.recover(session, pin_protection=False, label="label")
@pytest.mark.setup_client(uninitialized=True)
def test_1of1(client: Client):
with client:
def test_1of1(session: Session):
with session.client as client:
IF = InputFlowSlip39BasicRecovery(client, MNEMONIC_SLIP39_BASIC_20_1of1)
client.set_input_flow(IF.get())
ret = device.recover(
client,
session,
pin_protection=False,
passphrase_protection=False,
label="label",
@ -203,7 +203,7 @@ def test_1of1(client: Client):
# Workflow successfully ended
assert ret == messages.Success(message="Device recovered")
assert client.features.initialized is True
assert client.features.pin_protection is False
assert client.features.passphrase_protection is False
assert client.features.backup_type is messages.BackupType.Slip39_Basic
assert session.features.initialized is True
assert session.features.pin_protection is False
assert session.features.passphrase_protection is False
assert session.features.backup_type is messages.BackupType.Slip39_Basic

View File

@ -17,7 +17,7 @@
import pytest
from trezorlib import device, messages
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.debuglink import SessionDebugWrapper as Session
from trezorlib.exceptions import TrezorFailure
from ...input_flows import InputFlowSlip39BasicRecoveryDryRun
@ -37,12 +37,12 @@ INVALID_SHARES_20_2of3 = [
@pytest.mark.setup_client(mnemonic=SHARES_20_2of3[0:2])
def test_2of3_dryrun(client: Client):
with client:
def test_2of3_dryrun(session: Session):
with session.client as client:
IF = InputFlowSlip39BasicRecoveryDryRun(client, SHARES_20_2of3[1:3])
client.set_input_flow(IF.get())
ret = device.recover(
client,
session,
passphrase_protection=False,
pin_protection=False,
label="label",
@ -56,9 +56,9 @@ def test_2of3_dryrun(client: Client):
@pytest.mark.setup_client(mnemonic=SHARES_20_2of3[0:2])
def test_2of3_invalid_seed_dryrun(client: Client):
def test_2of3_invalid_seed_dryrun(session: Session):
# test fails because of different seed on device
with client, pytest.raises(
with session.client as client, pytest.raises(
TrezorFailure, match=r"The seed does not match the one in the device"
):
IF = InputFlowSlip39BasicRecoveryDryRun(
@ -66,7 +66,7 @@ def test_2of3_invalid_seed_dryrun(client: Client):
)
client.set_input_flow(IF.get())
device.recover(
client,
session,
passphrase_protection=False,
pin_protection=False,
label="label",

View File

@ -19,7 +19,7 @@ import pytest
from shamir_mnemonic import shamir
from trezorlib import device
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.debuglink import SessionDebugWrapper as Session
from trezorlib.messages import BackupAvailability, BackupType
from ...common import WITH_MOCK_URANDOM
@ -31,32 +31,32 @@ from ...input_flows import (
)
def backup_flow_bip39(client: Client) -> bytes:
with client:
def backup_flow_bip39(session: Session) -> bytes:
with session.client as client:
IF = InputFlowBip39Backup(client)
client.set_input_flow(IF.get())
device.backup(client)
device.backup(session)
assert IF.mnemonic is not None
return IF.mnemonic.encode()
def backup_flow_slip39_basic(client: Client):
with client:
def backup_flow_slip39_basic(session: Session):
with session.client as client:
IF = InputFlowSlip39BasicBackup(client, False)
client.set_input_flow(IF.get())
device.backup(client)
device.backup(session)
groups = shamir.decode_mnemonics(IF.mnemonics[:3])
ems = shamir.recover_ems(groups)
return ems.ciphertext
def backup_flow_slip39_advanced(client: Client):
with client:
def backup_flow_slip39_advanced(session: Session):
with session.client as client:
IF = InputFlowSlip39AdvancedBackup(client, False)
client.set_input_flow(IF.get())
device.backup(client)
device.backup(session)
mnemonics = IF.mnemonics[0:3] + IF.mnemonics[5:8] + IF.mnemonics[10:13]
groups = shamir.decode_mnemonics(mnemonics)
@ -74,32 +74,35 @@ VECTORS = [
@pytest.mark.models("core")
@pytest.mark.parametrize("backup_type, backup_flow", VECTORS)
@pytest.mark.setup_client(uninitialized=True)
def test_skip_backup_msg(client: Client, backup_type, backup_flow):
with WITH_MOCK_URANDOM, client:
@pytest.mark.uninitialized_session
def test_skip_backup_msg(session: Session, backup_type, backup_flow):
assert session.features.initialized is False
with WITH_MOCK_URANDOM, session:
device.reset(
client,
session,
skip_backup=True,
passphrase_protection=False,
pin_protection=False,
backup_type=backup_type,
)
assert client.features.initialized is True
assert client.features.backup_availability == BackupAvailability.Required
assert client.features.unfinished_backup is False
assert client.features.no_backup is False
assert client.features.backup_type is backup_type
assert session.features.initialized is True
assert session.features.backup_availability == BackupAvailability.Required
assert session.features.unfinished_backup is False
assert session.features.no_backup is False
assert session.features.backup_type is backup_type
secret = backup_flow(client)
secret = backup_flow(session)
client.init_device()
assert client.features.initialized is True
assert client.features.backup_availability == BackupAvailability.NotAvailable
assert client.features.unfinished_backup is False
assert client.features.backup_type is backup_type
session = session.client.get_session()
assert session.features.initialized is True
assert session.features.backup_availability == BackupAvailability.NotAvailable
assert session.features.unfinished_backup is False
assert session.features.backup_type is backup_type
assert secret is not None
state = client.debug.state()
state = session.client.debug.state()
assert state.mnemonic_type is backup_type
assert state.mnemonic_secret == secret
@ -107,32 +110,35 @@ def test_skip_backup_msg(client: Client, backup_type, backup_flow):
@pytest.mark.models("core")
@pytest.mark.parametrize("backup_type, backup_flow", VECTORS)
@pytest.mark.setup_client(uninitialized=True)
def test_skip_backup_manual(client: Client, backup_type: BackupType, backup_flow):
with WITH_MOCK_URANDOM, client:
@pytest.mark.uninitialized_session
def test_skip_backup_manual(session: Session, backup_type: BackupType, backup_flow):
assert session.features.initialized is False
with WITH_MOCK_URANDOM, session, session.client as client:
IF = InputFlowResetSkipBackup(client)
client.set_input_flow(IF.get())
device.reset(
client,
session,
pin_protection=False,
passphrase_protection=False,
backup_type=backup_type,
)
assert client.features.initialized is True
assert client.features.backup_availability == BackupAvailability.Required
assert client.features.unfinished_backup is False
assert client.features.no_backup is False
assert client.features.backup_type is backup_type
assert session.features.initialized is True
assert session.features.backup_availability == BackupAvailability.Required
assert session.features.unfinished_backup is False
assert session.features.no_backup is False
assert session.features.backup_type is backup_type
secret = backup_flow(client)
secret = backup_flow(session)
client.init_device()
assert client.features.initialized is True
assert client.features.backup_availability == BackupAvailability.NotAvailable
assert client.features.unfinished_backup is False
assert client.features.backup_type is backup_type
session = session.client.get_session()
assert session.features.initialized is True
assert session.features.backup_availability == BackupAvailability.NotAvailable
assert session.features.unfinished_backup is False
assert session.features.backup_type is backup_type
assert secret is not None
state = client.debug.state()
state = session.client.debug.state()
assert state.mnemonic_type is backup_type
assert state.mnemonic_secret == secret

View File

@ -18,7 +18,7 @@ import pytest
from mnemonic import Mnemonic
from trezorlib import messages
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.debuglink import SessionDebugWrapper as Session
from ...common import EXTERNAL_ENTROPY, generate_entropy
@ -28,8 +28,10 @@ STRENGTH = 128
@pytest.mark.setup_client(uninitialized=True)
def test_reset_device_skip_backup(client: Client):
ret = client.call_raw(
@pytest.mark.uninitialized_session
def test_reset_device_skip_backup(session: Session):
debug = session.client.debug
ret = session.call_raw(
messages.ResetDevice(
strength=STRENGTH,
passphrase_protection=False,
@ -40,17 +42,17 @@ def test_reset_device_skip_backup(client: Client):
)
assert isinstance(ret, messages.ButtonRequest)
client.debug.press_yes()
ret = client.call_raw(messages.ButtonAck())
debug.press_yes()
ret = session.call_raw(messages.ButtonAck())
# Provide entropy
assert isinstance(ret, messages.EntropyRequest)
internal_entropy = client.debug.state().reset_entropy
ret = client.call_raw(messages.EntropyAck(entropy=EXTERNAL_ENTROPY))
internal_entropy = debug.state().reset_entropy
ret = session.call_raw(messages.EntropyAck(entropy=EXTERNAL_ENTROPY))
assert isinstance(ret, messages.Success)
# Check if device is properly initialized
ret = client.call_raw(messages.Initialize())
ret = session.call_raw(messages.GetFeatures())
assert ret.initialized is True
assert ret.backup_availability == messages.BackupAvailability.Required
assert ret.unfinished_backup is False
@ -61,14 +63,14 @@ def test_reset_device_skip_backup(client: Client):
expected_mnemonic = Mnemonic("english").to_mnemonic(entropy)
# start Backup workflow
ret = client.call_raw(messages.BackupDevice())
ret = session.call_raw(messages.BackupDevice())
mnemonic = []
for _ in range(STRENGTH // 32 * 3):
assert isinstance(ret, messages.ButtonRequest)
mnemonic.append(client.debug.read_reset_word())
client.debug.press_yes()
client.call_raw(messages.ButtonAck())
mnemonic.append(debug.read_reset_word())
debug.press_yes()
session.call_raw(messages.ButtonAck())
mnemonic = " ".join(mnemonic)
@ -78,9 +80,9 @@ def test_reset_device_skip_backup(client: Client):
mnemonic = []
for _ in range(STRENGTH // 32 * 3):
assert isinstance(ret, messages.ButtonRequest)
mnemonic.append(client.debug.read_reset_word())
client.debug.press_yes()
ret = client.call_raw(messages.ButtonAck())
mnemonic.append(debug.read_reset_word())
debug.press_yes()
ret = session.call_raw(messages.ButtonAck())
assert isinstance(ret, messages.Success)
@ -90,13 +92,15 @@ def test_reset_device_skip_backup(client: Client):
assert mnemonic == expected_mnemonic
# start backup again - should fail
ret = client.call_raw(messages.BackupDevice())
ret = session.call_raw(messages.BackupDevice())
assert isinstance(ret, messages.Failure)
@pytest.mark.setup_client(uninitialized=True)
def test_reset_device_skip_backup_break(client: Client):
ret = client.call_raw(
@pytest.mark.uninitialized_session
def test_reset_device_skip_backup_break(session: Session):
debug = session.client.debug
ret = session.call_raw(
messages.ResetDevice(
strength=STRENGTH,
passphrase_protection=False,
@ -107,26 +111,26 @@ def test_reset_device_skip_backup_break(client: Client):
)
assert isinstance(ret, messages.ButtonRequest)
client.debug.press_yes()
ret = client.call_raw(messages.ButtonAck())
debug.press_yes()
ret = session.call_raw(messages.ButtonAck())
# Provide entropy
assert isinstance(ret, messages.EntropyRequest)
ret = client.call_raw(messages.EntropyAck(entropy=EXTERNAL_ENTROPY))
ret = session.call_raw(messages.EntropyAck(entropy=EXTERNAL_ENTROPY))
assert isinstance(ret, messages.Success)
# Check if device is properly initialized
ret = client.call_raw(messages.Initialize())
ret = session.call_raw(messages.GetFeatures())
assert ret.initialized is True
assert ret.backup_availability == messages.BackupAvailability.Required
assert ret.unfinished_backup is False
assert ret.no_backup is False
# start Backup workflow
ret = client.call_raw(messages.BackupDevice())
ret = session.call_raw(messages.BackupDevice())
# send Initialize -> break workflow
ret = client.call_raw(messages.Initialize())
ret = session.call_raw(messages.Initialize())
assert isinstance(ret, messages.Features)
assert ret.initialized is True
assert ret.backup_availability == messages.BackupAvailability.NotAvailable
@ -134,11 +138,11 @@ def test_reset_device_skip_backup_break(client: Client):
assert ret.no_backup is False
# start backup again - should fail
ret = client.call_raw(messages.BackupDevice())
ret = session.call_raw(messages.BackupDevice())
assert isinstance(ret, messages.Failure)
# read Features again
ret = client.call_raw(messages.Initialize())
ret = session.call_raw(messages.Initialize())
assert isinstance(ret, messages.Features)
assert ret.initialized is True
assert ret.backup_availability == messages.BackupAvailability.NotAvailable
@ -146,6 +150,6 @@ def test_reset_device_skip_backup_break(client: Client):
assert ret.no_backup is False
def test_initialized_device_backup_fail(client: Client):
ret = client.call_raw(messages.BackupDevice())
def test_initialized_device_backup_fail(session: Session):
ret = session.call_raw(messages.BackupDevice())
assert isinstance(ret, messages.Failure)

View File

@ -18,7 +18,7 @@ import pytest
from mnemonic import Mnemonic
from trezorlib import device, messages
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.debuglink import SessionDebugWrapper as Session
from trezorlib.tools import parse_path
from ...common import EXTERNAL_ENTROPY, generate_entropy
@ -26,9 +26,10 @@ from ...common import EXTERNAL_ENTROPY, generate_entropy
pytestmark = pytest.mark.models("legacy")
def reset_device(client: Client, strength: int):
def reset_device(session: Session, strength: int):
debug = session.client.debug
# No PIN, no passphrase
ret = client.call_raw(
ret = session.call_raw(
messages.ResetDevice(
strength=strength,
passphrase_protection=False,
@ -38,13 +39,13 @@ def reset_device(client: Client, strength: int):
)
assert isinstance(ret, messages.ButtonRequest)
client.debug.press_yes()
ret = client.call_raw(messages.ButtonAck())
debug.press_yes()
ret = session.call_raw(messages.ButtonAck())
# Provide entropy
assert isinstance(ret, messages.EntropyRequest)
internal_entropy = client.debug.state().reset_entropy
ret = client.call_raw(messages.EntropyAck(entropy=EXTERNAL_ENTROPY))
internal_entropy = debug.state().reset_entropy
ret = session.call_raw(messages.EntropyAck(entropy=EXTERNAL_ENTROPY))
# Generate mnemonic locally
entropy = generate_entropy(strength, internal_entropy, EXTERNAL_ENTROPY)
@ -53,9 +54,9 @@ def reset_device(client: Client, strength: int):
mnemonic = []
for _ in range(strength // 32 * 3):
assert isinstance(ret, messages.ButtonRequest)
mnemonic.append(client.debug.read_reset_word())
client.debug.press_yes()
client.call_raw(messages.ButtonAck())
mnemonic.append(session.debug.read_reset_word())
session.debug.press_yes()
session.call_raw(messages.ButtonAck())
mnemonic = " ".join(mnemonic)
@ -65,9 +66,9 @@ def reset_device(client: Client, strength: int):
mnemonic = []
for _ in range(strength // 32 * 3):
assert isinstance(ret, messages.ButtonRequest)
mnemonic.append(client.debug.read_reset_word())
client.debug.press_yes()
resp = client.call_raw(messages.ButtonAck())
mnemonic.append(session.debug.read_reset_word())
debug.press_yes()
resp = session.call_raw(messages.ButtonAck())
assert isinstance(resp, messages.Success)
@ -77,32 +78,38 @@ def reset_device(client: Client, strength: int):
assert mnemonic == expected_mnemonic
# Check if device is properly initialized
resp = client.call_raw(messages.Initialize())
resp = session.call_raw(messages.GetFeatures())
assert resp.initialized is True
assert resp.backup_availability == messages.BackupAvailability.NotAvailable
assert resp.pin_protection is False
assert resp.passphrase_protection is False
# Do pin & passphrase-protected action, PassphraseRequest should NOT be raised
resp = client.call_raw(messages.GetAddress(address_n=parse_path("m/44'/0'/0'/0/0")))
resp = session.call_raw(
messages.GetAddress(address_n=parse_path("m/44'/0'/0'/0/0"))
)
assert isinstance(resp, messages.Address)
@pytest.mark.setup_client(uninitialized=True)
def test_reset_device_128(client: Client):
reset_device(client, 128)
@pytest.mark.uninitialized_session
def test_reset_device_128(session: Session):
reset_device(session, 128)
@pytest.mark.setup_client(uninitialized=True)
def test_reset_device_192(client: Client):
reset_device(client, 192)
@pytest.mark.uninitialized_session
def test_reset_device_192(session: Session):
reset_device(session, 192)
@pytest.mark.setup_client(uninitialized=True)
def test_reset_device_256_pin(client: Client):
@pytest.mark.uninitialized_session
def test_reset_device_256_pin(session: Session):
debug = session.client.debug
strength = 256
ret = client.call_raw(
ret = session.call_raw(
messages.ResetDevice(
strength=strength,
passphrase_protection=True,
@ -113,24 +120,24 @@ def test_reset_device_256_pin(client: Client):
# Do you want ... ?
assert isinstance(ret, messages.ButtonRequest)
client.debug.press_yes()
ret = client.call_raw(messages.ButtonAck())
debug.press_yes()
ret = session.call_raw(messages.ButtonAck())
assert isinstance(ret, messages.PinMatrixRequest)
# Enter PIN for first time
pin_encoded = client.debug.encode_pin("654")
ret = client.call_raw(messages.PinMatrixAck(pin=pin_encoded))
pin_encoded = debug.encode_pin("654")
ret = session.call_raw(messages.PinMatrixAck(pin=pin_encoded))
assert isinstance(ret, messages.PinMatrixRequest)
# Enter PIN for second time
pin_encoded = client.debug.encode_pin("654")
ret = client.call_raw(messages.PinMatrixAck(pin=pin_encoded))
pin_encoded = debug.encode_pin("654")
ret = session.call_raw(messages.PinMatrixAck(pin=pin_encoded))
# Provide entropy
assert isinstance(ret, messages.EntropyRequest)
internal_entropy = client.debug.state().reset_entropy
ret = client.call_raw(messages.EntropyAck(entropy=EXTERNAL_ENTROPY))
internal_entropy = debug.state().reset_entropy
ret = session.call_raw(messages.EntropyAck(entropy=EXTERNAL_ENTROPY))
# Generate mnemonic locally
entropy = generate_entropy(strength, internal_entropy, EXTERNAL_ENTROPY)
@ -139,9 +146,9 @@ def test_reset_device_256_pin(client: Client):
mnemonic = []
for _ in range(strength // 32 * 3):
assert isinstance(ret, messages.ButtonRequest)
mnemonic.append(client.debug.read_reset_word())
client.debug.press_yes()
client.call_raw(messages.ButtonAck())
mnemonic.append(debug.read_reset_word())
debug.press_yes()
session.call_raw(messages.ButtonAck())
mnemonic = " ".join(mnemonic)
@ -151,9 +158,9 @@ def test_reset_device_256_pin(client: Client):
mnemonic = []
for _ in range(strength // 32 * 3):
assert isinstance(ret, messages.ButtonRequest)
mnemonic.append(client.debug.read_reset_word())
client.debug.press_yes()
resp = client.call_raw(messages.ButtonAck())
mnemonic.append(debug.read_reset_word())
debug.press_yes()
resp = session.call_raw(messages.ButtonAck())
assert isinstance(resp, messages.Success)
@ -163,23 +170,27 @@ def test_reset_device_256_pin(client: Client):
assert mnemonic == expected_mnemonic
# Check if device is properly initialized
resp = client.call_raw(messages.Initialize())
resp = session.call_raw(messages.GetFeatures())
assert resp.initialized is True
assert resp.backup_availability == messages.BackupAvailability.NotAvailable
assert resp.pin_protection is True
assert resp.passphrase_protection is True
# Do passphrase-protected action, PassphraseRequest should be raised
resp = client.call_raw(messages.GetAddress(address_n=parse_path("m/44'/0'/0'/0/0")))
resp = session.call_raw(
messages.GetAddress(address_n=parse_path("m/44'/0'/0'/0/0"))
)
assert isinstance(resp, messages.PassphraseRequest)
client.call_raw(messages.Cancel())
session.call_raw(messages.Cancel())
@pytest.mark.setup_client(uninitialized=True)
def test_failed_pin(client: Client):
@pytest.mark.uninitialized_session
def test_failed_pin(session: Session):
debug = session.client.debug
strength = 128
ret = client.call_raw(
ret = session.call_raw(
messages.ResetDevice(
strength=strength,
passphrase_protection=True,
@ -190,27 +201,27 @@ def test_failed_pin(client: Client):
# Do you want ... ?
assert isinstance(ret, messages.ButtonRequest)
client.debug.press_yes()
ret = client.call_raw(messages.ButtonAck())
debug.press_yes()
ret = session.call_raw(messages.ButtonAck())
assert isinstance(ret, messages.PinMatrixRequest)
# Enter PIN for first time
pin_encoded = client.debug.encode_pin("1234")
ret = client.call_raw(messages.PinMatrixAck(pin=pin_encoded))
pin_encoded = debug.encode_pin("1234")
ret = session.call_raw(messages.PinMatrixAck(pin=pin_encoded))
assert isinstance(ret, messages.PinMatrixRequest)
# Enter PIN for second time
pin_encoded = client.debug.encode_pin("6789")
ret = client.call_raw(messages.PinMatrixAck(pin=pin_encoded))
pin_encoded = debug.encode_pin("6789")
ret = session.call_raw(messages.PinMatrixAck(pin=pin_encoded))
assert isinstance(ret, messages.Failure)
def test_already_initialized(client: Client):
def test_already_initialized(session: Session):
with pytest.raises(Exception):
device.reset(
client,
session,
strength=128,
passphrase_protection=True,
pin_protection=True,

View File

@ -20,7 +20,7 @@ from mnemonic import Mnemonic
from trezorlib import device, messages
from trezorlib.btc import get_public_node
from trezorlib.debuglink import LayoutType
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.debuglink import SessionDebugWrapper as Session
from trezorlib.exceptions import TrezorFailure
from ...common import EXTERNAL_ENTROPY, MNEMONIC12, WITH_MOCK_URANDOM, generate_entropy
@ -33,14 +33,15 @@ from ...input_flows import (
pytestmark = pytest.mark.models("core")
def reset_device(client: Client, strength: int):
with WITH_MOCK_URANDOM, client:
def reset_device(session: Session, strength: int):
debug = session.client.debug
with WITH_MOCK_URANDOM, session.client as client:
IF = InputFlowBip39ResetBackup(client)
client.set_input_flow(IF.get())
# No PIN, no passphrase, don't display random
device.reset(
client,
session,
strength=strength,
passphrase_protection=False,
pin_protection=False,
@ -48,7 +49,7 @@ def reset_device(client: Client, strength: int):
)
# generate mnemonic locally
internal_entropy = client.debug.state().reset_entropy
internal_entropy = debug.state().reset_entropy
entropy = generate_entropy(strength, internal_entropy, EXTERNAL_ENTROPY)
expected_mnemonic = Mnemonic("english").to_mnemonic(entropy)
@ -56,7 +57,7 @@ def reset_device(client: Client, strength: int):
assert IF.mnemonic == expected_mnemonic
# Check if device is properly initialized
resp = client.call_raw(messages.Initialize())
resp = session.call_raw(messages.GetFeatures())
assert resp.initialized is True
assert resp.backup_availability == messages.BackupAvailability.NotAvailable
assert resp.pin_protection is False
@ -65,30 +66,34 @@ def reset_device(client: Client, strength: int):
# backup attempt fails because backup was done in reset
with pytest.raises(TrezorFailure, match="ProcessError: Seed already backed up"):
device.backup(client)
device.backup(session)
@pytest.mark.setup_client(uninitialized=True)
def test_reset_device(client: Client):
reset_device(client, 128) # 12 words
@pytest.mark.uninitialized_session
def test_reset_device(session: Session):
reset_device(session, 128) # 12 words
@pytest.mark.setup_client(uninitialized=True)
def test_reset_device_192(client: Client):
reset_device(client, 192) # 18 words
@pytest.mark.uninitialized_session
def test_reset_device_192(session: Session):
reset_device(session, 192) # 18 words
@pytest.mark.setup_client(uninitialized=True)
def test_reset_device_pin(client: Client):
@pytest.mark.uninitialized_session
def test_reset_device_pin(session: Session):
debug = session.client.debug
strength = 256 # 24 words
with WITH_MOCK_URANDOM, client:
with WITH_MOCK_URANDOM, session.client as client:
IF = InputFlowBip39ResetPIN(client)
client.set_input_flow(IF.get())
# PIN, passphrase, display random
device.reset(
client,
session,
strength=strength,
passphrase_protection=True,
pin_protection=True,
@ -96,7 +101,7 @@ def test_reset_device_pin(client: Client):
)
# generate mnemonic locally
internal_entropy = client.debug.state().reset_entropy
internal_entropy = debug.state().reset_entropy
entropy = generate_entropy(strength, internal_entropy, EXTERNAL_ENTROPY)
expected_mnemonic = Mnemonic("english").to_mnemonic(entropy)
@ -104,24 +109,24 @@ def test_reset_device_pin(client: Client):
assert IF.mnemonic == expected_mnemonic
# Check if device is properly initialized
resp = client.call_raw(messages.Initialize())
resp = session.call_raw(messages.GetFeatures())
assert resp.initialized is True
assert resp.backup_availability == messages.BackupAvailability.NotAvailable
assert resp.pin_protection is True
assert resp.passphrase_protection is True
@pytest.mark.setup_client(uninitialized=True)
def test_reset_entropy_check(client: Client):
@pytest.mark.uninitialized_session
def test_reset_entropy_check(session: Session):
strength = 128 # 12 words
with WITH_MOCK_URANDOM, client:
with WITH_MOCK_URANDOM, session.client as client:
IF = InputFlowBip39ResetBackup(client)
client.set_input_flow(IF.get())
# No PIN, no passphrase
_, path_xpubs = device.reset_entropy_check(
client,
session,
strength=strength,
passphrase_protection=False,
pin_protection=False,
@ -138,7 +143,7 @@ def test_reset_entropy_check(client: Client):
assert IF.mnemonic == expected_mnemonic
# Check that the device is properly initialized.
resp = client.call_raw(messages.Initialize())
resp = session.call_raw(messages.Initialize())
assert resp.initialized is True
assert resp.backup_availability == messages.BackupAvailability.NotAvailable
assert resp.pin_protection is False
@ -151,17 +156,18 @@ def test_reset_entropy_check(client: Client):
assert res.xpub == xpub
@pytest.mark.setup_client(uninitialized=True)
def test_reset_failed_check(client: Client):
@pytest.mark.uninitialized_session
def test_reset_failed_check(session: Session):
debug = session.client.debug
strength = 256 # 24 words
with WITH_MOCK_URANDOM, client:
with WITH_MOCK_URANDOM, session.client as client:
IF = InputFlowBip39ResetFailedCheck(client)
client.set_input_flow(IF.get())
# PIN, passphrase, display random
device.reset(
client,
session,
strength=strength,
passphrase_protection=False,
pin_protection=False,
@ -169,7 +175,7 @@ def test_reset_failed_check(client: Client):
)
# generate mnemonic locally
internal_entropy = client.debug.state().reset_entropy
internal_entropy = debug.state().reset_entropy
entropy = generate_entropy(strength, internal_entropy, EXTERNAL_ENTROPY)
expected_mnemonic = Mnemonic("english").to_mnemonic(entropy)
@ -177,7 +183,7 @@ def test_reset_failed_check(client: Client):
assert IF.mnemonic == expected_mnemonic
# Check if device is properly initialized
resp = client.call_raw(messages.Initialize())
resp = session.call_raw(messages.GetFeatures())
assert resp.initialized is True
assert resp.backup_availability == messages.BackupAvailability.NotAvailable
assert resp.pin_protection is False
@ -186,45 +192,56 @@ def test_reset_failed_check(client: Client):
@pytest.mark.setup_client(uninitialized=True)
def test_failed_pin(client: Client):
@pytest.mark.uninitialized_session
def test_failed_pin(session: Session):
debug = session.client.debug
strength = 128
ret = client.call_raw(
ret = session.call_raw(
messages.ResetDevice(strength=strength, pin_protection=True, label="test")
)
# Confirm Reset
assert isinstance(ret, messages.ButtonRequest)
client._raw_write(messages.ButtonAck())
client.debug.press_yes()
# client._raw_write(messages.ButtonAck())
# client.debug.press_yes()
# # Enter PIN for first time
# client.debug.input("654")
# ret = client.call_raw(messages.ButtonAck())
debug.press_yes() # TODO test fails here on T3T1
ret = session.call_raw(messages.ButtonAck())
# Enter PIN for first time
client.debug.input("654")
ret = client.call_raw(messages.ButtonAck())
assert isinstance(ret, messages.ButtonRequest)
debug.input("654")
ret = session.call_raw(messages.ButtonAck())
# Re-enter PIN for TR
if client.layout_type is LayoutType.TR:
if session.client.layout_type is LayoutType.TR:
assert isinstance(ret, messages.ButtonRequest)
client.debug.press_yes()
ret = client.call_raw(messages.ButtonAck())
debug.press_yes()
ret = session.call_raw(messages.ButtonAck())
# Enter PIN for second time
assert isinstance(ret, messages.ButtonRequest)
client.debug.input("456")
ret = client.call_raw(messages.ButtonAck())
debug.input("456")
ret = session.call_raw(messages.ButtonAck())
# PIN mismatch
assert isinstance(ret, messages.ButtonRequest)
client.debug.press_yes()
ret = client.call_raw(messages.ButtonAck())
debug.press_yes()
ret = session.call_raw(messages.ButtonAck())
assert isinstance(ret, messages.ButtonRequest)
@pytest.mark.setup_client(mnemonic=MNEMONIC12)
def test_already_initialized(client: Client):
def test_already_initialized(session: Session):
with pytest.raises(Exception):
device.reset(
client,
session,
strength=128,
passphrase_protection=True,
pin_protection=True,

View File

@ -17,6 +17,7 @@
import pytest
from trezorlib import btc, device, messages
from trezorlib.debuglink import SessionDebugWrapper as Session
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.messages import BackupType
from trezorlib.tools import parse_path
@ -29,25 +30,30 @@ from ...translations import set_language
@pytest.mark.models("core")
@pytest.mark.setup_client(uninitialized=True)
def test_reset_recovery(client: Client):
mnemonic = reset(client)
address_before = btc.get_address(client, "Bitcoin", parse_path("m/44h/0h/0h/0/0"))
session = client.get_management_session()
mnemonic = reset(session)
session = client.get_session()
address_before = btc.get_address(session, "Bitcoin", parse_path("m/44h/0h/0h/0/0"))
lang = client.features.language or "en"
device.wipe(client)
set_language(client, lang[:2])
recover(client, mnemonic)
address_after = btc.get_address(client, "Bitcoin", parse_path("m/44h/0h/0h/0/0"))
device.wipe(session)
client = client.get_new_client()
session = Session(client.get_management_session())
set_language(session, lang[:2])
recover(session, mnemonic)
session = client.get_session()
address_after = btc.get_address(session, "Bitcoin", parse_path("m/44h/0h/0h/0/0"))
assert address_before == address_after
def reset(client: Client, strength: int = 128, skip_backup: bool = False) -> str:
with WITH_MOCK_URANDOM, client:
def reset(session: Session, strength: int = 128, skip_backup: bool = False) -> str:
with WITH_MOCK_URANDOM, session.client as client:
IF = InputFlowBip39ResetBackup(client)
client.set_input_flow(IF.get())
# No PIN, no passphrase, don't display random
device.reset(
client,
session,
strength=strength,
passphrase_protection=False,
pin_protection=False,
@ -56,26 +62,26 @@ def reset(client: Client, strength: int = 128, skip_backup: bool = False) -> str
)
# Check if device is properly initialized
assert client.features.initialized is True
assert session.features.initialized is True
assert (
client.features.backup_availability == messages.BackupAvailability.NotAvailable
session.features.backup_availability == messages.BackupAvailability.NotAvailable
)
assert client.features.pin_protection is False
assert client.features.passphrase_protection is False
assert session.features.pin_protection is False
assert session.features.passphrase_protection is False
assert IF.mnemonic is not None
return IF.mnemonic
def recover(client: Client, mnemonic: str):
def recover(session: Session, mnemonic: str):
words = mnemonic.split(" ")
with client:
with session.client as client:
IF = InputFlowBip39Recovery(client, words)
client.set_input_flow(IF.get())
client.watch_layout()
ret = device.recover(client, pin_protection=False, label="label")
ret = device.recover(session, pin_protection=False, label="label")
# Workflow successfully ended
assert ret == messages.Success(message="Device recovered")
assert client.features.pin_protection is False
assert client.features.passphrase_protection is False
assert session.features.pin_protection is False
assert session.features.passphrase_protection is False

View File

@ -17,6 +17,7 @@
import pytest
from trezorlib import btc, device, messages
from trezorlib.debuglink import SessionDebugWrapper as Session
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.messages import BackupType
from trezorlib.tools import parse_path
@ -32,8 +33,10 @@ from ...translations import set_language
@pytest.mark.models("core")
@pytest.mark.setup_client(uninitialized=True)
def test_reset_recovery(client: Client):
mnemonics = reset(client)
address_before = btc.get_address(client, "Bitcoin", parse_path("m/44h/0h/0h/0/0"))
session = client.get_management_session()
mnemonics = reset(session)
session = client.get_session()
address_before = btc.get_address(session, "Bitcoin", parse_path("m/44h/0h/0h/0/0"))
# we're generating 3of5 groups 3of5 shares each
test_combinations = [
mnemonics[0:3] # shares 1-3 from groups 1-3
@ -50,25 +53,28 @@ def test_reset_recovery(client: Client):
+ mnemonics[22:25],
]
for combination in test_combinations:
session = client.get_management_session()
lang = client.features.language or "en"
device.wipe(client)
set_language(client, lang[:2])
recover(client, combination)
device.wipe(session)
client = client.get_new_client()
session = Session(client.get_management_session())
set_language(session, lang[:2])
recover(session, combination)
session = client.get_session()
address_after = btc.get_address(
client, "Bitcoin", parse_path("m/44h/0h/0h/0/0")
session, "Bitcoin", parse_path("m/44h/0h/0h/0/0")
)
assert address_before == address_after
def reset(client: Client, strength: int = 128) -> list[str]:
with WITH_MOCK_URANDOM, client:
def reset(session: Session, strength: int = 128) -> list[str]:
with WITH_MOCK_URANDOM, session.client as client:
IF = InputFlowSlip39AdvancedResetRecovery(client, False)
client.set_input_flow(IF.get())
# No PIN, no passphrase, don't display random
device.reset(
client,
session,
strength=strength,
passphrase_protection=False,
pin_protection=False,
@ -77,25 +83,25 @@ def reset(client: Client, strength: int = 128) -> list[str]:
)
# Check if device is properly initialized
assert client.features.initialized is True
assert session.features.initialized is True
assert (
client.features.backup_availability == messages.BackupAvailability.NotAvailable
session.features.backup_availability == messages.BackupAvailability.NotAvailable
)
assert client.features.pin_protection is False
assert client.features.passphrase_protection is False
assert client.features.backup_type is BackupType.Slip39_Advanced_Extendable
assert session.features.pin_protection is False
assert session.features.passphrase_protection is False
assert session.features.backup_type is BackupType.Slip39_Advanced_Extendable
return IF.mnemonics
def recover(client: Client, shares: list[str]):
with client:
def recover(session: Session, shares: list[str]):
with session.client as client:
IF = InputFlowSlip39AdvancedRecovery(client, shares, False)
client.set_input_flow(IF.get())
ret = device.recover(client, pin_protection=False, label="label")
ret = device.recover(session, pin_protection=False, label="label")
# Workflow successfully ended
assert ret == messages.Success(message="Device recovered")
assert client.features.pin_protection is False
assert client.features.passphrase_protection is False
assert client.features.backup_type is BackupType.Slip39_Advanced_Extendable
assert session.features.pin_protection is False
assert session.features.passphrase_protection is False
assert session.features.backup_type is BackupType.Slip39_Advanced_Extendable

View File

@ -19,6 +19,7 @@ import itertools
import pytest
from trezorlib import btc, device, messages
from trezorlib.debuglink import SessionDebugWrapper as Session
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.messages import BackupType
from trezorlib.tools import parse_path
@ -35,29 +36,35 @@ from ...translations import set_language
@pytest.mark.setup_client(uninitialized=True)
@WITH_MOCK_URANDOM
def test_reset_recovery(client: Client):
mnemonics = reset(client)
address_before = btc.get_address(client, "Bitcoin", parse_path("m/44h/0h/0h/0/0"))
session = client.get_management_session()
mnemonics = reset(session)
session = client.get_session()
address_before = btc.get_address(session, "Bitcoin", parse_path("m/44h/0h/0h/0/0"))
for share_subset in itertools.combinations(mnemonics, 3):
session = client.get_management_session()
lang = client.features.language or "en"
device.wipe(client)
set_language(client, lang[:2])
device.wipe(session)
client = client.get_new_client()
session = Session(client.get_management_session())
set_language(session, lang[:2])
selected_mnemonics = share_subset
recover(client, selected_mnemonics)
recover(session, selected_mnemonics)
session = client.get_session()
address_after = btc.get_address(
client, "Bitcoin", parse_path("m/44h/0h/0h/0/0")
session, "Bitcoin", parse_path("m/44h/0h/0h/0/0")
)
assert address_before == address_after
def reset(client: Client, strength: int = 128) -> list[str]:
with client:
def reset(session: Session, strength: int = 128) -> list[str]:
with session.client as client:
IF = InputFlowSlip39BasicResetRecovery(client)
client.set_input_flow(IF.get())
# No PIN, no passphrase, don't display random
device.reset(
client,
session,
strength=strength,
passphrase_protection=False,
pin_protection=False,
@ -66,25 +73,25 @@ def reset(client: Client, strength: int = 128) -> list[str]:
)
# Check if device is properly initialized
assert client.features.initialized is True
assert session.features.initialized is True
assert (
client.features.backup_availability == messages.BackupAvailability.NotAvailable
session.features.backup_availability == messages.BackupAvailability.NotAvailable
)
assert client.features.pin_protection is False
assert client.features.passphrase_protection is False
assert client.features.backup_type is BackupType.Slip39_Basic_Extendable
assert session.features.pin_protection is False
assert session.features.passphrase_protection is False
assert session.features.backup_type is BackupType.Slip39_Basic_Extendable
return IF.mnemonics
def recover(client: Client, shares: list[str]):
with client:
def recover(session: Session, shares: list[str]):
with session.client as client:
IF = InputFlowSlip39BasicRecovery(client, shares)
client.set_input_flow(IF.get())
ret = device.recover(client, pin_protection=False, label="label")
ret = device.recover(session, pin_protection=False, label="label")
# Workflow successfully ended
assert ret == messages.Success(message="Device recovered")
assert client.features.pin_protection is False
assert client.features.passphrase_protection is False
assert client.features.backup_type is BackupType.Slip39_Basic_Extendable
assert session.features.pin_protection is False
assert session.features.passphrase_protection is False
assert session.features.backup_type is BackupType.Slip39_Basic_Extendable

View File

@ -37,10 +37,10 @@ def test_reset_device_slip39_advanced(client: Client):
with WITH_MOCK_URANDOM, client:
IF = InputFlowSlip39AdvancedResetRecovery(client, False)
client.set_input_flow(IF.get())
session = client.get_management_session()
# No PIN, no passphrase, don't display random
device.reset(
client,
session,
strength=strength,
passphrase_protection=False,
pin_protection=False,
@ -54,17 +54,17 @@ def test_reset_device_slip39_advanced(client: Client):
# validate that all combinations will result in the correct master secret
validate_mnemonics(IF.mnemonics, member_threshold, secret)
session = client.get_session()
# Check if device is properly initialized
assert client.features.initialized is True
assert client.features.backup_availability == BackupAvailability.NotAvailable
assert client.features.pin_protection is False
assert client.features.passphrase_protection is False
assert client.features.backup_type is BackupType.Slip39_Advanced_Extendable
assert session.features.initialized is True
assert session.features.backup_availability == BackupAvailability.NotAvailable
assert session.features.pin_protection is False
assert session.features.passphrase_protection is False
assert session.features.backup_type is BackupType.Slip39_Advanced_Extendable
# backup attempt fails because backup was done in reset
with pytest.raises(TrezorFailure, match="ProcessError: Seed already backed up"):
device.backup(client)
device.backup(session)
def validate_mnemonics(

View File

@ -21,7 +21,7 @@ from shamir_mnemonic import MnemonicError, shamir
from trezorlib import device
from trezorlib.btc import get_public_node
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.debuglink import SessionDebugWrapper as Session
from trezorlib.exceptions import TrezorFailure
from trezorlib.messages import BackupAvailability, BackupType
@ -31,16 +31,16 @@ from ...input_flows import InputFlowSlip39BasicResetRecovery
pytestmark = pytest.mark.models("core")
def reset_device(client: Client, strength: int):
def reset_device(session: Session, strength: int):
member_threshold = 3
with WITH_MOCK_URANDOM, client:
with WITH_MOCK_URANDOM, session.client as client:
IF = InputFlowSlip39BasicResetRecovery(client)
client.set_input_flow(IF.get())
# No PIN, no passphrase, don't display random
device.reset(
client,
session,
strength=strength,
passphrase_protection=False,
pin_protection=False,
@ -49,47 +49,49 @@ def reset_device(client: Client, strength: int):
)
# generate secret locally
internal_entropy = client.debug.state().reset_entropy
internal_entropy = session.client.debug.state().reset_entropy
secret = generate_entropy(strength, internal_entropy, EXTERNAL_ENTROPY)
# validate that all combinations will result in the correct master secret
validate_mnemonics(IF.mnemonics, member_threshold, secret)
session = session.client.get_session()
# Check if device is properly initialized
assert client.features.initialized is True
assert client.features.backup_availability == BackupAvailability.NotAvailable
assert client.features.pin_protection is False
assert client.features.passphrase_protection is False
assert client.features.backup_type is BackupType.Slip39_Basic_Extendable
assert session.features.initialized is True
assert session.features.backup_availability == BackupAvailability.NotAvailable
assert session.features.pin_protection is False
assert session.features.passphrase_protection is False
assert session.features.backup_type is BackupType.Slip39_Basic_Extendable
# backup attempt fails because backup was done in reset
with pytest.raises(TrezorFailure, match="ProcessError: Seed already backed up"):
device.backup(client)
device.backup(session)
@pytest.mark.setup_client(uninitialized=True)
def test_reset_device_slip39_basic(client: Client):
reset_device(client, 128)
@pytest.mark.uninitialized_session
def test_reset_device_slip39_basic(session: Session):
reset_device(session, 128)
@pytest.mark.setup_client(uninitialized=True)
def test_reset_device_slip39_basic_256(client: Client):
reset_device(client, 256)
@pytest.mark.uninitialized_session
def test_reset_device_slip39_basic_256(session: Session):
reset_device(session, 256)
@pytest.mark.setup_client(uninitialized=True)
def test_reset_entropy_check(client: Client):
def test_reset_entropy_check(session: Session):
member_threshold = 3
strength = 128 # 20 words
with WITH_MOCK_URANDOM, client:
with WITH_MOCK_URANDOM, session.client as client:
IF = InputFlowSlip39BasicResetRecovery(client)
client.set_input_flow(IF.get())
# No PIN, no passphrase.
_, path_xpubs = device.reset_entropy_check(
client,
session,
strength=strength,
passphrase_protection=False,
pin_protection=False,

View File

@ -16,7 +16,7 @@
import pytest
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.debuglink import SessionDebugWrapper as Session
from trezorlib.ripple import get_address
from trezorlib.tools import parse_path
@ -43,28 +43,28 @@ TEST_VECTORS = [
@pytest.mark.parametrize("path, expected_address", TEST_VECTORS)
def test_ripple_get_address(client: Client, path: str, expected_address: str):
address = get_address(client, parse_path(path), show_display=True)
def test_ripple_get_address(session: Session, path: str, expected_address: str):
address = get_address(session, parse_path(path), show_display=True)
assert address == expected_address
@pytest.mark.parametrize("path, expected_address", TEST_VECTORS)
def test_ripple_get_address_chunkify_details(
client: Client, path: str, expected_address: str
session: Session, path: str, expected_address: str
):
with client:
with session.client as client:
IF = InputFlowShowAddressQRCode(client)
client.set_input_flow(IF.get())
address = get_address(
client, parse_path(path), show_display=True, chunkify=True
session, parse_path(path), show_display=True, chunkify=True
)
assert address == expected_address
@pytest.mark.setup_client(mnemonic=CUSTOM_MNEMONIC)
def test_ripple_get_address_other(client: Client):
def test_ripple_get_address_other(session: Session):
# data from https://github.com/you21979/node-ripple-bip32/blob/master/test/test.js
address = get_address(client, parse_path("m/44h/144h/0h/0/0"))
address = get_address(session, parse_path("m/44h/144h/0h/0/0"))
assert address == "r4ocGE47gm4G4LkA9mriVHQqzpMLBTgnTY"
address = get_address(client, parse_path("m/44h/144h/0h/0/1"))
address = get_address(session, parse_path("m/44h/144h/0h/0/1"))
assert address == "rUt9ULSrUvfCmke8HTFU1szbmFpWzVbBXW"

View File

@ -17,7 +17,7 @@
import pytest
from trezorlib import ripple
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.debuglink import SessionDebugWrapper as Session
from trezorlib.exceptions import TrezorFailure
from trezorlib.tools import parse_path
@ -29,7 +29,7 @@ pytestmark = [
@pytest.mark.parametrize("chunkify", (True, False))
def test_ripple_sign_simple_tx(client: Client, chunkify: bool):
def test_ripple_sign_simple_tx(session: Session, chunkify: bool):
msg = ripple.create_sign_tx_msg(
{
"TransactionType": "Payment",
@ -43,7 +43,7 @@ def test_ripple_sign_simple_tx(client: Client, chunkify: bool):
}
)
resp = ripple.sign_tx(
client, parse_path("m/44h/144h/0h/0/0"), msg, chunkify=chunkify
session, parse_path("m/44h/144h/0h/0/0"), msg, chunkify=chunkify
)
assert (
resp.signature.hex()
@ -66,7 +66,7 @@ def test_ripple_sign_simple_tx(client: Client, chunkify: bool):
}
)
resp = ripple.sign_tx(
client, parse_path("m/44h/144h/0h/0/2"), msg, chunkify=chunkify
session, parse_path("m/44h/144h/0h/0/2"), msg, chunkify=chunkify
)
assert (
resp.signature.hex()
@ -92,7 +92,7 @@ def test_ripple_sign_simple_tx(client: Client, chunkify: bool):
}
)
resp = ripple.sign_tx(
client, parse_path("m/44h/144h/0h/0/2"), msg, chunkify=chunkify
session, parse_path("m/44h/144h/0h/0/2"), msg, chunkify=chunkify
)
assert (
resp.signature.hex()
@ -104,7 +104,7 @@ def test_ripple_sign_simple_tx(client: Client, chunkify: bool):
)
def test_ripple_sign_invalid_fee(client: Client):
def test_ripple_sign_invalid_fee(session: Session):
msg = ripple.create_sign_tx_msg(
{
"TransactionType": "Payment",
@ -121,4 +121,4 @@ def test_ripple_sign_invalid_fee(client: Client):
TrezorFailure,
match="ProcessError: Fee must be in the range of 10 to 10,000 drops",
):
ripple.sign_tx(client, parse_path("m/44h/144h/0h/0/2"), msg)
ripple.sign_tx(session, parse_path("m/44h/144h/0h/0/2"), msg)

View File

@ -16,7 +16,7 @@
import pytest
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.debuglink import SessionDebugWrapper as Session
from trezorlib.solana import get_address
from trezorlib.tools import parse_path
@ -32,9 +32,9 @@ pytestmark = [
@parametrize_using_common_fixtures(
"solana/get_address.json",
)
def test_solana_get_address(client: Client, parameters, result):
def test_solana_get_address(session: Session, parameters, result):
actual_result = get_address(
client, address_n=parse_path(parameters["path"]), show_display=True
session, address_n=parse_path(parameters["path"]), show_display=True
)
assert actual_result.address == result["expected_address"]

View File

@ -16,7 +16,7 @@
import pytest
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.debuglink import SessionDebugWrapper as Session
from trezorlib.solana import get_public_key
from trezorlib.tools import parse_path
@ -32,9 +32,9 @@ pytestmark = [
@parametrize_using_common_fixtures(
"solana/get_public_key.json",
)
def test_solana_get_public_key(client: Client, parameters, result):
def test_solana_get_public_key(session: Session, parameters, result):
actual_result = get_public_key(
client, address_n=parse_path(parameters["path"]), show_display=True
session, address_n=parse_path(parameters["path"]), show_display=True
)
assert actual_result.public_key.hex() == result["expected_public_key"]

View File

@ -17,7 +17,7 @@
import pytest
from trezorlib import messages
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.debuglink import SessionDebugWrapper as Session
from trezorlib.solana import sign_tx
from trezorlib.tools import parse_path
@ -42,13 +42,11 @@ pytestmark = [
"solana/sign_tx.unknown_instructions.json",
"solana/sign_tx.predefined_transactions.json",
)
def test_solana_sign_tx(client: Client, parameters, result):
client.init_device(new_session=True)
def test_solana_sign_tx(session: Session, parameters, result):
serialized_tx = _serialize_tx(parameters["construct"])
actual_result = sign_tx(
client,
session,
address_n=parse_path(parameters["address"]),
serialized_tx=serialized_tx,
additional_info=(

View File

@ -55,7 +55,7 @@ from base64 import b64encode
import pytest
from trezorlib import messages, protobuf, stellar
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.debuglink import SessionDebugWrapper as Session
from trezorlib.tools import parse_path
from ...common import parametrize_using_common_fixtures
@ -87,10 +87,10 @@ def parameters_to_proto(parameters):
@parametrize_using_common_fixtures("stellar/sign_tx.json")
def test_sign_tx(client: Client, parameters, result):
def test_sign_tx(session: Session, parameters, result):
tx, operations = parameters_to_proto(parameters)
response = stellar.sign_tx(
client, tx, operations, tx.address_n, tx.network_passphrase
session, tx, operations, tx.address_n, tx.network_passphrase
)
assert response.public_key.hex() == result["public_key"]
assert b64encode(response.signature).decode() == result["signature"]
@ -113,20 +113,20 @@ def test_xdr(parameters, result):
@parametrize_using_common_fixtures("stellar/get_address.json")
def test_get_address(client: Client, parameters, result):
def test_get_address(session: Session, parameters, result):
address_n = parse_path(parameters["path"])
address = stellar.get_address(client, address_n, show_display=True)
address = stellar.get_address(session, address_n, show_display=True)
assert address == result["address"]
@pytest.mark.models("core")
@parametrize_using_common_fixtures("stellar/get_address.json")
def test_get_address_chunkify_details(client: Client, parameters, result):
with client:
def test_get_address_chunkify_details(session: Session, parameters, result):
with session.client as client:
IF = InputFlowShowAddressQRCode(client)
client.set_input_flow(IF.get())
address_n = parse_path(parameters["path"])
address = stellar.get_address(
client, address_n, show_display=True, chunkify=True
session, address_n, show_display=True, chunkify=True
)
assert address == result["address"]

View File

@ -5,7 +5,7 @@ from cryptography.hazmat.primitives.asymmetric import ec
from cryptography.x509 import extensions as ext
from trezorlib import device, models
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.debuglink import SessionDebugWrapper as Session
from ..common import compact_size
@ -35,16 +35,16 @@ ROOT_PUBLIC_KEY = {
),
),
)
def test_authenticate_device(client: Client, challenge: bytes) -> None:
def test_authenticate_device(session: Session, challenge: bytes) -> None:
# NOTE Applications must generate a random challenge for each request.
# Issue an AuthenticateDevice challenge to Trezor.
proof = device.authenticate(client, challenge)
proof = device.authenticate(session, challenge)
certs = [x509.load_der_x509_certificate(cert) for cert in proof.certificates]
# Verify the last certificate in the certificate chain against trust anchor.
root_public_key = ec.EllipticCurvePublicKey.from_encoded_point(
ec.SECP256R1(), ROOT_PUBLIC_KEY[client.model]
ec.SECP256R1(), ROOT_PUBLIC_KEY[session.model]
)
root_public_key.verify(
certs[-1].signature,
@ -78,11 +78,11 @@ def test_authenticate_device(client: Client, challenge: bytes) -> None:
# Verify that the common name matches the Trezor model.
common_name = cert.subject.get_attributes_for_oid(x509.oid.NameOID.COMMON_NAME)[0]
if client.model == models.T3B1:
if session.model == models.T3B1:
# XXX TODO replace as soon as we have T3B1 staging
internal_model = "T2B1"
else:
internal_model = client.model.internal_name
internal_model = session.model.internal_name
assert common_name.value.startswith(internal_model)
# Verify the signature of the challenge.

View File

@ -19,7 +19,7 @@ import time
import pytest
from trezorlib import device, messages, models
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.debuglink import SessionDebugWrapper as Session
from trezorlib.exceptions import TrezorFailure
from ..common import TEST_ADDRESS_N, get_test_address
@ -29,42 +29,42 @@ PIN4 = "1234"
pytestmark = pytest.mark.setup_client(pin=PIN4)
def pin_request(client: Client):
def pin_request(session: Session):
return (
messages.PinMatrixRequest
if client.model is models.T1B1
if session.model is models.T1B1
else messages.ButtonRequest
)
def set_autolock_delay(client: Client, delay):
with client:
def set_autolock_delay(session: Session, delay):
with session, session.client as client:
client.use_pin_sequence([PIN4])
client.set_expected_responses(
session.set_expected_responses(
[
pin_request(client),
pin_request(session),
messages.ButtonRequest,
messages.Success,
messages.Features,
# messages.Features,
]
)
device.apply_settings(client, auto_lock_delay_ms=delay)
device.apply_settings(session, auto_lock_delay_ms=delay)
def test_apply_auto_lock_delay(client: Client):
set_autolock_delay(client, 10 * 1000)
def test_apply_auto_lock_delay(session: Session):
set_autolock_delay(session, 10 * 1000)
time.sleep(0.1) # sleep less than auto-lock delay
with client:
with session:
# No PIN protection is required.
client.set_expected_responses([messages.Address])
get_test_address(client)
session.set_expected_responses([messages.Address])
get_test_address(session)
time.sleep(10.5) # sleep more than auto-lock delay
with client:
with session, session.client as client:
client.use_pin_sequence([PIN4])
client.set_expected_responses([pin_request(client), messages.Address])
get_test_address(client)
session.set_expected_responses([pin_request(session), messages.Address])
get_test_address(session)
@pytest.mark.parametrize(
@ -78,44 +78,45 @@ def test_apply_auto_lock_delay(client: Client):
536870, # 149 hours, maximum
],
)
def test_apply_auto_lock_delay_valid(client: Client, seconds):
set_autolock_delay(client, seconds * 1000)
assert client.features.auto_lock_delay_ms == seconds * 1000
def test_apply_auto_lock_delay_valid(session: Session, seconds):
set_autolock_delay(session, seconds * 1000)
assert session.features.auto_lock_delay_ms == seconds * 1000
def test_autolock_default_value(client: Client):
assert client.features.auto_lock_delay_ms is None
with client:
def test_autolock_default_value(session: Session):
assert session.features.auto_lock_delay_ms is None
with session, session.client as client:
client.use_pin_sequence([PIN4])
device.apply_settings(client, label="pls unlock")
client.refresh_features()
assert client.features.auto_lock_delay_ms == 60 * 10 * 1000
device.apply_settings(session, label="pls unlock")
session.refresh_features()
assert session.features.auto_lock_delay_ms == 60 * 10 * 1000
@pytest.mark.parametrize(
"seconds",
[0, 1, 9, 536871, 2**22],
)
def test_apply_auto_lock_delay_out_of_range(client: Client, seconds):
with client:
def test_apply_auto_lock_delay_out_of_range(session: Session, seconds):
with session, session.client as client:
client.use_pin_sequence([PIN4])
client.set_expected_responses(
session.set_expected_responses(
[
pin_request(client),
pin_request(session),
messages.Failure(code=messages.FailureType.ProcessError),
]
)
delay = seconds * 1000
with pytest.raises(TrezorFailure):
device.apply_settings(client, auto_lock_delay_ms=delay)
device.apply_settings(session, auto_lock_delay_ms=delay)
@pytest.mark.models("core")
def test_autolock_cancels_ui(client: Client):
set_autolock_delay(client, 10 * 1000)
def test_autolock_cancels_ui(session: Session):
set_autolock_delay(session, 10 * 1000)
resp = client.call_raw(
resp = session.call_raw(
messages.GetAddress(
coin_name="Testnet",
address_n=TEST_ADDRESS_N,
@ -126,44 +127,47 @@ def test_autolock_cancels_ui(client: Client):
assert isinstance(resp, messages.ButtonRequest)
# send an ack, do not read response
client._raw_write(messages.ButtonAck())
session._write(messages.ButtonAck())
# sleep more than auto-lock delay
time.sleep(10.5)
resp = client._raw_read()
resp = session._read()
assert isinstance(resp, messages.Failure)
assert resp.code == messages.FailureType.ActionCancelled
def test_autolock_ignores_initialize(client: Client):
set_autolock_delay(client, 10 * 1000)
def test_autolock_ignores_initialize(session: Session):
client = session.client
set_autolock_delay(session, 10 * 1000)
assert client.features.unlocked is True
assert session.features.unlocked is True
start = time.monotonic()
while time.monotonic() - start < 11:
# init_device should always work even if locked
client.init_device()
client.resume_session(session)
time.sleep(0.1)
# after 11 seconds we are definitely locked
assert client.features.unlocked is False
session.refresh_features()
assert session.features.unlocked is False
def test_autolock_ignores_getaddress(client: Client):
set_autolock_delay(client, 10 * 1000)
def test_autolock_ignores_getaddress(session: Session):
assert client.features.unlocked is True
set_autolock_delay(session, 10 * 1000)
assert session.features.unlocked is True
start = time.monotonic()
# let's continue for 8 seconds to give a little leeway to the slow CI
while time.monotonic() - start < 8:
get_test_address(client)
get_test_address(session)
time.sleep(0.1)
# sleep 3 more seconds to wait for autolock
time.sleep(3)
# after 11 seconds we are definitely locked
client.refresh_features()
assert client.features.unlocked is False
session.refresh_features()
assert session.features.unlocked is False

View File

@ -15,44 +15,64 @@
# If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.
from trezorlib import device, messages, models
from trezorlib.client import ProtocolVersion
from trezorlib.debuglink import SessionDebugWrapper as Session
from trezorlib.debuglink import TrezorClientDebugLink as Client
def test_features(client: Client):
f0 = client.features
# client erases session_id from its features
f0.session_id = client.session_id
f1 = client.call(messages.Initialize(session_id=f0.session_id))
assert f0 == f1
session = client.get_session()
f0 = session.features
if client.protocol_version == ProtocolVersion.PROTOCOL_V1:
# session erases session_id from its features
f0.session_id = session.id
f1 = session.call(messages.Initialize(session_id=session.id))
assert f0 == f1
else:
session2 = client.resume_session(session)
f1: messages.Features = session2.call(messages.GetFeatures())
assert f1.session_id is None
assert f0 == f1
def test_capabilities(client: Client):
assert (messages.Capability.Translations in client.features.capabilities) == (
client.model is not models.T1B1
def test_capabilities(session: Session):
assert (messages.Capability.Translations in session.features.capabilities) == (
session.model is not models.T1B1
)
def test_ping(client: Client):
ping = client.call(messages.Ping(message="ahoj!"))
def test_ping(session: Session):
ping = session.call(messages.Ping(message="ahoj!"))
assert ping == messages.Success(message="ahoj!")
def test_device_id_same(client: Client):
id1 = client.get_device_id()
client.init_device()
id2 = client.get_device_id()
session1 = client.get_session()
session2 = client.get_session()
id1 = session1.features.device_id
session2.refresh_features()
id2 = session2.features.device_id
client = client.get_new_client()
session3 = client.get_session()
id3 = session3.features.device_id
# ID must be at least 12 characters
assert len(id1) >= 12
# Every resulf of UUID must be the same
assert id1 == id2
assert id2 == id3
def test_device_id_different(client: Client):
id1 = client.get_device_id()
device.wipe(client)
id2 = client.get_device_id()
session = client.get_management_session()
id1 = client.features.device_id
device.wipe(session)
client = client.get_new_client()
session = client.get_management_session()
id2 = client.features.device_id
# Device ID must be fresh after every reset
assert id1 != id2

View File

@ -19,7 +19,7 @@ import time
import pytest
from trezorlib import btc, device
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.debuglink import SessionDebugWrapper as Session
from trezorlib.messages import SafetyCheckLevel
from trezorlib.tools import H_
@ -29,47 +29,47 @@ pytestmark = [
]
def test_public_ckd(client: Client):
def test_public_ckd(session: Session):
# disable safety checks to access non-standard paths
device.apply_settings(client, safety_checks=SafetyCheckLevel.PromptTemporarily)
btc.get_address(client, "Bitcoin", []) # to compute root node via BIP39
device.apply_settings(session, safety_checks=SafetyCheckLevel.PromptTemporarily)
btc.get_address(session, "Bitcoin", []) # to compute root node via BIP39
for depth in range(8):
start = time.time()
btc.get_address(client, "Bitcoin", range(depth))
btc.get_address(session, "Bitcoin", range(depth))
delay = time.time() - start
expected = (depth + 1) * 0.26
print("DEPTH", depth, "EXPECTED DELAY", expected, "REAL DELAY", delay)
assert delay <= expected
def test_private_ckd(client: Client):
def test_private_ckd(session: Session):
# disable safety checks to access non-standard paths
device.apply_settings(client, safety_checks=SafetyCheckLevel.PromptTemporarily)
btc.get_address(client, "Bitcoin", []) # to compute root node via BIP39
device.apply_settings(session, safety_checks=SafetyCheckLevel.PromptTemporarily)
btc.get_address(session, "Bitcoin", []) # to compute root node via BIP39
for depth in range(8):
start = time.time()
address_n = [H_(-i) for i in range(-depth, 0)]
btc.get_address(client, "Bitcoin", address_n)
btc.get_address(session, "Bitcoin", address_n)
delay = time.time() - start
expected = (depth + 1) * 0.26
print("DEPTH", depth, "EXPECTED DELAY", expected, "REAL DELAY", delay)
assert delay <= expected
def test_cache(client: Client):
def test_cache(session: Session):
# disable safety checks to access non-standard paths
device.apply_settings(client, safety_checks=SafetyCheckLevel.PromptTemporarily)
device.apply_settings(session, safety_checks=SafetyCheckLevel.PromptTemporarily)
start = time.time()
for x in range(10):
btc.get_address(client, "Bitcoin", [x, 2, 3, 4, 5, 6, 7, 8])
btc.get_address(session, "Bitcoin", [x, 2, 3, 4, 5, 6, 7, 8])
nocache_time = time.time() - start
start = time.time()
for x in range(10):
btc.get_address(client, "Bitcoin", [1, 2, 3, 4, 5, 6, 7, x])
btc.get_address(session, "Bitcoin", [1, 2, 3, 4, 5, 6, 7, x])
cache_time = time.time() - start
print("NOCACHE TIME", nocache_time)

View File

@ -20,62 +20,66 @@ import pytest
from trezorlib import btc, device
from trezorlib.debuglink import LayoutType
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.debuglink import SessionDebugWrapper as Session
from trezorlib.tools import parse_path
PIN = "1234"
def _assert_busy(client: Client, should_be_busy: bool, screen: str = "Homescreen"):
assert client.features.busy is should_be_busy
if client.layout_type is not LayoutType.T1:
def _assert_busy(session: Session, should_be_busy: bool, screen: str = "Homescreen"):
assert session.features.busy is should_be_busy
if session.client.layout_type is not LayoutType.T1:
if should_be_busy:
assert "CoinJoinProgress" in client.debug.read_layout().all_components()
assert (
"CoinJoinProgress"
in session.client.debug.read_layout().all_components()
)
else:
assert client.debug.read_layout().main_component() == screen
assert session.client.debug.read_layout().main_component() == screen
@pytest.mark.setup_client(pin=PIN)
def test_busy_state(client: Client):
_assert_busy(client, False, "Lockscreen")
assert client.features.unlocked is False
def test_busy_state(session: Session):
_assert_busy(session, False, "Lockscreen")
assert session.features.unlocked is False
# Show busy dialog for 1 minute.
device.set_busy(client, expiry_ms=60 * 1000)
_assert_busy(client, True)
assert client.features.unlocked is False
device.set_busy(session, expiry_ms=60 * 1000)
_assert_busy(session, True)
assert session.features.unlocked is False
with client:
with session.client as client:
client.use_pin_sequence([PIN])
btc.get_address(
client, "Bitcoin", parse_path("m/44h/0h/0h/0/0"), show_display=True
session, "Bitcoin", parse_path("m/44h/0h/0h/0/0"), show_display=True
)
client.refresh_features()
_assert_busy(client, True)
assert client.features.unlocked is True
session.refresh_features()
_assert_busy(session, True)
assert session.features.unlocked is True
# Hide the busy dialog.
device.set_busy(client, None)
device.set_busy(session, None)
_assert_busy(client, False)
assert client.features.unlocked is True
_assert_busy(session, False)
assert session.features.unlocked is True
@pytest.mark.models("core")
def test_busy_expiry_core(client: Client):
def test_busy_expiry_core(session: Session):
WAIT_TIME_MS = 1500
TOLERANCE = 1000
_assert_busy(client, False)
_assert_busy(session, False)
# Start a timer
start = time.monotonic()
# Show the busy dialog.
device.set_busy(client, expiry_ms=WAIT_TIME_MS)
_assert_busy(client, True)
device.set_busy(session, expiry_ms=WAIT_TIME_MS)
_assert_busy(session, True)
# Wait until the layout changes
client.debug.wait_layout()
time.sleep(0.1) # Improves stability of the test for devices with THP
session.client.debug.wait_layout()
end = time.monotonic()
# Check that the busy dialog was shown for at least WAIT_TIME_MS.
@ -84,26 +88,26 @@ def test_busy_expiry_core(client: Client):
# Check that the device is no longer busy.
# Also needs to come back to Homescreen (for UI tests).
client.refresh_features()
_assert_busy(client, False)
session.refresh_features()
_assert_busy(session, False)
@pytest.mark.flaky(max_runs=5)
@pytest.mark.models("legacy")
def test_busy_expiry_legacy(client: Client):
_assert_busy(client, False)
def test_busy_expiry_legacy(session: Session):
_assert_busy(session, False)
# Show the busy dialog.
device.set_busy(client, expiry_ms=1500)
_assert_busy(client, True)
device.set_busy(session, expiry_ms=1500)
_assert_busy(session, True)
# Hasn't expired yet.
time.sleep(0.1)
_assert_busy(client, True)
_assert_busy(session, True)
# Wait for it to expire. Add some tolerance to account for CI/hardware slowness.
time.sleep(4.0)
# Check that the device is no longer busy.
# Also needs to come back to Homescreen (for UI tests).
client.refresh_features()
_assert_busy(client, False)
session.refresh_features()
_assert_busy(session, False)

View File

@ -17,7 +17,7 @@
import pytest
import trezorlib.messages as m
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.debuglink import SessionDebugWrapper as Session
from trezorlib.exceptions import Cancelled
from ..common import TEST_ADDRESS_N
@ -35,15 +35,15 @@ from ..common import TEST_ADDRESS_N
),
],
)
def test_cancel_message_via_cancel(client: Client, message):
def test_cancel_message_via_cancel(session: Session, message):
def input_flow():
yield
client.cancel()
session.cancel()
with client, pytest.raises(Cancelled):
client.set_expected_responses([m.ButtonRequest(), m.Failure()])
with session, session.client as client, pytest.raises(Cancelled):
session.set_expected_responses([m.ButtonRequest(), m.Failure()])
client.set_input_flow(input_flow)
client.call(message)
session.call(message)
@pytest.mark.parametrize(
@ -58,43 +58,45 @@ def test_cancel_message_via_cancel(client: Client, message):
),
],
)
def test_cancel_message_via_initialize(client: Client, message):
resp = client.call_raw(message)
@pytest.mark.protocol("protocol_v1")
def test_cancel_message_via_initialize(session: Session, message):
resp = session.call_raw(message)
assert isinstance(resp, m.ButtonRequest)
client._raw_write(m.ButtonAck())
client._raw_write(m.Initialize())
session._write(m.ButtonAck())
session._write(m.Initialize())
resp = client._raw_read()
resp = session._read()
assert isinstance(resp, m.Features)
@pytest.mark.models("core")
def test_cancel_on_paginated(client: Client):
def test_cancel_on_paginated(session: Session):
"""Check that device is responsive on paginated screen. See #1708."""
# In #1708, the device would ignore USB (or UDP) events while waiting for the user
# to page through the screen. This means that this testcase, instead of failing,
# would get stuck waiting for the _raw_read result.
# I'm not spending the effort to modify the testcase to cause a _failure_ if that
# happens again. Just be advised that this should not get stuck.
message = m.SignMessage(
message=b"hello" * 64,
address_n=TEST_ADDRESS_N,
coin_name="Testnet",
)
resp = client.call_raw(message)
resp = session.call_raw(message)
assert isinstance(resp, m.ButtonRequest)
client._raw_write(m.ButtonAck())
client.debug.press_yes()
session._write(m.ButtonAck())
session.client.debug.press_yes()
resp = client._raw_read()
resp = session._read()
assert isinstance(resp, m.ButtonRequest)
assert resp.pages is not None
client._raw_write(m.ButtonAck())
session._write(m.ButtonAck())
client._raw_write(m.Cancel())
resp = client._raw_read()
session._write(m.Cancel())
resp = session._read()
assert isinstance(resp, m.Failure)
assert resp.code == m.FailureType.ActionCancelled

View File

@ -17,6 +17,8 @@
import pytest
from trezorlib import debuglink, device, messages, misc
from trezorlib.client import ProtocolVersion
from trezorlib.debuglink import SessionDebugWrapper as Session
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.tools import parse_path
from trezorlib.transport import udp
@ -32,35 +34,41 @@ def test_layout(client: Client):
@pytest.mark.models("legacy")
@pytest.mark.setup_client(mnemonic=MNEMONIC12)
def test_mnemonic(client: Client):
client.ensure_unlocked()
mnemonic = client.debug.state().mnemonic_secret
def test_mnemonic(session: Session):
session.ensure_unlocked()
mnemonic = session.client.debug.state().mnemonic_secret
assert mnemonic == MNEMONIC12.encode()
@pytest.mark.models("legacy")
@pytest.mark.setup_client(mnemonic=MNEMONIC12, pin="1234", passphrase="")
def test_pin(client: Client):
resp = client.call_raw(messages.GetAddress(address_n=parse_path("m/44'/0'/0'/0/0")))
def test_pin(session: Session):
resp = session.call_raw(
messages.GetAddress(address_n=parse_path("m/44'/0'/0'/0/0"))
)
assert isinstance(resp, messages.PinMatrixRequest)
state = client.debug.state()
assert state.pin == "1234"
assert state.matrix != ""
with session.client as client:
state = client.debug.state()
assert state.pin == "1234"
assert state.matrix != ""
pin_encoded = client.debug.encode_pin("1234")
resp = client.call_raw(messages.PinMatrixAck(pin=pin_encoded))
assert isinstance(resp, messages.PassphraseRequest)
pin_encoded = client.debug.encode_pin("1234")
resp = session.call_raw(messages.PinMatrixAck(pin=pin_encoded))
assert isinstance(resp, messages.PassphraseRequest)
resp = client.call_raw(messages.PassphraseAck(passphrase=""))
assert isinstance(resp, messages.Address)
resp = session.call_raw(messages.PassphraseAck(passphrase=""))
assert isinstance(resp, messages.Address)
@pytest.mark.models("core")
def test_softlock_instability(client: Client):
def test_softlock_instability(session: Session):
if session.protocol_version == ProtocolVersion.PROTOCOL_V2:
raise Exception("THIS NEEDS TO BE CHANGED FOR THP")
def load_device():
debuglink.load_device(
client,
session,
mnemonic=MNEMONIC12,
pin="1234",
passphrase_protection=False,
@ -68,27 +76,29 @@ def test_softlock_instability(client: Client):
)
# start from a clean slate:
resp = client.debug.reseed(0)
resp = session.client.debug.reseed(0)
if isinstance(resp, messages.Failure) and not isinstance(
client.transport, udp.UdpTransport
session.client.transport, udp.UdpTransport
):
pytest.xfail("reseed only supported on emulator")
device.wipe(client)
entropy_after_wipe = misc.get_entropy(client, 16)
device.wipe(session)
entropy_after_wipe = misc.get_entropy(session, 16)
session.refresh_features()
# configure and wipe the device
load_device()
client.debug.reseed(0)
device.wipe(client)
assert misc.get_entropy(client, 16) == entropy_after_wipe
session.client.debug.reseed(0)
device.wipe(session)
assert misc.get_entropy(session, 16) == entropy_after_wipe
session.refresh_features()
load_device()
# the device has PIN -> lock it
client.call(messages.LockDevice())
client.debug.reseed(0)
session.call(messages.LockDevice())
session.client.debug.reseed(0)
# wipe_device should succeed with no need to unlock
device.wipe(client)
device.wipe(session)
# the device is now trying to run the lockscreen, which attempts to unlock.
# If the device actually called config.unlock(), it would use additional randomness.
# That is undesirable. Assert that the returned entropy is still the same.
assert misc.get_entropy(client, 16) == entropy_after_wipe
assert misc.get_entropy(session, 16) == entropy_after_wipe

View File

@ -3,7 +3,7 @@ from hashlib import blake2s
import pytest
from trezorlib import firmware, models
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.debuglink import SessionDebugWrapper as Session
# size of FIRMWARE_AREA, see core/embed/models/model_*_layout.c
FIRMWARE_LENGTHS = {
@ -15,35 +15,35 @@ FIRMWARE_LENGTHS = {
}
def test_firmware_hash_emu(client: Client) -> None:
if client.features.fw_vendor != "EMULATOR":
def test_firmware_hash_emu(session: Session) -> None:
if session.features.fw_vendor != "EMULATOR":
pytest.skip("Only for emulator")
data = b"\xff" * FIRMWARE_LENGTHS[client.model]
data = b"\xff" * FIRMWARE_LENGTHS[session.model]
expected_hash = blake2s(data).digest()
hash = firmware.get_hash(client, None)
hash = firmware.get_hash(session, None)
assert hash == expected_hash
challenge = b"Hello Trezor"
expected_hash = blake2s(data, key=challenge).digest()
hash = firmware.get_hash(client, challenge)
hash = firmware.get_hash(session, challenge)
assert hash == expected_hash
def test_firmware_hash_hw(client: Client) -> None:
if client.features.fw_vendor == "EMULATOR":
def test_firmware_hash_hw(session: Session) -> None:
if session.features.fw_vendor == "EMULATOR":
pytest.skip("Only for hardware")
# TODO get firmware image from outside the environment, check for actual result
challenge = b"Hello Trezor"
empty_data = b"\xff" * FIRMWARE_LENGTHS[client.model]
empty_data = b"\xff" * FIRMWARE_LENGTHS[session.model]
empty_hash = blake2s(empty_data).digest()
empty_hash_challenge = blake2s(empty_data, key=challenge).digest()
hash = firmware.get_hash(client, None)
hash = firmware.get_hash(session, None)
assert hash != empty_hash
hash2 = firmware.get_hash(client, challenge)
hash2 = firmware.get_hash(session, challenge)
assert hash != hash2
assert hash2 != empty_hash_challenge

View File

@ -23,6 +23,7 @@ import pytest
from trezorlib import debuglink, device, exceptions, messages, models
from trezorlib._internal import translations
from trezorlib.debuglink import SessionDebugWrapper as Session
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.debuglink import message_filters
@ -57,228 +58,235 @@ def get_ping_title(lang: str) -> str:
@pytest.fixture
def client(client: Client) -> Iterator[Client]:
lang_before = client.features.language or ""
def session(session: Session) -> Iterator[Session]:
lang_before = session.features.language or ""
try:
set_language(client, "en")
yield client
set_language(session, "en")
yield session
finally:
set_language(client, lang_before[:2])
set_language(session, lang_before[:2])
def _check_ping_screen_texts(client: Client, title: str, right_button: str) -> None:
def ping_input_flow(client: Client, title: str, right_button: str):
def _check_ping_screen_texts(session: Session, title: str, right_button: str) -> None:
def ping_input_flow(session: Session, title: str, right_button: str):
yield
layout = client.debug.read_layout()
layout = session.client.debug.read_layout()
assert layout.title().upper() == title.upper()
assert layout.button_contents()[-1].upper() == right_button.upper()
client.debug.press_yes()
session.client.debug.press_yes()
# TT does not have a right button text (but a green OK tick)
if client.model in (models.T2T1, models.T3T1):
if session.model in (models.T2T1, models.T3T1):
right_button = "-"
with client:
with session, session.client as client:
client.watch_layout(True)
client.set_input_flow(ping_input_flow(client, title, right_button))
ping = client.call(messages.Ping(message="ahoj!", button_protection=True))
client.set_input_flow(ping_input_flow(session, title, right_button))
ping = session.call(messages.Ping(message="ahoj!", button_protection=True))
assert ping == messages.Success(message="ahoj!")
def test_error_too_long(client: Client):
assert client.features.language == "en-US"
def test_error_too_long(session: Session):
assert session.features.language == "en-US"
# Translations too long
# Sending more than allowed by the flash capacity
max_length = MAX_DATA_LENGTH[client.model]
with pytest.raises(exceptions.TrezorFailure, match="Translations too long"), client:
max_length = MAX_DATA_LENGTH[session.model]
with pytest.raises(
exceptions.TrezorFailure, match="Translations too long"
), session:
bad_data = (max_length + 1) * b"a"
device.change_language(client, language_data=bad_data)
assert client.features.language == "en-US"
_check_ping_screen_texts(client, get_ping_title("en"), get_ping_button("en"))
device.change_language(session, language_data=bad_data)
assert session.features.language == "en-US"
_check_ping_screen_texts(session, get_ping_title("en"), get_ping_button("en"))
def test_error_invalid_data_length(client: Client):
assert client.features.language == "en-US"
def test_error_invalid_data_length(session: Session):
assert session.features.language == "en-US"
# Invalid data length
# Sending more data than advertised in the header
with pytest.raises(exceptions.TrezorFailure, match="Invalid data length"), client:
good_data = build_and_sign_blob("cs", client)
with pytest.raises(exceptions.TrezorFailure, match="Invalid data length"), session:
good_data = build_and_sign_blob("cs", session)
bad_data = good_data + b"abcd"
device.change_language(client, language_data=bad_data)
assert client.features.language == "en-US"
_check_ping_screen_texts(client, get_ping_title("en"), get_ping_button("en"))
device.change_language(session, language_data=bad_data)
assert session.features.language == "en-US"
_check_ping_screen_texts(session, get_ping_title("en"), get_ping_button("en"))
def test_error_invalid_header_magic(client: Client):
assert client.features.language == "en-US"
def test_error_invalid_header_magic(session: Session):
assert session.features.language == "en-US"
# Invalid header magic
# Does not match the expected magic
with pytest.raises(
exceptions.TrezorFailure, match="Invalid translations data"
), client:
good_data = build_and_sign_blob("cs", client)
), session:
good_data = build_and_sign_blob("cs", session)
bad_data = 4 * b"a" + good_data[4:]
device.change_language(client, language_data=bad_data)
assert client.features.language == "en-US"
_check_ping_screen_texts(client, get_ping_title("en"), get_ping_button("en"))
device.change_language(session, language_data=bad_data)
assert session.features.language == "en-US"
_check_ping_screen_texts(session, get_ping_title("en"), get_ping_button("en"))
def test_error_invalid_data_hash(client: Client):
assert client.features.language == "en-US"
def test_error_invalid_data_hash(session: Session):
assert session.features.language == "en-US"
# Invalid data hash
# Changing the data after their hash has been calculated
with pytest.raises(
exceptions.TrezorFailure, match="Translation data verification failed"
), client:
good_data = build_and_sign_blob("cs", client)
), session:
good_data = build_and_sign_blob("cs", session)
bad_data = good_data[:-8] + 8 * b"a"
device.change_language(
client,
session,
language_data=bad_data,
)
assert client.features.language == "en-US"
_check_ping_screen_texts(client, get_ping_title("en"), get_ping_button("en"))
assert session.features.language == "en-US"
_check_ping_screen_texts(session, get_ping_title("en"), get_ping_button("en"))
def test_error_version_mismatch(client: Client):
assert client.features.language == "en-US"
def test_error_version_mismatch(session: Session):
assert session.features.language == "en-US"
# Translations version mismatch
# Change the version to one not matching the current device
with pytest.raises(
exceptions.TrezorFailure, match="Translations version mismatch"
), client:
blob = prepare_blob("cs", client.model, (3, 5, 4, 0))
), session:
blob = prepare_blob("cs", session.model, (3, 5, 4, 0))
device.change_language(
client,
session,
language_data=sign_blob(blob),
)
assert client.features.language == "en-US"
_check_ping_screen_texts(client, get_ping_title("en"), get_ping_button("en"))
assert session.features.language == "en-US"
_check_ping_screen_texts(session, get_ping_title("en"), get_ping_button("en"))
def test_error_invalid_signature(client: Client):
assert client.features.language == "en-US"
def test_error_invalid_signature(session: Session):
assert session.features.language == "en-US"
# Invalid signature
# Changing the data in the signature section
with pytest.raises(
exceptions.TrezorFailure, match="Invalid translations data"
), client:
blob = prepare_blob("cs", client.model, client.version)
), session:
blob = prepare_blob("cs", session.model, session.version)
blob.proof = translations.Proof(
merkle_proof=[],
sigmask=0b011,
signature=b"a" * 64,
)
device.change_language(
client,
session,
language_data=blob.build(),
)
assert client.features.language == "en-US"
_check_ping_screen_texts(client, get_ping_title("en"), get_ping_button("en"))
assert session.features.language == "en-US"
_check_ping_screen_texts(session, get_ping_title("en"), get_ping_button("en"))
@pytest.mark.parametrize("lang", LANGUAGES)
def test_full_language_change(client: Client, lang: str):
assert client.features.language == "en-US"
assert client.features.language_version_matches is True
def test_full_language_change(session: Session, lang: str):
assert session.features.language == "en-US"
assert session.features.language_version_matches is True
# Setting selected language
set_language(client, lang)
assert client.features.language[:2] == lang
assert client.features.language_version_matches is True
_check_ping_screen_texts(client, get_ping_title(lang), get_ping_button(lang))
set_language(session, lang)
assert session.features.language[:2] == lang
assert session.features.language_version_matches is True
_check_ping_screen_texts(session, get_ping_title(lang), get_ping_button(lang))
# Setting the default language via empty data
set_language(client, "en")
assert client.features.language == "en-US"
assert client.features.language_version_matches is True
_check_ping_screen_texts(client, get_ping_title("en"), get_ping_button("en"))
set_language(session, "en")
assert session.features.language == "en-US"
assert session.features.language_version_matches is True
_check_ping_screen_texts(session, get_ping_title("en"), get_ping_button("en"))
def test_language_is_removed_after_wipe(client: Client):
assert client.features.language == "en-US"
session = Session(client.get_session())
assert session.features.language == "en-US"
_check_ping_screen_texts(client, get_ping_title("en"), get_ping_button("en"))
_check_ping_screen_texts(session, get_ping_title("en"), get_ping_button("en"))
# Setting cs language
set_language(client, "cs")
assert client.features.language == "cs-CZ"
set_language(session, "cs")
assert session.features.language == "cs-CZ"
_check_ping_screen_texts(client, get_ping_title("cs"), get_ping_button("cs"))
_check_ping_screen_texts(session, get_ping_title("cs"), get_ping_button("cs"))
# Wipe device
device.wipe(client)
assert client.features.language == "en-US"
device.wipe(session)
client = client.get_new_client()
session = Session(client.get_management_session())
assert session.features.language == "en-US"
# Load it again
debuglink.load_device(
client,
session,
mnemonic=" ".join(["all"] * 12),
pin=None,
passphrase_protection=False,
label="test",
)
assert client.features.language == "en-US"
assert session.features.language == "en-US"
_check_ping_screen_texts(client, get_ping_title("en"), get_ping_button("en"))
_check_ping_screen_texts(session, get_ping_title("en"), get_ping_button("en"))
def test_translations_renders_on_screen(client: Client):
def test_translations_renders_on_screen(session: Session):
czech_data = get_lang_json("cs")
# Setting some values of words__confirm key and checking that in ping screen title
assert client.features.language == "en-US"
assert session.features.language == "en-US"
# Normal english
_check_ping_screen_texts(client, get_ping_title("en"), get_ping_button("en"))
_check_ping_screen_texts(session, get_ping_title("en"), get_ping_button("en"))
# Normal czech
set_language(client, "cs")
assert client.features.language == "cs-CZ"
_check_ping_screen_texts(client, get_ping_title("cs"), get_ping_button("cs"))
set_language(session, "cs")
assert session.features.language == "cs-CZ"
_check_ping_screen_texts(session, get_ping_title("cs"), get_ping_button("cs"))
# Modified czech - changed value
czech_data_copy = deepcopy(czech_data)
new_czech_confirm = "ABCD"
czech_data_copy["translations"]["words__confirm"] = new_czech_confirm
device.change_language(
client,
language_data=build_and_sign_blob(czech_data_copy, client),
session,
language_data=build_and_sign_blob(czech_data_copy, session),
)
_check_ping_screen_texts(client, new_czech_confirm, get_ping_button("cs"))
_check_ping_screen_texts(session, new_czech_confirm, get_ping_button("cs"))
# Modified czech - key deleted completely, english is shown
czech_data_copy = deepcopy(czech_data)
del czech_data_copy["translations"]["words__confirm"]
device.change_language(
client,
language_data=build_and_sign_blob(czech_data_copy, client),
session,
language_data=build_and_sign_blob(czech_data_copy, session),
)
_check_ping_screen_texts(client, get_ping_title("en"), get_ping_button("cs"))
_check_ping_screen_texts(session, get_ping_title("en"), get_ping_button("cs"))
def test_reject_update(client: Client):
assert client.features.language == "en-US"
def test_reject_update(session: Session):
assert session.features.language == "en-US"
lang = "cs"
language_data = build_and_sign_blob(lang, client)
language_data = build_and_sign_blob(lang, session)
def input_flow_reject():
yield
client.debug.press_no()
session.client.debug.press_no()
with pytest.raises(exceptions.Cancelled), client:
with pytest.raises(exceptions.Cancelled), session, session.client as client:
client.set_input_flow(input_flow_reject)
device.change_language(client, language_data)
device.change_language(session, language_data)
assert client.features.language == "en-US"
assert session.features.language == "en-US"
_check_ping_screen_texts(client, get_ping_title("en"), get_ping_button("en"))
_check_ping_screen_texts(session, get_ping_title("en"), get_ping_button("en"))
def _maybe_confirm_set_language(
client: Client, lang: str, show_display: bool | None, is_displayed: bool
session: Session, lang: str, show_display: bool | None, is_displayed: bool
) -> None:
language_data = build_and_sign_blob(lang, client)
language_data = build_and_sign_blob(lang, session)
CHUNK_SIZE = 1024
@ -289,34 +297,35 @@ def _maybe_confirm_set_language(
expected_responses_silent: list[Any] = [
messages.TranslationDataRequest(data_offset=off, data_length=len)
for off, len in chunks(language_data, CHUNK_SIZE)
] + [message_filters.Success(), message_filters.Features()]
] + [message_filters.Success()]
# , message_filters.Features()]
expected_responses_confirm = expected_responses_silent[:]
# confirmation after first TranslationDataRequest
expected_responses_confirm.insert(1, message_filters.ButtonRequest())
# success screen before Success / Features
expected_responses_confirm.insert(-2, message_filters.ButtonRequest())
expected_responses_confirm.insert(-1, message_filters.ButtonRequest())
if is_displayed:
expected_responses = expected_responses_confirm
else:
expected_responses = expected_responses_silent
with client:
client.set_expected_responses(expected_responses)
device.change_language(client, language_data, show_display=show_display)
assert client.features.language is not None
assert client.features.language[:2] == lang
with session:
session.set_expected_responses(expected_responses)
device.change_language(session, language_data, show_display=show_display)
assert session.features.language is not None
assert session.features.language[:2] == lang
# explicitly handle the cases when expected_responses are correct for
# change_language but incorrect for selected is_displayed mode (otherwise the
# user would get an unhelpful generic expected_responses mismatch)
if is_displayed and client.actual_responses == expected_responses_silent:
if is_displayed and session.actual_responses == expected_responses_silent:
raise AssertionError("Change should have been visible but was silent")
if not is_displayed and client.actual_responses == expected_responses_confirm:
if not is_displayed and session.actual_responses == expected_responses_confirm:
raise AssertionError("Change should have been silent but was visible")
# if the expected_responses do not match either, the generic error message will
# be raised by the client context manager
# be raised by the session context manager
@pytest.mark.parametrize(
@ -328,61 +337,64 @@ def _maybe_confirm_set_language(
],
)
@pytest.mark.setup_client(uninitialized=True)
def test_silent_first_install(client: Client, show_display: bool, is_displayed: bool):
assert not client.features.initialized
_maybe_confirm_set_language(client, "cs", show_display, is_displayed)
@pytest.mark.uninitialized_session
def test_silent_first_install(session: Session, show_display: bool, is_displayed: bool):
assert not session.features.initialized
_maybe_confirm_set_language(session, "cs", show_display, is_displayed)
@pytest.mark.parametrize("show_display", (True, None))
def test_switch_from_english(client: Client, show_display: bool | None):
assert client.features.initialized
assert client.features.language == "en-US"
_maybe_confirm_set_language(client, "cs", show_display, True)
def test_switch_from_english(session: Session, show_display: bool | None):
assert session.features.initialized
assert session.features.language == "en-US"
_maybe_confirm_set_language(session, "cs", show_display, True)
def test_switch_from_english_not_silent(client: Client):
assert client.features.initialized
assert client.features.language == "en-US"
def test_switch_from_english_not_silent(session: Session):
assert session.features.initialized
assert session.features.language == "en-US"
with pytest.raises(
exceptions.TrezorFailure, match="Cannot change language without user prompt"
):
_maybe_confirm_set_language(client, "cs", False, False)
_maybe_confirm_set_language(session, "cs", False, False)
@pytest.mark.setup_client(uninitialized=True)
def test_switch_language(client: Client):
assert not client.features.initialized
assert client.features.language == "en-US"
@pytest.mark.uninitialized_session
def test_switch_language(session: Session):
assert not session.features.initialized
assert session.features.language == "en-US"
# switch to Czech silently
_maybe_confirm_set_language(client, "cs", False, False)
_maybe_confirm_set_language(session, "cs", False, False)
# switch to French silently
with pytest.raises(
exceptions.TrezorFailure, match="Cannot change language without user prompt"
):
_maybe_confirm_set_language(client, "fr", False, False)
_maybe_confirm_set_language(session, "fr", False, False)
# switch to French with display, explicitly
_maybe_confirm_set_language(client, "fr", True, True)
_maybe_confirm_set_language(session, "fr", True, True)
# switch back to Czech with display, implicitly
_maybe_confirm_set_language(client, "cs", None, True)
_maybe_confirm_set_language(session, "cs", None, True)
def test_header_trailing_data(client: Client):
def test_header_trailing_data(session: Session):
"""Adding trailing data to _header_ section specifically must be accepted by
firmware, as long as the blob is otherwise valid and signed.
(this ensures forwards compatibility if we extend the header)
"""
assert client.features.language == "en-US"
assert session.features.language == "en-US"
lang = "cs"
blob = prepare_blob(lang, client.model, client.version)
blob = prepare_blob(lang, session.model, session.version)
blob.header_bytes += b"trailing dataa"
assert len(blob.header_bytes) % 2 == 0, "Trailing data must keep the 2-alignment"
language_data = sign_blob(blob)
device.change_language(client, language_data)
assert client.features.language == "cs-CZ"
_check_ping_screen_texts(client, get_ping_title(lang), get_ping_button(lang))
device.change_language(session, language_data)
assert session.features.language == "cs-CZ"
_check_ping_screen_texts(session, get_ping_title(lang), get_ping_button(lang))

View File

@ -19,7 +19,8 @@ from pathlib import Path
import pytest
from trezorlib import btc, device, exceptions, messages, misc, models
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.client import ProtocolVersion
from trezorlib.debuglink import SessionDebugWrapper as Session
from trezorlib.tools import parse_path
from ..input_flows import InputFlowConfirmAllWarnings
@ -30,7 +31,7 @@ HERE = Path(__file__).parent.resolve()
EXPECTED_RESPONSES_NOPIN = [
messages.ButtonRequest(),
messages.Success,
messages.Features,
# messages.Features,
]
EXPECTED_RESPONSES_PIN_T1 = [messages.PinMatrixRequest()] + EXPECTED_RESPONSES_NOPIN
EXPECTED_RESPONSES_PIN_TT = [messages.ButtonRequest()] + EXPECTED_RESPONSES_NOPIN
@ -38,7 +39,7 @@ EXPECTED_RESPONSES_PIN_TT = [messages.ButtonRequest()] + EXPECTED_RESPONSES_NOPI
EXPECTED_RESPONSES_EXPERIMENTAL_FEATURES = [
messages.ButtonRequest,
messages.Success,
messages.Features,
# messages.Features,
]
PIN4 = "1234"
@ -50,173 +51,178 @@ T1_HOMESCREEN = b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x
TR_HOMESCREEN = b"TOIG\x80\x00@\x00\x0c\x04\x00\x00\xa5RY\x96\xdc0\x08\xe4\x06\xdc\xff\x96\xdc\x80\xa8\x16\x90z\xd2y\xf9\x18{<m\xc9\x02j\xeb\xea_\xddy\xfe~\xf14:\xfc\xe2I\x00\xf8\xff\x13\xff\xfa\xc6>\xc0\xf1\xe5\xc9y\x0f\x95\x7f;C\xfe\xd0\xe1K\xefS\x96o\xf9\xb739\x1a\n\xc7\xde\x89\xff\x11\xd8=\xd5\xcf\xb1\x9f\xf7U\xf2\xa3spx\xb0&t\xe4\xaf3x\xcaT\xec\xe50k\xb4\xe8\nl\x16\xbf`'\xf3\xa7Z\x8d-\x98h\x1c\x03\x07\xf0\xcf\xf0\x8aD\x13\xec\x1f@y\x9e\xd8\xa3\xc6\x84F*\x1dx\x02U\x00\x10\xd3\x8cF\xbb\x97y\x18J\xa5T\x18x\x1c\x02\xc6\x90\xfd\xdc\x89\x1a\x94\xb3\xeb\x01\xdc\x9f2\x8c/\xe9/\x8c$\xc6\x9c\x1e\xf8C\x8f@\x17Q\x1d\x11F\x02g\xe4A \xebO\xad\xc6\xe3F\xa7\x8b\xf830R\x82\x0b\x8e\x16\x1dL,\x14\xce\x057tht^\xfe\x00\x9e\x86\xc2\x86\xa3b~^Bl\x18\x1f\xb9+w\x11\x14\xceO\xe9\xb6W\xd8\x85\xbeX\x17\xc2\x13,M`y\xd1~\xa3/\xcd0\xed6\xda\xf5b\x15\xb5\x18\x0f_\xf6\xe2\xdc\x8d\x8ez\xdd\xd5\r^O\x9e\xb6|\xc4e\x0f\x1f\xff0k\xd4\xb8\n\x12{\x8d\x8a>\x0b5\xa2o\xf2jZ\xe5\xee\xdc\x14\xd1\xbd\xd5\xad\x95\xbe\x8c\t\x8f\xb9\xde\xc4\xa551,#`\x94'\x1b\xe7\xd53u\x8fq\xbd4v>3\x8f\xcc\x1d\xbcV>\x90^\xb3L\xc3\xde0]\x05\xec\x83\xd0\x07\xd2(\xbb\xcf+\xd0\xc7ru\xecn\x14k-\xc0|\xd2\x0e\xe8\xe08\xa8<\xdaQ+{\xad\x01\x02#\x16\x12+\xc8\xe0P\x06\xedD7\xae\xd0\xa4\x97\x84\xe32\xca;]\xd04x:\x94`\xbe\xca\x89\xe2\xcb\xc5L\x03\xac|\xe7\xd5\x1f\xe3\x08_\xee!\x04\xd2\xef\x00\xd8\xea\x91p)\xed^#\xb1\xa78eJ\x00F*\xc7\xf1\x0c\x1a\x04\xf5l\xcc\xfc\xa4\x83,c\x1e\xb1>\xc5q\x8b\xe6Y9\xc7\x07\xfa\xcf\xf9\x15\x8a\xdd\x11\x1f\x98\x82\xbe>\xbe+u#g]aC\\\x1bC\xb1\xe8P\xce2\xd6\xb6r\x12\x1c*\xd3\x92\x9d9\xf9cB\x82\xf9S.\xc2B\xe7\x9d\xcf\xdb\xf3\xfd#\xfd\x94x9p<D?\x0e0\xd0)ufMK\x9d\x84\xbf\x95\x02\x15\x04\xaf\x9b\xd7|\x9f\xf5\xc2\x19D\xe1\xe8pC=\\\xb54\xff\xfd<\xfc\x8b\x83\x19\x9aZ\x99J\x9d\xa2oP6\xb2=\xe0\xe5=Z0\x7f\xb6\xe9\xb1\x98\n\xcc \xdb\x9f\xb6\xf4\xc2\x82Z:\t\xf2\xcd\x88\xe3\x8a0\n\x13\xdd\xf9;\xdbtr\xf4kj\xa6\x90\x9d\x97\x92+#\xf4;t\x1e6\x80\xcd)\xfe\xe1\xabdD(V\xf5\xcc\xcf\xbeY\xd8\xddX\x08*\xc5\xd6\xa1\xa2\xae\x89s]\xafj\x9b\x07\x8d\xcf\xb5\n\x162\xb7\xb0\x02p\xc0.{\xbf\xd6\xc7|\x8a\x8c\xc9g\xa8DO\x85\xf6<E\x05Ek\x8c\xbfU\x13bz\xcf\xd0\x07\xcd^\x0f\x9b\x951\xa1vb\x17u:\xd2X\x91/\x0f\x9a\xae\x16T\x81\xb6\x8e\xdc,\xb0\xa1=\x11af%^\xec\x95\x83\xa9\xb8+\xd0i\xe0+#%\x02\xfd2\x84\xf3\xde\x0c\x88\x8c\x80\xf7\xc2H\xaa#\x80m\xf4\x1e\xd4#\x04J\r\xb6\xf83s\x8c\x0e\x0bx\xabw\xbe\x90\x94\x90:C\x88\x9bR`B\xc02\x1a\x08\xca-M9\xac\xa3TP\xb1\x83\xf2\x8aT\xe9\xc0c9(\xe5d\xd1\xac\xfd\x83\xf3\xb4C\x95\x04doh\xd7M\xed \xd0\x90\xc9|\x8a\x1fX\x1f\x0eI\x12\x8e&\xc3\x91NM-\x02\xeckp\x1a/\x19\x9d\xf2\xb4$\x0eG:\xbe\xb2~\x10(,\x1cd\x07\xbb]n^F@\x173'\xc63\xdf!u\xf4F\xa9\xc3\x96E!e\xc2Iv\xe8zQH=v\x89\x9a\x04a^\x10\x06\x01\x04!2\xa6\x1b\xba\x111/\xfa\xfa\x9c\x15 @\xf6\xb9{&\xcc\x84\xfa\xd6\x81\x90\xd4\x92\xcf\x89/\xc8\x80\xadP\xa3\xf4Xa\x1f\x04A\x07\xe6N\xd2oEZ\xc9\xa6(!\x8e#|\x0e\xfbq\xce\xe6\x8b-;\x06_\x04n\xdc\x8d^\x05s\xd2\xa8\x0f\xfa/\xfa\xf8\xe1x\n\xa3\xf701i7\x0c \x87\xec#\x80\x9c^X\x02\x01C\xc7\x85\x83\x9dS\xf5\x07"
def _set_expected_responses(client: Client):
client.use_pin_sequence([PIN4])
if client.model is models.T1B1:
client.set_expected_responses(EXPECTED_RESPONSES_PIN_T1)
def _set_expected_responses(session: Session):
session.client.use_pin_sequence([PIN4])
if session.model is models.T1B1:
session.set_expected_responses(EXPECTED_RESPONSES_PIN_T1)
else:
client.set_expected_responses(EXPECTED_RESPONSES_PIN_TT)
session.set_expected_responses(EXPECTED_RESPONSES_PIN_TT)
def test_apply_settings(client: Client):
assert client.features.label == "test"
def test_apply_settings(session: Session):
assert session.features.label == "test"
with client:
_set_expected_responses(client)
device.apply_settings(client, label="new label")
with session:
_set_expected_responses(session)
device.apply_settings(session, label="new label")
assert client.features.label == "new label"
assert session.features.label == "new label"
@pytest.mark.models("core")
def test_apply_settings_rotation(client: Client):
assert client.features.display_rotation is None
def test_apply_settings_rotation(session: Session):
assert session.features.display_rotation is None
with client:
_set_expected_responses(client)
device.apply_settings(client, display_rotation=messages.DisplayRotation.West)
with session:
_set_expected_responses(session)
device.apply_settings(session, display_rotation=messages.DisplayRotation.West)
assert client.features.display_rotation == messages.DisplayRotation.West
assert session.features.display_rotation == messages.DisplayRotation.West
@pytest.mark.setup_client(pin=PIN4, passphrase=False)
def test_apply_settings_passphrase(client: Client):
with client:
_set_expected_responses(client)
device.apply_settings(client, use_passphrase=True)
def test_apply_settings_passphrase(session: Session):
with session:
_set_expected_responses(session)
device.apply_settings(session, use_passphrase=True)
assert client.features.passphrase_protection is True
assert session.features.passphrase_protection is True
with client:
client.set_expected_responses(EXPECTED_RESPONSES_NOPIN)
device.apply_settings(client, use_passphrase=False)
with session:
session.set_expected_responses(EXPECTED_RESPONSES_NOPIN)
device.apply_settings(session, use_passphrase=False)
assert client.features.passphrase_protection is False
assert session.features.passphrase_protection is False
with client:
client.set_expected_responses(EXPECTED_RESPONSES_NOPIN)
device.apply_settings(client, use_passphrase=True)
with session:
session.set_expected_responses(EXPECTED_RESPONSES_NOPIN)
device.apply_settings(session, use_passphrase=True)
assert client.features.passphrase_protection is True
assert session.features.passphrase_protection is True
@pytest.mark.setup_client(passphrase=False)
@pytest.mark.models("core")
def test_apply_settings_passphrase_on_device(client: Client):
def test_apply_settings_passphrase_on_device(session: Session):
# enable passphrase
with client:
client.set_expected_responses(EXPECTED_RESPONSES_NOPIN)
device.apply_settings(client, use_passphrase=True)
with session:
session.set_expected_responses(EXPECTED_RESPONSES_NOPIN)
device.apply_settings(session, use_passphrase=True)
assert client.features.passphrase_protection is True
assert session.features.passphrase_protection is True
# enable force on device
with client:
client.set_expected_responses(EXPECTED_RESPONSES_NOPIN)
device.apply_settings(client, passphrase_always_on_device=True)
with session:
session.set_expected_responses(EXPECTED_RESPONSES_NOPIN)
device.apply_settings(session, passphrase_always_on_device=True)
assert client.features.passphrase_protection is True
assert client.features.passphrase_always_on_device is True
assert session.features.passphrase_protection is True
assert session.features.passphrase_always_on_device is True
# turning off the passphrase should also clear the always_on_device setting
with client:
client.set_expected_responses(EXPECTED_RESPONSES_NOPIN)
device.apply_settings(client, use_passphrase=False)
with session:
session.set_expected_responses(EXPECTED_RESPONSES_NOPIN)
device.apply_settings(session, use_passphrase=False)
assert client.features.passphrase_protection is False
assert client.features.passphrase_always_on_device is False
assert session.features.passphrase_protection is False
assert session.features.passphrase_always_on_device is False
# and turning it back on does not modify always_on_device
with client:
client.set_expected_responses(EXPECTED_RESPONSES_NOPIN)
device.apply_settings(client, use_passphrase=True)
with session:
session.set_expected_responses(EXPECTED_RESPONSES_NOPIN)
device.apply_settings(session, use_passphrase=True)
assert client.features.passphrase_protection is True
assert client.features.passphrase_always_on_device is False
assert session.features.passphrase_protection is True
assert session.features.passphrase_always_on_device is False
@pytest.mark.models("safe3")
def test_apply_homescreen_tr_toif_good(client: Client):
with client:
_set_expected_responses(client)
device.apply_settings(client, homescreen=TR_HOMESCREEN)
def test_apply_homescreen_tr_toif_good(session: Session):
with session:
_set_expected_responses(session)
device.apply_settings(session, homescreen=TR_HOMESCREEN)
# Revert to default settings
client.set_expected_responses(EXPECTED_RESPONSES_NOPIN)
device.apply_settings(client, homescreen=b"")
session.set_expected_responses(EXPECTED_RESPONSES_NOPIN)
device.apply_settings(session, homescreen=b"")
@pytest.mark.models("safe3")
@pytest.mark.setup_client(pin=None) # so that "PIN NOT SET" is shown in the header
def test_apply_homescreen_tr_toif_with_notification(client: Client):
with client:
client.set_expected_responses(EXPECTED_RESPONSES_NOPIN)
device.apply_settings(client, homescreen=TR_HOMESCREEN)
def test_apply_homescreen_tr_toif_with_notification(session: Session):
with session:
session.set_expected_responses(EXPECTED_RESPONSES_NOPIN)
device.apply_settings(session, homescreen=TR_HOMESCREEN)
@pytest.mark.models("safe3")
def test_apply_homescreen_tr_toif_with_long_label(client: Client):
with client:
_set_expected_responses(client)
device.apply_settings(client, homescreen=TR_HOMESCREEN)
def test_apply_homescreen_tr_toif_with_long_label(session: Session):
with session:
_set_expected_responses(session)
device.apply_settings(session, homescreen=TR_HOMESCREEN)
# Showing longer label
with client:
device.apply_settings(client, label="My long label")
with session:
device.apply_settings(session, label="My long label")
# Showing label that will not fit on the line
with client:
device.apply_settings(client, label="My even longer label")
with session:
device.apply_settings(session, label="My even longer label")
@pytest.mark.models("safe3")
def test_apply_homescreen_tr_toif_wrong_size(client: Client):
def test_apply_homescreen_tr_toif_wrong_size(session: Session):
# 64x64 img
img = b"TOIG@\x00@\x009\x02\x00\x00}R\xdb\x81$A\x08\"\x03\xf3\xcf\xd2\x0c<\x01-{\xefc\xe6\xd5\xbbU\xa2\x08T\xd6\xcfw\xf4\xe7\xc7\xb7X\xf1\xe3\x1bl\xf0\xf7\x1b\xf8\x1f\xcf\xe7}\xe1\x83\xcf|>\x8d%\x14\xa5\xb3\xe9p5\xa1;~4:\xcd\xe0&\x11\x1d\xe9\xf6\xa1\x1fw\xf54\x95eWx\xda\xd0u\x91\x86\xb8\xbc\xdf\xdc\x008f\x15\xc6\xf6\x7f\xf0T\xb8\xc1\xa3\xc5_A\xc0G\x930\xe7\xdc=\xd5\xa7\xc1\xbcI\x16\xb8s\x9c&\xaa\x06\xc1}\x8b\x19\x9d'c\xc3\xe3^\xc3m\xb6n\xb0(\x16\xf6\xdeg\xb3\x96:i\xe5\x9c\x02\x93\x9fF\x9f-\xa7\"w\xf3X\x9f\x87\x08\x84\"v,\xab!9:<j+\xcb\xf3_\xc7\xd6^<\xce\xc1\xb8!\xec\x8f/\xb1\xc1\x8f\xbd\xcc\x06\x90\x0e\x98)[\xdb\x15\x99\xaf\xf2~\x8e\xd0\xdb\xcd\xfd\x90\x12\xb6\xdd\xc3\xdd|\x96$\x01P\x86H\xbc\xc0}\xa2\x08\xe5\x82\x06\xd2\xeb\x07[\r\xe4\xdeP\xf4\x86;\xa5\x14c\x12\xe3\xb16x\xad\xc7\x1d\x02\xef\x86<\xc6\x95\xd3/\xc4 \xa1\xf5V\xe2\t\xb2\x8a\xd6`\xf2\xcf\xb7\xd6\x07\xdf8X\xa7\x18\x03\x96\x82\xa4 \xeb.*kP\xceu\x9d~}H\xe9\xb8\x04<4\xff\xf8\xcf\xf6\xa0\xf2\xfcM\xe3/?k\xff\x18\x1d\xb1\xee\xc5\xf5\x1f\x01\x14\x03;\x1bU\x1f~\xcf\xb3\xf7w\xe5\nMfd/\xb93\x9fq\x9bQ\xb7'\xbfvq\x1d\xce\r\xbaDo\x90\xbc\xc5:?;\x84y\x8a\x1e\xad\xe9\xb7\x14\x10~\x9b@\xf8\x82\xdc\x89\xe7\xf0\xe0k4o\x9a\xa0\xc4\xb9\xba\xc56\x01i\x85EO'e6\xb7\x15\xb4G\x05\xe1\xe7%\xd3&\x93\x91\xc9CTQ\xeb\xcc\xd0\xd7E9\xa9JK\xcc\x00\x95(\xdc.\xd2#7:Yo}y_*\x1a\xae6)\x97\x9d\xc0\x80vl\x02\\M\xfe\xc9sW\xa8\xfbD\x99\xb8\xb0:\xbc\x80\xfd\xef\xd3\x94\xbe\x18j9z\x12S\xa1\xec$\x1c\xe3\xd1\xd0\xf4\xdd\xbfI\xf1rBj\x0f\x1cz\x1d\xf7\xa5tR\xb3\xfc\xa4\xd0\xfah\xc3Mj\xbe\x14r\x9d\x84z\xd2\x7f\x13\xb4w\xce\xa0\xaeW\xa4\x18\x0b\xe4\x8f\xe6\xc3\xbeQ\x93\xb0L<J\xe3g9\xb5W#f\xd1\x0b\x96|\xd6z1;\x85\x7f\xe3\xe6[\x02A\xdc\xa4\x02\x1b\x91\x88\x7f"
with pytest.raises(exceptions.TrezorFailure), client:
_set_expected_responses(client)
device.apply_settings(client, homescreen=img)
with pytest.raises(exceptions.TrezorFailure), session:
_set_expected_responses(session)
device.apply_settings(session, homescreen=img)
@pytest.mark.models("safe3")
def test_apply_homescreen_tr_upload_jpeg_fail(client: Client):
def test_apply_homescreen_tr_upload_jpeg_fail(session: Session):
with open(HERE / "test_bg.jpg", "rb") as f:
img = f.read()
with pytest.raises(exceptions.TrezorFailure), client:
_set_expected_responses(client)
device.apply_settings(client, homescreen=img)
with pytest.raises(exceptions.TrezorFailure), session:
_set_expected_responses(session)
device.apply_settings(session, homescreen=img)
@pytest.mark.models("safe3")
def test_apply_homescreen_tr_upload_t1_fail(client: Client):
with pytest.raises(exceptions.TrezorFailure), client:
_set_expected_responses(client)
device.apply_settings(client, homescreen=T1_HOMESCREEN)
def test_apply_homescreen_tr_upload_t1_fail(session: Session):
with pytest.raises(exceptions.TrezorFailure), session:
_set_expected_responses(session)
device.apply_settings(session, homescreen=T1_HOMESCREEN)
@pytest.mark.models(skip=["legacy", "safe3"])
def test_apply_homescreen_toif(client: Client):
def test_apply_homescreen_toif(session: Session):
img = b"TOIf\x90\x00\x90\x00~\x00\x00\x00\xed\xd2\xcb\r\x83@\x10D\xc1^.\xde#!\xac31\x99\x10\x8aC%\x14~\x16\x92Y9\x02WI3\x01<\xf5cI2d\x1es(\xe1[\xdbn\xba\xca\xe8s7\xa4\xd5\xd4\xb3\x13\xbdw\xf6:\xf3\xd1\xe7%\xc7]\xdd_\xb3\x9e\x9f\x9e\x9fN\xed\xaaE\xef\xdc\xcf$D\xa7\xa4X\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0OV"
with pytest.raises(exceptions.TrezorFailure), client:
_set_expected_responses(client)
device.apply_settings(client, homescreen=img)
with pytest.raises(exceptions.TrezorFailure), session:
_set_expected_responses(session)
device.apply_settings(session, homescreen=img)
@pytest.mark.models(skip=["legacy", "safe3"])
def test_apply_homescreen_jpeg(client: Client):
def test_apply_homescreen_jpeg(session: Session):
if session.protocol_version is ProtocolVersion.PROTOCOL_V2:
raise Exception(
"FAILS BECAUSE THE MESSAGE IS BIGGER THAN THE INTERNAL READ BUFFER"
)
with open(HERE / "test_bg.jpg", "rb") as f:
img = f.read()
with client:
_set_expected_responses(client)
device.apply_settings(client, homescreen=img)
# raise Exception("FAILS FOR SOME REASON ")
with session:
_set_expected_responses(session)
device.apply_settings(session, homescreen=img)
client.set_expected_responses(EXPECTED_RESPONSES_NOPIN)
device.apply_settings(client, homescreen=b"")
session.set_expected_responses(EXPECTED_RESPONSES_NOPIN)
device.apply_settings(session, homescreen=b"")
@pytest.mark.models(skip=["legacy", "safe3"])
def test_apply_homescreen_jpeg_progressive(client: Client):
def test_apply_homescreen_jpeg_progressive(session: Session):
img = (
b"\xff\xd8\xff\xe0\x00\x10JFIF\x00\x01\x01\x01\x01,\x01,"
b"\x00\x00\xff\xdb\x00C\x00\x02\x01\x01\x02\x01\x01\x02\x02\x02\x02\x02\x02\x02\x02\x03\x05\x03\x03\x03\x03"
@ -266,13 +272,13 @@ def test_apply_homescreen_jpeg_progressive(client: Client):
b"\x00\x00\x00\x00\x90\xff\xda\x00\x08\x01\x01\x00\x01?\x10a?\xff\xd9"
)
with pytest.raises(exceptions.TrezorFailure), client:
_set_expected_responses(client)
device.apply_settings(client, homescreen=img)
with pytest.raises(exceptions.TrezorFailure), session:
_set_expected_responses(session)
device.apply_settings(session, homescreen=img)
@pytest.mark.models(skip=["legacy", "safe3"])
def test_apply_homescreen_jpeg_wrong_size(client: Client):
def test_apply_homescreen_jpeg_wrong_size(session: Session):
img = (
b"\xff\xd8\xff\xe0\x00\x10JFIF\x00\x01\x01\x01\x01,\x01,"
b"\x00\x00\xff\xdb\x00C\x00\x02\x01\x01\x02\x01\x01\x02\x02\x02\x02\x02\x02\x02\x02\x03\x05\x03\x03\x03\x03"
@ -312,124 +318,125 @@ def test_apply_homescreen_jpeg_wrong_size(client: Client):
b"\x00\x00\x1f\xff\xd9"
)
with pytest.raises(exceptions.TrezorFailure), client:
_set_expected_responses(client)
device.apply_settings(client, homescreen=img)
with pytest.raises(exceptions.TrezorFailure), session:
_set_expected_responses(session)
device.apply_settings(session, homescreen=img)
@pytest.mark.models("legacy")
def test_apply_homescreen(client: Client):
with client:
_set_expected_responses(client)
device.apply_settings(client, homescreen=T1_HOMESCREEN)
def test_apply_homescreen(session: Session):
with session:
_set_expected_responses(session)
device.apply_settings(session, homescreen=T1_HOMESCREEN)
@pytest.mark.setup_client(pin=None)
def test_safety_checks(client: Client):
def test_safety_checks(session: Session):
def get_bad_address():
btc.get_address(client, "Bitcoin", parse_path("m/44h"), show_display=True)
btc.get_address(session, "Bitcoin", parse_path("m/44h"), show_display=True)
assert client.features.safety_checks == messages.SafetyCheckLevel.Strict
assert session.features.safety_checks == messages.SafetyCheckLevel.Strict
with pytest.raises(exceptions.TrezorFailure, match="Forbidden key path"), client:
client.set_expected_responses([messages.Failure])
with pytest.raises(exceptions.TrezorFailure, match="Forbidden key path"), session:
session.set_expected_responses([messages.Failure])
get_bad_address()
if client.model is not models.T1B1:
with client:
client.set_expected_responses(EXPECTED_RESPONSES_NOPIN)
if session.model is not models.T1B1:
with session:
session.set_expected_responses(EXPECTED_RESPONSES_NOPIN)
device.apply_settings(
client, safety_checks=messages.SafetyCheckLevel.PromptAlways
session, safety_checks=messages.SafetyCheckLevel.PromptAlways
)
assert client.features.safety_checks == messages.SafetyCheckLevel.PromptAlways
assert session.features.safety_checks == messages.SafetyCheckLevel.PromptAlways
with client:
client.set_expected_responses(
with session, session.client as client:
session.set_expected_responses(
[messages.ButtonRequest, messages.ButtonRequest, messages.Address]
)
IF = InputFlowConfirmAllWarnings(client)
client.set_input_flow(IF.get())
get_bad_address()
with client:
client.set_expected_responses(EXPECTED_RESPONSES_NOPIN)
device.apply_settings(client, safety_checks=messages.SafetyCheckLevel.Strict)
with session:
session.set_expected_responses(EXPECTED_RESPONSES_NOPIN)
device.apply_settings(session, safety_checks=messages.SafetyCheckLevel.Strict)
assert client.features.safety_checks == messages.SafetyCheckLevel.Strict
assert session.features.safety_checks == messages.SafetyCheckLevel.Strict
with pytest.raises(exceptions.TrezorFailure, match="Forbidden key path"), client:
client.set_expected_responses([messages.Failure])
with pytest.raises(exceptions.TrezorFailure, match="Forbidden key path"), session:
session.set_expected_responses([messages.Failure])
get_bad_address()
with client:
client.set_expected_responses(EXPECTED_RESPONSES_NOPIN)
with session:
session.set_expected_responses(EXPECTED_RESPONSES_NOPIN)
device.apply_settings(
client, safety_checks=messages.SafetyCheckLevel.PromptTemporarily
session, safety_checks=messages.SafetyCheckLevel.PromptTemporarily
)
assert client.features.safety_checks == messages.SafetyCheckLevel.PromptTemporarily
assert session.features.safety_checks == messages.SafetyCheckLevel.PromptTemporarily
with client:
client.set_expected_responses(
with session, session.client as client:
session.set_expected_responses(
[messages.ButtonRequest, messages.ButtonRequest, messages.Address]
)
if client.model is not models.T1B1:
if session.model is not models.T1B1:
IF = InputFlowConfirmAllWarnings(client)
client.set_input_flow(IF.get())
get_bad_address()
@pytest.mark.models("core")
def test_experimental_features(client: Client):
def experimental_call():
misc.get_nonce(client)
def test_experimental_features(session: Session):
assert client.features.experimental_features is None
def experimental_call():
misc.get_nonce(session)
assert session.features.experimental_features is None
# unlock
with client:
_set_expected_responses(client)
device.apply_settings(client, label="new label")
with session:
_set_expected_responses(session)
device.apply_settings(session, label="new label")
assert not client.features.experimental_features
assert not session.features.experimental_features
with pytest.raises(exceptions.TrezorFailure, match="DataError"), client:
client.set_expected_responses([messages.Failure])
with pytest.raises(exceptions.TrezorFailure, match="DataError"), session:
session.set_expected_responses([messages.Failure])
experimental_call()
with client:
client.set_expected_responses(EXPECTED_RESPONSES_EXPERIMENTAL_FEATURES)
device.apply_settings(client, experimental_features=True)
with session:
session.set_expected_responses(EXPECTED_RESPONSES_EXPERIMENTAL_FEATURES)
device.apply_settings(session, experimental_features=True)
assert client.features.experimental_features
assert session.features.experimental_features
with client:
client.set_expected_responses([messages.Nonce])
with session:
session.set_expected_responses([messages.Nonce])
experimental_call()
# relock and try again
client.lock()
with client:
session.lock()
with session, session.client as client:
client.use_pin_sequence([PIN4])
client.set_expected_responses([messages.ButtonRequest, messages.Nonce])
session.set_expected_responses([messages.ButtonRequest, messages.Nonce])
experimental_call()
@pytest.mark.setup_client(pin=None)
def test_label_too_long(client: Client):
with pytest.raises(exceptions.TrezorFailure), client:
client.set_expected_responses([messages.Failure])
device.apply_settings(client, label="A" * 33)
def test_label_too_long(session: Session):
with pytest.raises(exceptions.TrezorFailure), session:
session.set_expected_responses([messages.Failure])
device.apply_settings(session, label="A" * 33)
@pytest.mark.models(skip=["legacy", "safe3"])
@pytest.mark.setup_client(pin=None)
def test_set_brightness(client: Client):
with client:
def test_set_brightness(session: Session):
with session:
assert (
device.set_brightness(
client,
session,
None,
)
== "Settings applied"

View File

@ -20,7 +20,7 @@ import shamir_mnemonic as shamir
from trezorlib import device, messages
from trezorlib.debuglink import LayoutType
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.debuglink import SessionDebugWrapper as Session
from trezorlib.exceptions import TrezorFailure
from ..common import (
@ -41,23 +41,23 @@ from ..input_flows import (
@pytest.mark.models("core") # TODO we want this for t1 too
@pytest.mark.setup_client(needs_backup=True, mnemonic=MNEMONIC12)
def test_backup_bip39(client: Client):
assert client.features.backup_availability == messages.BackupAvailability.Required
def test_backup_bip39(session: Session):
assert session.features.backup_availability == messages.BackupAvailability.Required
with client:
with session.client as client:
IF = InputFlowBip39Backup(client)
client.set_input_flow(IF.get())
device.backup(client)
device.backup(session)
assert IF.mnemonic == MNEMONIC12
client.init_device()
assert client.features.initialized is True
# TODO remove session.init_device()
assert session.features.initialized is True
assert (
client.features.backup_availability == messages.BackupAvailability.NotAvailable
session.features.backup_availability == messages.BackupAvailability.NotAvailable
)
assert client.features.unfinished_backup is False
assert client.features.no_backup is False
assert client.features.backup_type is messages.BackupType.Bip39
assert session.features.unfinished_backup is False
assert session.features.no_backup is False
assert session.features.backup_type is messages.BackupType.Bip39
@pytest.mark.models("core")
@ -65,25 +65,25 @@ def test_backup_bip39(client: Client):
@pytest.mark.parametrize(
"click_info", [True, False], ids=["click_info", "no_click_info"]
)
def test_backup_slip39_basic(client: Client, click_info: bool):
if click_info and client.layout_type is LayoutType.TR:
def test_backup_slip39_basic(session: Session, click_info: bool):
if click_info and session.client.layout_type is LayoutType.TR:
pytest.skip("click_info not implemented on T2B1")
assert client.features.backup_availability == messages.BackupAvailability.Required
assert session.features.backup_availability == messages.BackupAvailability.Required
with client:
with session.client as client:
IF = InputFlowSlip39BasicBackup(client, click_info)
client.set_input_flow(IF.get())
device.backup(client)
device.backup(session)
client.init_device()
assert client.features.initialized is True
# TODO remove session.init_device()
assert session.features.initialized is True
assert (
client.features.backup_availability == messages.BackupAvailability.NotAvailable
session.features.backup_availability == messages.BackupAvailability.NotAvailable
)
assert client.features.unfinished_backup is False
assert client.features.no_backup is False
assert client.features.backup_type is messages.BackupType.Slip39_Basic
assert session.features.unfinished_backup is False
assert session.features.no_backup is False
assert session.features.backup_type is messages.BackupType.Slip39_Basic
expected_ms = shamir.combine_mnemonics(MNEMONIC_SLIP39_BASIC_20_3of6)
actual_ms = shamir.combine_mnemonics(IF.mnemonics[:3])
@ -121,25 +121,25 @@ def test_backup_slip39_single(client: Client):
@pytest.mark.parametrize(
"click_info", [True, False], ids=["click_info", "no_click_info"]
)
def test_backup_slip39_advanced(client: Client, click_info: bool):
if click_info and client.layout_type is LayoutType.TR:
def test_backup_slip39_advanced(session: Session, click_info: bool):
if click_info and session.client.layout_type is LayoutType.TR:
pytest.skip("click_info not implemented on T2B1")
assert client.features.backup_availability == messages.BackupAvailability.Required
assert session.features.backup_availability == messages.BackupAvailability.Required
with client:
with session.client as client:
IF = InputFlowSlip39AdvancedBackup(client, click_info)
client.set_input_flow(IF.get())
device.backup(client)
device.backup(session)
client.init_device()
assert client.features.initialized is True
# TODO remove session.init_device()
assert session.features.initialized is True
assert (
client.features.backup_availability == messages.BackupAvailability.NotAvailable
session.features.backup_availability == messages.BackupAvailability.NotAvailable
)
assert client.features.unfinished_backup is False
assert client.features.no_backup is False
assert client.features.backup_type is messages.BackupType.Slip39_Advanced
assert session.features.unfinished_backup is False
assert session.features.no_backup is False
assert session.features.backup_type is messages.BackupType.Slip39_Advanced
expected_ms = shamir.combine_mnemonics(MNEMONIC_SLIP39_ADVANCED_20)
actual_ms = shamir.combine_mnemonics(
@ -155,23 +155,23 @@ def test_backup_slip39_advanced(client: Client, click_info: bool):
[(1, 1), (2, 2), (3, 5)],
ids=["1_of_1", "2_of_2", "3_of_5"],
)
def test_backup_slip39_custom(client: Client, share_threshold, share_count):
assert client.features.backup_availability == messages.BackupAvailability.Required
def test_backup_slip39_custom(session: Session, share_threshold, share_count):
assert session.features.backup_availability == messages.BackupAvailability.Required
with client:
with session.client as client:
IF = InputFlowSlip39CustomBackup(client, share_count)
client.set_input_flow(IF.get())
device.backup(
client, group_threshold=1, groups=[(share_threshold, share_count)]
session, group_threshold=1, groups=[(share_threshold, share_count)]
)
client.init_device()
assert client.features.initialized is True
# TODO remove session.init_device()
assert session.features.initialized is True
assert (
client.features.backup_availability == messages.BackupAvailability.NotAvailable
session.features.backup_availability == messages.BackupAvailability.NotAvailable
)
assert client.features.unfinished_backup is False
assert client.features.no_backup is False
assert session.features.unfinished_backup is False
assert session.features.no_backup is False
assert len(IF.mnemonics) == share_count
assert (
@ -182,42 +182,44 @@ def test_backup_slip39_custom(client: Client, share_threshold, share_count):
# we only test this with bip39 because the code path is always the same
@pytest.mark.setup_client(no_backup=True)
def test_no_backup_fails(client: Client):
client.ensure_unlocked()
assert client.features.initialized is True
assert client.features.no_backup is True
def test_no_backup_fails(session: Session):
# TODO ?? session.ensure_unlocked()
assert session.features.initialized is True
assert session.features.no_backup is True
assert (
client.features.backup_availability == messages.BackupAvailability.NotAvailable
session.features.backup_availability == messages.BackupAvailability.NotAvailable
)
# backup attempt should fail because no_backup=True
with pytest.raises(TrezorFailure, match=r".*Seed already backed up"):
device.backup(client)
device.backup(session)
# we only test this with bip39 because the code path is always the same
@pytest.mark.setup_client(needs_backup=True)
def test_interrupt_backup_fails(client: Client):
client.ensure_unlocked()
assert client.features.initialized is True
assert client.features.backup_availability == messages.BackupAvailability.Required
assert client.features.unfinished_backup is False
assert client.features.no_backup is False
def test_interrupt_backup_fails(session: Session):
session.ensure_unlocked()
assert session.features.initialized is True
assert session.features.backup_availability == messages.BackupAvailability.Required
assert session.features.unfinished_backup is False
assert session.features.no_backup is False
# start backup
client.call_raw(messages.BackupDevice())
session.call_raw(messages.BackupDevice())
# interupt backup by sending initialize
client.init_device()
session2 = session.client.resume_session(session)
session2.refresh_features()
# check that device state is as expected
assert client.features.initialized is True
assert session2.features.initialized is True
assert (
client.features.backup_availability == messages.BackupAvailability.NotAvailable
session2.features.backup_availability
== messages.BackupAvailability.NotAvailable
)
assert client.features.unfinished_backup is True
assert client.features.no_backup is False
assert session2.features.unfinished_backup is True
assert session2.features.no_backup is False
# Second attempt at backup should fail
with pytest.raises(TrezorFailure, match=r".*Seed already backed up"):
device.backup(client)
device.backup(session2)

Some files were not shown because too many files have changed in this diff Show More