feat(tests): Device tests for SLIP-0025 CoinJoin accounts.

[no changelog]
andrewkozlik/account-naming
Andrew Kozlik 2 years ago
parent 19d5c43ce5
commit 7c1c5b4a44

@ -114,7 +114,13 @@ def get_public_node(
coin_name: Optional[str] = None,
script_type: messages.InputScriptType = messages.InputScriptType.SPENDADDRESS,
ignore_xpub_magic: bool = False,
preauthorized: bool = False,
) -> "MessageType":
if preauthorized:
res = client.call(messages.DoPreauthorized())
if not isinstance(res, messages.PreauthorizedRequest):
raise exceptions.TrezorException("Unexpected message")
return client.call(
messages.GetPublicKey(
address_n=n,

@ -23,20 +23,14 @@ from trezorlib.tools import parse_path
from ...tx_cache import TxCache
from .payment_req import make_payment_request
from .signtx import (
request_finished,
request_input,
request_meta,
request_output,
request_payment_req,
)
from .signtx import request_finished, request_input, request_output, request_payment_req
B = messages.ButtonRequestType
TX_CACHE_TESTNET = TxCache("Testnet")
TX_CACHE_MAINNET = TxCache("Bitcoin")
TXHASH_e5b7e2 = bytes.fromhex(
FAKE_TXHASH_e5b7e2 = bytes.fromhex(
"e5b7e21b5ba720e81efd6bfa9f854ababdcddc75a43bfa60bf0fe069cfd1bb8a"
)
FAKE_TXHASH_f982c0 = bytes.fromhex(
@ -63,9 +57,9 @@ def test_sign_tx(client: Client):
max_rounds=2,
max_coordinator_fee_rate=50_000_000, # 0.5 %
max_fee_per_kvbyte=3500,
n=parse_path("m/84h/1h/0h"),
n=parse_path("m/10025h/1h/0h/1h"),
coin_name="Testnet",
script_type=messages.InputScriptType.SPENDWITNESS,
script_type=messages.InputScriptType.SPENDTAPROOT,
)
client.call(messages.LockDevice())
@ -77,8 +71,8 @@ def test_sign_tx(client: Client):
btc.get_ownership_proof(
client,
"Testnet",
parse_path("m/84h/1h/0h/1/0"),
script_type=messages.InputScriptType.SPENDWITNESS,
parse_path("m/10025h/1h/0h/1h/1/0"),
script_type=messages.InputScriptType.SPENDTAPROOT,
user_confirmation=True,
commitment_data=commitment_data,
preauthorized=True,
@ -91,8 +85,8 @@ def test_sign_tx(client: Client):
btc.get_ownership_proof(
client,
"Testnet",
parse_path("m/84h/1h/0h/1/5"),
script_type=messages.InputScriptType.SPENDWITNESS,
parse_path("m/10025h/1h/0h/1h/1/5"),
script_type=messages.InputScriptType.SPENDTAPROOT,
user_confirmation=True,
commitment_data=commitment_data,
preauthorized=True,
@ -101,63 +95,69 @@ def test_sign_tx(client: Client):
inputs = [
messages.TxInputType(
# seed "alcohol woman abuse must during monitor noble actual mixed trade anger aisle"
# 84'/1'/0'/0/0
# tb1qnspxpr2xj9s2jt6qlhuvdnxw6q55jvygcf89r2
# m/10025h/1h/0h/1h/0/0
# tb1pkw382r3plt8vx6e22mtkejnqrxl4z7jugh3w4rjmfmgezzg0xqpsdaww8z
amount=100_000,
prev_hash=TXHASH_e5b7e2,
prev_hash=FAKE_TXHASH_e5b7e2,
prev_index=0,
script_type=messages.InputScriptType.EXTERNAL,
script_pubkey=bytes.fromhex("00149c02608d469160a92f40fdf8c6ccced029493088"),
script_pubkey=bytes.fromhex(
"5120b3a2750e21facec36b2a56d76cca6019bf517a5c45e2ea8e5b4ed191090f3003"
),
ownership_proof=bytearray.fromhex(
"534c001901016b2055d8190244b2ed2d46513c40658a574d3bc2deb6969c0535bb818b44d2c40002483045022100a6c7d59b453efa7b4abc9bc724a94c5655ae986d5924dc29d28bcc2b859cbace022047d2bc4422a47f7b044bd6cdfbf63fe1a0ecbf11393f4c0bf8565f867a5ced16012103505f0d82bbdd251511591b34f36ad5eea37d3220c2b81a1189084431ddb3aa3d"
"534c001901019cf1b0ad730100bd7a69e987d55348bb798e2b2096a6a5713e9517655bd2021300014052d479f48d34f1ca6872d4571413660040c3e98841ab23a2c5c1f37399b71bfa6f56364b79717ee90552076a872da68129694e1b4fb0e0651373dcf56db123c5"
),
commitment_data=commitment_data,
),
messages.TxInputType(
address_n=parse_path("m/84h/1h/0h/1/0"),
address_n=parse_path("m/10025h/1h/0h/1h/1/0"),
amount=7_289_000,
prev_hash=FAKE_TXHASH_f982c0,
prev_index=1,
script_type=messages.InputScriptType.SPENDWITNESS,
script_type=messages.InputScriptType.SPENDTAPROOT,
),
]
outputs = [
# Other's coinjoined output.
messages.TxOutputType(
address="tb1qk7j3ahs2v6hrv4v282cf0tvxh0vqq7rpt3zcml",
# seed "alcohol woman abuse must during monitor noble actual mixed trade anger aisle"
# m/10025h/1h/0h/1h/1/0
address="tb1pupzczx9cpgyqgtvycncr2mvxscl790luqd8g88qkdt2w3kn7ymhsrdueu2",
amount=50_000,
script_type=messages.OutputScriptType.PAYTOWITNESS,
script_type=messages.OutputScriptType.PAYTOADDRESS,
payment_req_index=0,
),
# Our coinjoined output.
messages.TxOutputType(
# tb1qze76uzqteg6un6jfcryrxhwvfvjj58ts0swg3d
address_n=parse_path("m/84h/1h/0h/1/1"),
# tb1phkcspf88hge86djxgtwx2wu7ddghsw77d6sd7txtcxncu0xpx22shcydyf
address_n=parse_path("m/10025h/1h/0h/1h/1/1"),
amount=50_000,
script_type=messages.OutputScriptType.PAYTOWITNESS,
script_type=messages.OutputScriptType.PAYTOTAPROOT,
payment_req_index=0,
),
# Our change output.
messages.TxOutputType(
# tb1qr5p6f5sk09sms57ket074vywfymuthlgud7xyx
address_n=parse_path("m/84h/1h/0h/1/2"),
# tb1pchruvduckkwuzm5hmytqz85emften5dnmkqu9uhfxwfywaqhuu0qjggqyp
address_n=parse_path("m/10025h/1h/0h/1h/1/2"),
amount=7_289_000 - 50_000 - 36_445 - 490,
script_type=messages.OutputScriptType.PAYTOWITNESS,
script_type=messages.OutputScriptType.PAYTOTAPROOT,
payment_req_index=0,
),
# Other's change output.
messages.TxOutputType(
address="tb1q9cqhdr9ydetjzrct6tyeuccws9505hl96azwxk",
# seed "alcohol woman abuse must during monitor noble actual mixed trade anger aisle"
# m/10025h/1h/0h/1h/1/1
address="tb1pvt7lzserh8xd5m6mq0zu9s5wxkpe5wgf5ts56v44jhrr6578hz8saxup5m",
amount=100_000 - 50_000 - 500 - 490,
script_type=messages.OutputScriptType.PAYTOWITNESS,
script_type=messages.OutputScriptType.PAYTOADDRESS,
payment_req_index=0,
),
# Coordinator's output.
messages.TxOutputType(
address="mvbu1Gdy8SUjTenqerxUaZyYjmveZvt33q",
amount=36_945,
script_type=messages.OutputScriptType.PAYTOWITNESS,
script_type=messages.OutputScriptType.PAYTOADDRESS,
payment_req_index=0,
),
]
@ -167,8 +167,8 @@ def test_sign_tx(client: Client):
recipient_name="www.example.com",
outputs=outputs,
change_addresses=[
"tb1qze76uzqteg6un6jfcryrxhwvfvjj58ts0swg3d",
"tb1qr5p6f5sk09sms57ket074vywfymuthlgud7xyx",
"tb1phkcspf88hge86djxgtwx2wu7ddghsw77d6sd7txtcxncu0xpx22shcydyf",
"tb1pchruvduckkwuzm5hmytqz85emften5dnmkqu9uhfxwfywaqhuu0qjggqyp",
],
)
payment_req.amount = None
@ -186,15 +186,6 @@ def test_sign_tx(client: Client):
request_output(3),
request_output(4),
request_input(0),
request_meta(TXHASH_e5b7e2),
request_input(0, TXHASH_e5b7e2),
request_output(0, TXHASH_e5b7e2),
request_output(1, TXHASH_e5b7e2),
request_input(1),
request_meta(FAKE_TXHASH_f982c0),
request_input(0, FAKE_TXHASH_f982c0),
request_output(0, FAKE_TXHASH_f982c0),
request_output(1, FAKE_TXHASH_f982c0),
request_input(0),
request_input(1),
request_output(0),
@ -219,7 +210,7 @@ def test_sign_tx(client: Client):
# Transaction does not exist on the blockchain, not using assert_tx_matches()
assert (
serialized_tx.hex()
== "010000000001028abbd1cf69e00fbf60fa3ba475dccdbdba4a859ffa6bfd1ee820a75b1be2b7e50000000000ffffffff0ab6ad3ba09261cfb4fa1d3680cb19332a8fe4d9de9ea89aa565bd83a2c082f90100000000ffffffff0550c3000000000000160014b7a51ede0a66ae36558a3ab097ad86bbd800786150c3000000000000160014167dae080bca35c9ea49c0c8335dcc4b252a1d7011e56d00000000001600141d03a4d2167961b853d6cadfeab08e4937c5dfe872bf0000000000001600142e01768ca46e57210f0bd2c99e630e8168fa5fe551900000000000001976a914a579388225827d9f2fe9014add644487808c695d88ac000247304402204df07c5baacca264696cc4270665cb759be05387dead8942bd41f20309ceb29002203e685b8e9483435d9b70006bb424b5fef7249415a0f212abdf202b5d62859698012103505647c017ff2156eb6da20fae72173d3b681a1d0a629f95f49e884db300689f00000000"
== "010000000001028abbd1cf69e00fbf60fa3ba475dccdbdba4a859ffa6bfd1ee820a75b1be2b7e50000000000ffffffff0ab6ad3ba09261cfb4fa1d3680cb19332a8fe4d9de9ea89aa565bd83a2c082f90100000000ffffffff0550c3000000000000225120e0458118b80a08042d84c4f0356d86863fe2bffc034e839c166ad4e8da7e26ef50c3000000000000225120bdb100a4e7ba327d364642dc653b9e6b51783bde6ea0df2ccbc1a78e3cc1329511e56d0000000000225120c5c7c63798b59dc16e97d916011e99da5799d1b3dd81c2f2e93392477417e71e72bf00000000000022512062fdf14323b9ccda6f5b03c5c2c28e35839a3909a2e14d32b595c63d53c7b88f51900000000000001976a914a579388225827d9f2fe9014add644487808c695d88ac000140c017fce789fa8db54a2ae032012d2dd6d7c76cc1c1a6f00e29b86acbf93022da8aa559009a574792c7b09b2535d288d6e03c6ed169902ed8c4c97626a83fbc1100000000"
)
# Test for a second time.
@ -255,23 +246,57 @@ def test_wrong_coordinator(client: Client):
max_rounds=10,
max_coordinator_fee_rate=50_000_000, # 0.5 %
max_fee_per_kvbyte=3500,
n=parse_path("m/84h/1h/0h"),
n=parse_path("m/10025h/1h/0h/1h"),
coin_name="Testnet",
script_type=messages.InputScriptType.SPENDWITNESS,
script_type=messages.InputScriptType.SPENDTAPROOT,
)
with pytest.raises(TrezorFailure, match="Unauthorized operation"):
btc.get_ownership_proof(
client,
"Testnet",
parse_path("m/84h/1h/0h/1/0"),
script_type=messages.InputScriptType.SPENDWITNESS,
parse_path("m/10025h/1h/0h/1h/1/0"),
script_type=messages.InputScriptType.SPENDTAPROOT,
user_confirmation=True,
commitment_data=b"\x0fwww.example.org" + (1).to_bytes(ROUND_ID_LEN, "big"),
preauthorized=True,
)
def test_wrong_account_type(client: Client):
params = {
"client": client,
"coordinator": "www.example.com",
"max_rounds": 10,
"max_coordinator_fee_rate": 50_000_000, # 0.5 %
"max_fee_per_kvbyte": 3500,
"coin_name": "Testnet",
}
# Ensure that Trezor accepts CoinJoin authorizations only for SLIP-0025 paths.
with pytest.raises(TrezorFailure, match="Forbidden path"):
btc.authorize_coinjoin(
**params,
n=parse_path("m/86h/1h/0h"),
script_type=messages.InputScriptType.SPENDTAPROOT,
)
# Ensure that Trezor accepts CoinJoin authorizations only for Taproot scripts.
with pytest.raises(TrezorFailure, match="Forbidden path"):
btc.authorize_coinjoin(
**params,
n=parse_path("m/10025h/1h/0h/1h"),
script_type=messages.InputScriptType.SPENDWITNESS,
)
# Ensure that correct parameters succeed.
btc.authorize_coinjoin(
**params,
n=parse_path("m/10025h/1h/0h/1h"),
script_type=messages.InputScriptType.SPENDTAPROOT,
)
def test_cancel_authorization(client: Client):
# Ensure that a preauthorized GetOwnershipProof fails if the commitment_data doesn't match the coordinator.
@ -281,9 +306,9 @@ def test_cancel_authorization(client: Client):
max_rounds=10,
max_coordinator_fee_rate=50_000_000, # 0.5 %
max_fee_per_kvbyte=3500,
n=parse_path("m/84h/1h/0h"),
n=parse_path("m/10025h/1h/0h/1h"),
coin_name="Testnet",
script_type=messages.InputScriptType.SPENDWITNESS,
script_type=messages.InputScriptType.SPENDTAPROOT,
)
device.cancel_authorization(client)
@ -292,14 +317,87 @@ def test_cancel_authorization(client: Client):
btc.get_ownership_proof(
client,
"Testnet",
parse_path("m/84h/1h/0h/1/0"),
script_type=messages.InputScriptType.SPENDWITNESS,
parse_path("m/10025h/1h/0h/1h/1/0"),
script_type=messages.InputScriptType.SPENDTAPROOT,
user_confirmation=True,
commitment_data=b"\x0fwww.example.com" + (1).to_bytes(ROUND_ID_LEN, "big"),
preauthorized=True,
)
def test_get_public_key(client: Client):
expected_xpub = "xpub6DyhEpXMikKQgH2S1UcRwjYhxHVVLK8ffaABC5E1M1juvdik9t8VsucEnM585ZpiJjiu5uFnpuq21WnkvAH2h8LDMw6jubfX5J2ZggQX1hP"
btc.authorize_coinjoin(
client,
coordinator="www.example1.com",
max_rounds=10,
max_coordinator_fee_rate=50_000_000, # 0.5 %
max_fee_per_kvbyte=3500,
n=parse_path("m/10025h/1h/0h/1h"),
coin_name="Testnet",
script_type=messages.InputScriptType.SPENDTAPROOT,
)
# Ensure that user needs to confirm access to CoinJoin XPUB when preauthorization is not used.
with client:
client.set_expected_responses(
[messages.ButtonRequest(code=B.Other), messages.PublicKey]
)
resp = btc.get_public_node(client, parse_path("m/10025h/1h/0h/1h"))
assert resp.xpub == expected_xpub
# Ensure that user does not need to confirm access to CoinJoin XPUB when preauthorization is used.
with client:
client.set_expected_responses(
[messages.PreauthorizedRequest, messages.PublicKey]
)
resp = btc.get_public_node(
client, parse_path("m/10025h/1h/0h/1h"), preauthorized=True
)
assert resp.xpub == expected_xpub
def test_get_address(client: Client):
# Ensure that the SLIP-0025 external chain is freely accessible.
resp = btc.get_address(
client,
"Testnet",
parse_path("m/10025h/1h/0h/1h/0/0"),
script_type=messages.InputScriptType.SPENDTAPROOT,
show_display=True,
)
assert resp == "tb1pl3y9gf7xk2ryvmav5ar66ra0d2hk7lhh9mmusx3qvn0n09kmaghqh32ru7"
resp = btc.get_address(
client,
"Testnet",
parse_path("m/10025h/1h/0h/1h/0/1"),
script_type=messages.InputScriptType.SPENDTAPROOT,
show_display=False,
)
assert resp == "tb1p64rqq64rtt7eq6p0htegalcjl2nkjz64ur8xsclc59s5845jty7skp2843"
# Ensure that the SLIP-0025 internal chain is inaccessible.
with pytest.raises(TrezorFailure, match="Forbidden key path"):
btc.get_address(
client,
"Testnet",
parse_path("m/10025h/1h/0h/1h/1/0"),
script_type=messages.InputScriptType.SPENDTAPROOT,
show_display=True,
)
with pytest.raises(TrezorFailure, match="Forbidden key path"):
btc.get_address(
client,
"Testnet",
parse_path("m/10025h/1h/0h/1h/1/1"),
script_type=messages.InputScriptType.SPENDTAPROOT,
show_display=False,
)
def test_multisession_authorization(client: Client):
# Authorize CoinJoin with www.example1.com in session 1.
btc.authorize_coinjoin(
@ -308,9 +406,9 @@ def test_multisession_authorization(client: Client):
max_rounds=10,
max_coordinator_fee_rate=50_000_000, # 0.5 %
max_fee_per_kvbyte=3500,
n=parse_path("m/84h/1h/0h"),
n=parse_path("m/10025h/1h/0h/1h"),
coin_name="Testnet",
script_type=messages.InputScriptType.SPENDWITNESS,
script_type=messages.InputScriptType.SPENDTAPROOT,
)
# Open a second session.
@ -324,9 +422,9 @@ def test_multisession_authorization(client: Client):
max_rounds=10,
max_coordinator_fee_rate=50_000_000, # 0.5 %
max_fee_per_kvbyte=3500,
n=parse_path("m/84h/1h/0h"),
n=parse_path("m/10025h/1h/0h/1h"),
coin_name="Testnet",
script_type=messages.InputScriptType.SPENDWITNESS,
script_type=messages.InputScriptType.SPENDTAPROOT,
)
# Requesting a preauthorized ownership proof for www.example1.com should fail in session 2.
@ -334,8 +432,8 @@ def test_multisession_authorization(client: Client):
ownership_proof, _ = btc.get_ownership_proof(
client,
"Testnet",
parse_path("m/84h/1h/0h/1/0"),
script_type=messages.InputScriptType.SPENDWITNESS,
parse_path("m/10025h/1h/0h/1h/1/0"),
script_type=messages.InputScriptType.SPENDTAPROOT,
user_confirmation=True,
commitment_data=b"\x10www.example1.com" + (1).to_bytes(ROUND_ID_LEN, "big"),
preauthorized=True,
@ -345,8 +443,8 @@ def test_multisession_authorization(client: Client):
ownership_proof, _ = btc.get_ownership_proof(
client,
"Testnet",
parse_path("m/84h/1h/0h/1/0"),
script_type=messages.InputScriptType.SPENDWITNESS,
parse_path("m/10025h/1h/0h/1h/1/0"),
script_type=messages.InputScriptType.SPENDTAPROOT,
user_confirmation=True,
commitment_data=b"\x10www.example2.com" + (1).to_bytes(ROUND_ID_LEN, "big"),
preauthorized=True,
@ -354,7 +452,7 @@ def test_multisession_authorization(client: Client):
assert (
ownership_proof.hex()
== "534c00190101f3ce2cb33599634353452b60b38e311282b6fca743eb6147d3d492066c8963de0002483045022100e09d9c43108841930e5cb0b0336d022684ded53c7b76e2a8e037eab0950f62ae02205409788b59624c75d2af48cd0da4ab2c1814e719b6036baf2df946d9cc68b488012103505647c017ff2156eb6da20fae72173d3b681a1d0a629f95f49e884db300689f"
== "534c0019010169d0c751442f4c9adacbd42987121d75b36e3932db217e5bb3784f368f5a4c5d00014097bb2f1f87aea1e809756a6f2ef84109613ccf1bf9b96ffb9305b6193b3942510a8650693ca8af74f0f63401baa384d0c0f7188f1d2df56b91362646c82223a8"
)
# Switch back to the first session.
@ -365,8 +463,8 @@ def test_multisession_authorization(client: Client):
ownership_proof, _ = btc.get_ownership_proof(
client,
"Testnet",
parse_path("m/84h/1h/0h/1/0"),
script_type=messages.InputScriptType.SPENDWITNESS,
parse_path("m/10025h/1h/0h/1h/1/0"),
script_type=messages.InputScriptType.SPENDTAPROOT,
user_confirmation=True,
commitment_data=b"\x10www.example1.com" + (1).to_bytes(ROUND_ID_LEN, "big"),
preauthorized=True,
@ -374,7 +472,7 @@ def test_multisession_authorization(client: Client):
assert (
ownership_proof.hex()
== "534c00190101f3ce2cb33599634353452b60b38e311282b6fca743eb6147d3d492066c8963de000247304402203522d44da76232481ae7f045cddec4a2aa3f3e4e46f7a54ffe456702b6f7185b02203c95860358a703c7497f5e22c9e4506114de5d7257af651ccff1bb6cf50b80cb012103505647c017ff2156eb6da20fae72173d3b681a1d0a629f95f49e884db300689f"
== "534c0019010169d0c751442f4c9adacbd42987121d75b36e3932db217e5bb3784f368f5a4c5d00014078fefa8243283cd575c885f97fd2e3405c934ab4d3e415ff5fe27d49f347bbb592e03ff6195f46c94a592799748c8dd7daea8b3fc4b2011b7e58a74ee296853b"
)
# Requesting a preauthorized ownership proof for www.example2.com should fail in session 1.
@ -382,8 +480,8 @@ def test_multisession_authorization(client: Client):
ownership_proof, _ = btc.get_ownership_proof(
client,
"Testnet",
parse_path("m/84h/1h/0h/1/0"),
script_type=messages.InputScriptType.SPENDWITNESS,
parse_path("m/10025h/1h/0h/1h/1/0"),
script_type=messages.InputScriptType.SPENDTAPROOT,
user_confirmation=True,
commitment_data=b"\x10www.example2.com" + (1).to_bytes(ROUND_ID_LEN, "big"),
preauthorized=True,
@ -397,8 +495,8 @@ def test_multisession_authorization(client: Client):
ownership_proof, _ = btc.get_ownership_proof(
client,
"Testnet",
parse_path("m/84h/1h/0h/1/0"),
script_type=messages.InputScriptType.SPENDWITNESS,
parse_path("m/10025h/1h/0h/1h/1/0"),
script_type=messages.InputScriptType.SPENDTAPROOT,
user_confirmation=True,
commitment_data=b"\x10www.example1.com" + (1).to_bytes(ROUND_ID_LEN, "big"),
preauthorized=True,
@ -411,8 +509,8 @@ def test_multisession_authorization(client: Client):
ownership_proof, _ = btc.get_ownership_proof(
client,
"Testnet",
parse_path("m/84h/1h/0h/1/0"),
script_type=messages.InputScriptType.SPENDWITNESS,
parse_path("m/10025h/1h/0h/1h/1/0"),
script_type=messages.InputScriptType.SPENDTAPROOT,
user_confirmation=True,
commitment_data=b"\x10www.example2.com" + (1).to_bytes(ROUND_ID_LEN, "big"),
preauthorized=True,

@ -232,9 +232,9 @@ def test_experimental_features(client: Client):
max_rounds=10,
max_coordinator_fee_rate=50_000_000, # 0.5 %
max_fee_per_kvbyte=3500,
n=parse_path("m/84h/1h/0h"),
n=parse_path("m/10025h/1h/0h/1h"),
coin_name="Testnet",
script_type=messages.InputScriptType.SPENDWITNESS,
script_type=messages.InputScriptType.SPENDTAPROOT,
)
assert client.features.experimental_features is None

@ -610,8 +610,11 @@
"TT_binance-test_sign_tx.py::test_binance_sign_message[message1-expected_response1]": "805fc5ef8074c3f5cfee5f7128c2cd068fef42f4f01f9450578f50e791ff811f",
"TT_binance-test_sign_tx.py::test_binance_sign_message[message2-expected_response2]": "323e0a474e71ede187ee1332e42952aeca501b42da95f88b2bad5445a3db858c",
"TT_bitcoin-test_authorize_coinjoin.py::test_cancel_authorization": "2e5cffe7bd0dc6034852d21612fba8cf1ee3c45a14e76140a4c2786f360f54f0",
"TT_bitcoin-test_authorize_coinjoin.py::test_get_address": "39d274b177e209def42bd743d06f67da5ab8136518273de34b7006d56bf79269",
"TT_bitcoin-test_authorize_coinjoin.py::test_get_public_key": "2fc73514d4ea9271ae0d505d2aaab207490112cf4259b8694fa168f633b535f5",
"TT_bitcoin-test_authorize_coinjoin.py::test_multisession_authorization": "65c9435e10e3dede19169a9b02d373bd5acb22eba0ba3b31324271025d65d5a7",
"TT_bitcoin-test_authorize_coinjoin.py::test_sign_tx": "87b81a29fe6e27fdfedfdbb1953b3d0178786749eadbb0fe01509c1af8075de5",
"TT_bitcoin-test_authorize_coinjoin.py::test_wrong_account_type": "2e5cffe7bd0dc6034852d21612fba8cf1ee3c45a14e76140a4c2786f360f54f0",
"TT_bitcoin-test_authorize_coinjoin.py::test_wrong_coordinator": "2e5cffe7bd0dc6034852d21612fba8cf1ee3c45a14e76140a4c2786f360f54f0",
"TT_bitcoin-test_bcash.py::test_attack_change_input": "3979e688361b1ee8c0b824d58b49eb77836e190e92dc13b9c67f8fe653785aa0",
"TT_bitcoin-test_bcash.py::test_send_bch_change": "3979e688361b1ee8c0b824d58b49eb77836e190e92dc13b9c67f8fe653785aa0",

Loading…
Cancel
Save