From 2a19d70e98f971e1f1bd27b97a1bdda48cb39604 Mon Sep 17 00:00:00 2001 From: Andrew Kozlik Date: Thu, 10 Sep 2020 17:17:41 +0200 Subject: [PATCH] test: Add device tests for replacement transaction flow. --- tests/device_tests/signtx.py | 14 + .../test_msg_signtx_replacement.py | 733 ++++++++++++++++++ ...b2c932cde7d370f7cee50fd1fad6790f6206d.json | 13 + ...68ad5864228639db514c81cfb29f108bb1e7a.json | 18 + ...c4bcb37df6cd49b4c96143e99580a472f79fb.json | 1 + ...39e95efb0803071648048a7f289492e7b4c8a.json | 36 + ...de6f6b57592f32108ed9b301eeece6de24ad6.json | 22 + ...0a04f1dd6a3abc6d7b41d5e9d9f91605b37d9.json | 16 + ...ff1d0f9ed216a234e836b8d3ac65661cbb457.json | 47 ++ ...a739978fc86f35514edf7e7da25d53d83030b.json | 33 + ...a3b4a6330f9c3c0a46d96674e632df504b56b.json | 22 + ...7c7feae89fdde12867943eec91293139730d1.json | 46 ++ ...56894cfd32725c590300108f40c9edc1aac35.json | 18 + tests/ui_tests/fixtures.json | 8 + 14 files changed, 1027 insertions(+) create mode 100644 tests/device_tests/test_msg_signtx_replacement.py create mode 100644 tests/txcache/bitcoin/beafc7cbd873d06dbee88a7002768ad5864228639db514c81cfb29f108bb1e7a.json create mode 100644 tests/txcache/testnet/334cd7ad982b3b15d07dd1c84e939e95efb0803071648048a7f289492e7b4c8a.json create mode 100644 tests/txcache/testnet/5e7667690076ae4737e2f872005de6f6b57592f32108ed9b301eeece6de24ad6.json create mode 100644 tests/txcache/testnet/6673b7248e324882b2f9d02fdd1ff1d0f9ed216a234e836b8d3ac65661cbb457.json create mode 100644 tests/txcache/testnet/927784e07bbcefc4c738f5c31c7a739978fc86f35514edf7e7da25d53d83030b.json create mode 100644 tests/txcache/testnet/e4b5b24159856ea18ab5819832da3b4a6330f9c3c0a46d96674e632df504b56b.json create mode 100644 tests/txcache/testnet/ed89acb52cfa438e3653007478e7c7feae89fdde12867943eec91293139730d1.json create mode 100644 tests/txcache/testnet/efaa41ff3e67edf508846c1a1ed56894cfd32725c590300108f40c9edc1aac35.json diff --git a/tests/device_tests/signtx.py b/tests/device_tests/signtx.py index a0d6f9e9b..be75084ab 100644 --- a/tests/device_tests/signtx.py +++ b/tests/device_tests/signtx.py @@ -17,6 +17,20 @@ def request_output(n, tx_hash=None): ) +def request_orig_input(n, tx_hash): + return messages.TxRequest( + request_type=T.TXORIGINPUT, + details=messages.TxRequestDetailsType(request_index=n, tx_hash=tx_hash), + ) + + +def request_orig_output(n, tx_hash): + return messages.TxRequest( + request_type=T.TXORIGOUTPUT, + details=messages.TxRequestDetailsType(request_index=n, tx_hash=tx_hash), + ) + + def request_meta(tx_hash): return messages.TxRequest( request_type=T.TXMETA, diff --git a/tests/device_tests/test_msg_signtx_replacement.py b/tests/device_tests/test_msg_signtx_replacement.py new file mode 100644 index 000000000..7a9981369 --- /dev/null +++ b/tests/device_tests/test_msg_signtx_replacement.py @@ -0,0 +1,733 @@ +# This file is part of the Trezor project. +# +# Copyright (C) 2020 SatoshiLabs and contributors +# +# This library is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# as published by the Free Software Foundation. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the License along with this library. +# If not, see . + +import pytest + +from trezorlib import btc, messages +from trezorlib.exceptions import TrezorFailure +from trezorlib.tools import parse_path + +from ..tx_cache import TxCache +from .signtx import ( + request_finished, + request_input, + request_meta, + request_orig_input, + request_orig_output, + request_output, +) + +B = messages.ButtonRequestType + +TX_CACHE_TESTNET = TxCache("Testnet") +TX_CACHE_MAINNET = TxCache("Bitcoin") + +TXHASH_50f6f1 = bytes.fromhex( + "50f6f1209ca92d7359564be803cb2c932cde7d370f7cee50fd1fad6790f6206d" +) +TXHASH_beafc7 = bytes.fromhex( + "beafc7cbd873d06dbee88a7002768ad5864228639db514c81cfb29f108bb1e7a" +) +TXHASH_65b768 = bytes.fromhex( + "65b768dacccfb209eebd95a1fb80a04f1dd6a3abc6d7b41d5e9d9f91605b37d9" +) +TXHASH_e4b5b2 = bytes.fromhex( + "e4b5b24159856ea18ab5819832da3b4a6330f9c3c0a46d96674e632df504b56b" +) +TXHASH_70f987 = bytes.fromhex( + "70f9871eb03a38405cfd7a01e0e1448678132d815e2c9f552ad83ae23969509e" +) +TXHASH_334cd7 = bytes.fromhex( + "334cd7ad982b3b15d07dd1c84e939e95efb0803071648048a7f289492e7b4c8a" +) +TXHASH_5e7667 = bytes.fromhex( + "5e7667690076ae4737e2f872005de6f6b57592f32108ed9b301eeece6de24ad6" +) +TXHASH_efaa41 = bytes.fromhex( + "efaa41ff3e67edf508846c1a1ed56894cfd32725c590300108f40c9edc1aac35" +) +TXHASH_ed89ac = bytes.fromhex( + "ed89acb52cfa438e3653007478e7c7feae89fdde12867943eec91293139730d1" +) +TXHASH_6673b7 = bytes.fromhex( + "6673b7248e324882b2f9d02fdd1ff1d0f9ed216a234e836b8d3ac65661cbb457" +) +TXHASH_927784 = bytes.fromhex( + "927784e07bbcefc4c738f5c31c7a739978fc86f35514edf7e7da25d53d83030b" +) + + +@pytest.mark.skip_t1 +def test_p2pkh_fee_bump(client): + inp1 = messages.TxInputType( + address_n=parse_path("44h/0h/0h/0/4"), + amount=174998, + prev_hash=TXHASH_beafc7, + prev_index=0, + orig_hash=TXHASH_50f6f1, + orig_index=0, + ) + + out1 = messages.TxOutputType( + address_n=parse_path("44h/0h/0h/1/2"), + amount=174998 - 50000 - 15000, # Originally fee was 11300, now 15000. + script_type=messages.OutputScriptType.PAYTOADDRESS, + orig_hash=TXHASH_50f6f1, + orig_index=0, + ) + + out2 = messages.TxOutputType( + address="1GA9u9TfCG7SWmKCveBumdA1TZpfom6ZdJ", + amount=50000, + script_type=messages.OutputScriptType.PAYTOADDRESS, + orig_hash=TXHASH_50f6f1, + orig_index=1, + ) + + with client: + client.set_expected_responses( + [ + request_input(0), + request_meta(TXHASH_50f6f1), + request_orig_input(0, TXHASH_50f6f1), + request_output(0), + request_orig_output(0, TXHASH_50f6f1), + request_output(1), + request_orig_output(1, TXHASH_50f6f1), + messages.ButtonRequest(code=B.SignTx), + messages.ButtonRequest(code=B.SignTx), + request_input(0), + request_meta(TXHASH_beafc7), + request_input(0, TXHASH_beafc7), + request_output(0, TXHASH_beafc7), + request_orig_input(0, TXHASH_50f6f1), + request_orig_output(0, TXHASH_50f6f1), + request_orig_output(1, TXHASH_50f6f1), + request_input(0), + request_output(0), + request_output(1), + request_output(0), + request_output(1), + request_finished(), + ] + ) + _, serialized_tx = btc.sign_tx( + client, + "Bitcoin", + [inp1], + [out1, out2], + prev_txes=TX_CACHE_MAINNET, + ) + + assert ( + serialized_tx.hex() + == "01000000017a1ebb08f129fb1cc814b59d63284286d58a7602708ae8be6dd073d8cbc7afbe000000006b483045022100a8c1c118d61259f8df463deb538a10d9e9f42bbdfff28bb1337ee5426e5098f8022060e7464f7a63a83fd93dbd268f319133cb03452764afd601db063ff3eede9207012103f54094da6a0b2e0799286268bb59ca7c83538e81c78e64f6333f40f9e0e222c0ffffffff02aead0100000000001976a914902c642ba3a22f5c6cfa30a1790c133ddf15cc8888ac50c30000000000001976a914a6450f1945831a81912616691e721b787383f4ed88ac00000000" + ) + + +@pytest.mark.skip_t1 +@pytest.mark.parametrize( + "out1_amount, out2_amount, copayer_witness, expected_tx", + ( + ( + # Scenario 1: No fee bump by sender or receiver. + 10000 + 19899859, # out1: Receiver does not contribute to fee. + 100000 - 10000 - 141, # out2: Original change. + "02483045022100eb74abb36f317d707c36d6fe1f4f73192d54417b9d5cd274e0077590833aad0a02206cf26621706aaf232c48a139910de71f7dbf17f3fb6af52a7222d19d88041e8b012102d587bc96e0ceab05f27401d66dc3e596ba02f2c0d7b018b5f80eebfaeb011012", + "010000000001026bb504f52d634e67966da4c0c3f930634a3bda329881b58aa16e855941b2b5e400000000005a2417009e506939e23ad82a559f2c5e812d13788644e1e0017afd5c40383ab01e87f9700100000000ffffffff02e3cc2f0100000000160014fb7e49f4017dc951615dea221b66626189aa43b9035f0100000000001600141d03a4d2167961b853d6cadfeab08e4937c5dfe802483045022100fd695bb0b5d07f0578ba56cb385b7662b98a1eb7d61ac25eaa565376ebd042de02201dc5209206d5d4c1bb79f9278a330767bf73afa774cd6a8331068d430bc95e50012103adc58245cf28406af0ef5cc24b8afba7f1be6c72f279b642d85c48798685f86202483045022100eb74abb36f317d707c36d6fe1f4f73192d54417b9d5cd274e0077590833aad0a02206cf26621706aaf232c48a139910de71f7dbf17f3fb6af52a7222d19d88041e8b012102d587bc96e0ceab05f27401d66dc3e596ba02f2c0d7b018b5f80eebfaeb0110125a241700", + ), + ( + # Scenario 2: Sender fee bump only. + 10000 + 19899859, # out1: Receiver does not contribute to fee. + 100000 - 10000 - 200, # out2: Sender bumps fee from 141 to 200. + "02483045022100af3a874c966ee595321e8699e7157f0b21f2542ddcdcafd06a9c2b4fd75e998b02206daecf235b5eb3c9dac088c904774cc0a61ac601c840efc5cbe00f99e1979a09012102d587bc96e0ceab05f27401d66dc3e596ba02f2c0d7b018b5f80eebfaeb011012", + "010000000001026bb504f52d634e67966da4c0c3f930634a3bda329881b58aa16e855941b2b5e400000000005a2417009e506939e23ad82a559f2c5e812d13788644e1e0017afd5c40383ab01e87f9700100000000ffffffff02e3cc2f0100000000160014fb7e49f4017dc951615dea221b66626189aa43b9c85e0100000000001600141d03a4d2167961b853d6cadfeab08e4937c5dfe8024730440220524e0f020a4ed910fa8e654feca8a2d54962e9691b2e1be9648685fbe84d900402203971dbba53400ed93d69dc5811cc0c7b3d368ffa9ba92c746fda8925bd5f556f012103adc58245cf28406af0ef5cc24b8afba7f1be6c72f279b642d85c48798685f86202483045022100af3a874c966ee595321e8699e7157f0b21f2542ddcdcafd06a9c2b4fd75e998b02206daecf235b5eb3c9dac088c904774cc0a61ac601c840efc5cbe00f99e1979a09012102d587bc96e0ceab05f27401d66dc3e596ba02f2c0d7b018b5f80eebfaeb0110125a241700", + ), + ( + # Scenario 3: Receiver fee bump. + 10000 + 19899859 - 59, # out1: Receiver contributes 59 to fee. + 100000 - 10000 - 141, # out2: Sender does not bump fee. + "0248304502210097a42b35d3d16fa169667cd85a007eaf6b674495634b120d9fb62d72a0df872402203d0cdf746fd7a668276f93f660a9d052bc8a5d7cd8fea36073de38da463ece85012102d587bc96e0ceab05f27401d66dc3e596ba02f2c0d7b018b5f80eebfaeb011012", + "010000000001026bb504f52d634e67966da4c0c3f930634a3bda329881b58aa16e855941b2b5e400000000005a2417009e506939e23ad82a559f2c5e812d13788644e1e0017afd5c40383ab01e87f9700100000000ffffffff02a8cc2f0100000000160014fb7e49f4017dc951615dea221b66626189aa43b9035f0100000000001600141d03a4d2167961b853d6cadfeab08e4937c5dfe802473044022002bdb052c49648cd7a9488080c5489f89cff52b752acfcabf6e130d2e9f9fe3902202433f50b8b2a0cc4d463c44c0f24812e0b7f2f5c8f2ec67137694a934335b60f012103adc58245cf28406af0ef5cc24b8afba7f1be6c72f279b642d85c48798685f8620248304502210097a42b35d3d16fa169667cd85a007eaf6b674495634b120d9fb62d72a0df872402203d0cdf746fd7a668276f93f660a9d052bc8a5d7cd8fea36073de38da463ece85012102d587bc96e0ceab05f27401d66dc3e596ba02f2c0d7b018b5f80eebfaeb0110125a241700", + ), + ( + # Scenario 4: Receiver pays entire fee. + 10000 + 19899859 - 141, # out1: Receiver pays entire original fee of 141. + 100000 - 10000, # out2: Sender pays no fee. + "024730440220753f53049ca43d55f65633d3f1a8fe0464f24f780070db27474fd48d161b958302204a08e2956ac9bf1bdc762eb19f77cab5aa22ab24e058f31b8db2b878c875be74012102d587bc96e0ceab05f27401d66dc3e596ba02f2c0d7b018b5f80eebfaeb011012", + "010000000001026bb504f52d634e67966da4c0c3f930634a3bda329881b58aa16e855941b2b5e400000000005a2417009e506939e23ad82a559f2c5e812d13788644e1e0017afd5c40383ab01e87f9700100000000ffffffff0256cc2f0100000000160014fb7e49f4017dc951615dea221b66626189aa43b9905f0100000000001600141d03a4d2167961b853d6cadfeab08e4937c5dfe802483045022100e7f8b2d226cf98ab342c99d1bd51728661c8a81c94b0e198ea423c3cf704c29402203f522364bd1e4221bd5aa2db2364f1618b67fcddf54a838d8994b9f51f0c1c0c012103adc58245cf28406af0ef5cc24b8afba7f1be6c72f279b642d85c48798685f862024730440220753f53049ca43d55f65633d3f1a8fe0464f24f780070db27474fd48d161b958302204a08e2956ac9bf1bdc762eb19f77cab5aa22ab24e058f31b8db2b878c875be74012102d587bc96e0ceab05f27401d66dc3e596ba02f2c0d7b018b5f80eebfaeb0110125a241700", + ), + ( + # Scenario 5: Receiver bumps and pays entire fee. + 10000 + 19899859 - 200, # out1: Receiver bumps fee from 141 to 200. + 100000 - 10000, # out2: Sender pays no fee. + "02483045022100aa1b91fb25cc9a0ace45db3dfae5d0beffdda4b76ccd4f362b460729efdf78b502206ed6de7fb6cdacdddd90f184416a46ea692f4a656a26702665bf2db1ef080a03012102d587bc96e0ceab05f27401d66dc3e596ba02f2c0d7b018b5f80eebfaeb011012", + "010000000001026bb504f52d634e67966da4c0c3f930634a3bda329881b58aa16e855941b2b5e400000000005a2417009e506939e23ad82a559f2c5e812d13788644e1e0017afd5c40383ab01e87f9700100000000ffffffff021bcc2f0100000000160014fb7e49f4017dc951615dea221b66626189aa43b9905f0100000000001600141d03a4d2167961b853d6cadfeab08e4937c5dfe802473044022075c504c90351394d0d019bc5022f860ecb33c0fcbf3b448b97d03169d1605427022007f0330591652a9a4a36417dc1477c8242abcc5110b312dfffc04df06901979c012103adc58245cf28406af0ef5cc24b8afba7f1be6c72f279b642d85c48798685f86202483045022100aa1b91fb25cc9a0ace45db3dfae5d0beffdda4b76ccd4f362b460729efdf78b502206ed6de7fb6cdacdddd90f184416a46ea692f4a656a26702665bf2db1ef080a03012102d587bc96e0ceab05f27401d66dc3e596ba02f2c0d7b018b5f80eebfaeb0110125a241700", + ), + ), +) +def test_p2wpkh_payjoin(client, out1_amount, out2_amount, copayer_witness, expected_tx): + # Original input. + inp1 = messages.TxInputType( + address_n=parse_path("84h/1h/0h/0/0"), + amount=100000, + script_type=messages.InputScriptType.SPENDWITNESS, + prev_hash=TXHASH_e4b5b2, + prev_index=0, + orig_hash=TXHASH_65b768, + orig_index=0, + sequence=1516634, + ) + + # New presigned external input. (Actually 84h/1h/0h/1/1, making it easier to generate witnesses.) + inp2 = messages.TxInputType( + amount=19899859, + script_type=messages.InputScriptType.EXTERNAL, + prev_hash=TXHASH_70f987, + prev_index=1, + witness=bytes.fromhex(copayer_witness), + ) + + # PayJoined output. + out1 = messages.TxOutputType( + address="tb1qldlynaqp0hy4zc2aag3pkenzvxy65saesxw3wd", + # Originally payment was 10000, now we add receiver's inp2. + amount=out1_amount, + script_type=messages.OutputScriptType.PAYTOWITNESS, + orig_hash=TXHASH_65b768, + orig_index=0, + ) + + # Original change. + out2 = messages.TxOutputType( + address_n=parse_path("84h/1h/0h/1/2"), + amount=out2_amount, + script_type=messages.OutputScriptType.PAYTOWITNESS, + orig_hash=TXHASH_65b768, + orig_index=1, + ) + + with client: + client.set_expected_responses( + [ + request_input(0), + request_meta(TXHASH_65b768), + request_orig_input(0, TXHASH_65b768), + request_input(1), + request_output(0), + request_orig_output(0, TXHASH_65b768), + request_output(1), + request_orig_output(1, TXHASH_65b768), + messages.ButtonRequest(code=B.SignTx), + messages.ButtonRequest(code=B.SignTx), + request_input(0), + request_meta(TXHASH_e4b5b2), + request_input(0, TXHASH_e4b5b2), + request_output(0, TXHASH_e4b5b2), + request_output(1, TXHASH_e4b5b2), + request_input(1), + request_meta(TXHASH_70f987), + request_input(0, TXHASH_70f987), + request_output(0, TXHASH_70f987), + request_output(1, TXHASH_70f987), + request_input(0), + request_input(1), + request_output(0), + request_output(1), + request_input(0), + request_input(1), + request_finished(), + ] + ) + _, serialized_tx = btc.sign_tx( + client, + "Testnet", + [inp1, inp2], + [out1, out2], + lock_time=1516634, + prev_txes=TX_CACHE_TESTNET, + ) + + assert serialized_tx.hex() == expected_tx + + +@pytest.mark.skip_t1 +def test_p2wpkh_in_p2sh_remove_change(client): + # Test fee bump with change-output removal. Originally fee was 3780, now 98060. + + inp1 = messages.TxInputType( + address_n=parse_path("49h/1h/0h/0/4"), + amount=100000, + script_type=messages.InputScriptType.SPENDP2SHWITNESS, + prev_hash=TXHASH_5e7667, + prev_index=1, + orig_hash=TXHASH_334cd7, + orig_index=0, + ) + + inp2 = messages.TxInputType( + address_n=parse_path("49h/1h/0h/0/3"), + amount=998060, + script_type=messages.InputScriptType.SPENDP2SHWITNESS, + prev_hash=TXHASH_efaa41, + prev_index=0, + orig_hash=TXHASH_334cd7, + orig_index=1, + ) + + out1 = messages.TxOutputType( + # Actually m/49'/1'/0'/0/5. + address="2MvUUSiQZDSqyeSdofKX9KrSCio1nANPDTe", + amount=1000000, + orig_hash=TXHASH_334cd7, + orig_index=0, + ) + + with client: + client.set_expected_responses( + [ + request_input(0), + request_meta(TXHASH_334cd7), + request_orig_input(0, TXHASH_334cd7), + request_input(1), + request_orig_input(1, TXHASH_334cd7), + request_output(0), + request_orig_output(0, TXHASH_334cd7), + request_orig_output(1, TXHASH_334cd7), + messages.ButtonRequest(code=B.SignTx), + messages.ButtonRequest(code=B.SignTx), + request_input(0), + request_meta(TXHASH_5e7667), + request_input(0, TXHASH_5e7667), + request_output(0, TXHASH_5e7667), + request_output(1, TXHASH_5e7667), + request_input(1), + request_meta(TXHASH_efaa41), + request_input(0, TXHASH_efaa41), + request_output(0, TXHASH_efaa41), + request_input(0), + request_input(1), + request_output(0), + request_input(0), + request_input(1), + request_finished(), + ] + ) + _, serialized_tx = btc.sign_tx( + client, + "Testnet", + [inp1, inp2], + [out1], + prev_txes=TX_CACHE_TESTNET, + ) + + assert ( + serialized_tx.hex() + == "01000000000102d64ae26dceee1e309bed0821f39275b5f6e65d0072f8e23747ae76006967765e0100000017160014039ba06270e6c6c1ad4e6940515aa5cdbad33f9effffffff35ac1adc9e0cf408013090c52527d3cf9468d51e1a6c8408f5ed673eff41aaef0000000017160014209297fb46272a0b7e05139440dbd39daea3e25affffffff0140420f000000000017a9142369da13fee80c9d7fd8043bf1275c04deb360e68702483045022100c28eceaade3d0bc82e4b634d2c6d06feed4afe37c77b04b379eaf8c058b7190702202b7a369dd6104c13c60821c1ad4e7c2d8d37cf1962a9b3f5d70717709c021d63012103bb0e339d7495b1f355c49d385b79343e52e68d99de2fe1f7f476c465c9ccd16702483045022100f6a447b7f95fb067c87453c408aa648262adaf2472a7ccc754518cd06353b87502202e00359dd663eda24d381e070b92a5e41f1d047d276f685ff549a03659842b1b012103c2c2e65556ca4b7371549324b99390725493c8a6792e093a0bdcbb3e2d7df4ab00000000" + ) + + +@pytest.mark.skip_t1 +def test_tx_meld(client): + # Meld two original transactions into one, joining the change-outputs into a different one. + + inp1 = messages.TxInputType( + address_n=parse_path("49h/1h/0h/0/4"), + amount=100000, + script_type=messages.InputScriptType.SPENDP2SHWITNESS, + prev_hash=TXHASH_5e7667, + prev_index=1, + orig_hash=TXHASH_334cd7, + orig_index=0, + ) + + inp2 = messages.TxInputType( + address_n=parse_path("49h/1h/0h/0/8"), + amount=4973340, + script_type=messages.InputScriptType.SPENDP2SHWITNESS, + prev_hash=TXHASH_6673b7, + prev_index=0, + orig_hash=TXHASH_ed89ac, + orig_index=0, + ) + + inp3 = messages.TxInputType( + address_n=parse_path("49h/1h/0h/0/3"), + amount=998060, + script_type=messages.InputScriptType.SPENDP2SHWITNESS, + prev_hash=TXHASH_efaa41, + prev_index=0, + orig_hash=TXHASH_334cd7, + orig_index=1, + ) + + inp4 = messages.TxInputType( + address_n=parse_path("49h/1h/0h/0/9"), + amount=839318869, + script_type=messages.InputScriptType.SPENDP2SHWITNESS, + prev_hash=TXHASH_927784, + prev_index=0, + orig_hash=TXHASH_ed89ac, + orig_index=1, + ) + + out1 = messages.TxOutputType( + address="moE1dVYvebvtaMuNdXQKvu4UxUftLmS1Gt", + amount=100000000, + orig_hash=TXHASH_ed89ac, + orig_index=1, + ) + + out2 = messages.TxOutputType( + # Actually m/49'/1'/0'/0/5. + address="2MvUUSiQZDSqyeSdofKX9KrSCio1nANPDTe", + amount=1000000, + orig_hash=TXHASH_334cd7, + orig_index=0, + ) + + # Change-output. Original fees were 3780 + 90720 = 94500. + out3 = messages.TxOutputType( + address_n=parse_path("49h/1h/0h/1/0"), + amount=100000 + 4973340 + 998060 + 839318869 - 100000000 - 1000000 - 94500, + script_type=messages.OutputScriptType.PAYTOP2SHWITNESS, + ) + + with client: + client.set_expected_responses( + [ + request_input(0), + request_meta(TXHASH_334cd7), + request_orig_input(0, TXHASH_334cd7), + request_input(1), + request_meta(TXHASH_ed89ac), + request_orig_input(0, TXHASH_ed89ac), + request_input(2), + request_orig_input(1, TXHASH_334cd7), + request_input(3), + request_orig_input(1, TXHASH_ed89ac), + request_output(0), + request_orig_output(0, TXHASH_ed89ac), + request_orig_output(1, TXHASH_ed89ac), + request_output(1), + request_orig_output(0, TXHASH_334cd7), + request_output(2), + request_orig_output(1, TXHASH_334cd7), + messages.ButtonRequest(code=B.SignTx), + messages.ButtonRequest(code=B.SignTx), + messages.ButtonRequest(code=B.SignTx), + request_input(0), + request_meta(TXHASH_5e7667), + request_input(0, TXHASH_5e7667), + request_output(0, TXHASH_5e7667), + request_output(1, TXHASH_5e7667), + request_input(1), + request_meta(TXHASH_6673b7), + request_input(0, TXHASH_6673b7), + request_input(1, TXHASH_6673b7), + request_input(2, TXHASH_6673b7), + request_input(3, TXHASH_6673b7), + request_input(4, TXHASH_6673b7), + request_output(0, TXHASH_6673b7), + request_input(2), + request_meta(TXHASH_efaa41), + request_input(0, TXHASH_efaa41), + request_output(0, TXHASH_efaa41), + request_input(3), + request_meta(TXHASH_927784), + request_input(0, TXHASH_927784), + request_input(1, TXHASH_927784), + request_input(2, TXHASH_927784), + request_output(0, TXHASH_927784), + request_input(0), + request_input(1), + request_input(2), + request_input(3), + request_output(0), + request_output(1), + request_output(2), + request_input(0), + request_input(1), + request_input(2), + request_input(3), + request_finished(), + ] + ) + _, serialized_tx = btc.sign_tx( + client, + "Testnet", + [inp1, inp2, inp3, inp4], + [out1, out2, out3], + prev_txes=TX_CACHE_TESTNET, + ) + + assert ( + serialized_tx.hex() + == "01000000000104d64ae26dceee1e309bed0821f39275b5f6e65d0072f8e23747ae76006967765e0100000017160014039ba06270e6c6c1ad4e6940515aa5cdbad33f9effffffff57b4cb6156c63a8d6b834e236a21edf9d0f11fdd2fd0f9b28248328e24b773660000000017160014adbbadefe594e9e4bfccb9c699ae5d4f18716772ffffffff35ac1adc9e0cf408013090c52527d3cf9468d51e1a6c8408f5ed673eff41aaef0000000017160014209297fb46272a0b7e05139440dbd39daea3e25affffffff0b03833dd525dae7f7ed1455f386fc7899737a1cc3f538c7c4efbc7be08477920000000017160014681ea49259abb892460bf3373e8a0b43d877fa18ffffffff0300e1f505000000001976a914548cb80e45b1d36312fe0cb075e5e337e3c54cef88ac40420f000000000017a9142369da13fee80c9d7fd8043bf1275c04deb360e687590d5d2c0000000017a91458b53ea7f832e8f096e896b8713a8c6df0e892ca870247304402205b4b304cb5a23cd3b73aa586c983cbadefc3fcbcb8fb33684037b17a818726c002202a3f529183eebf2f06d041b18d379579c22d908be31060752179f01d125ff020012103bb0e339d7495b1f355c49d385b79343e52e68d99de2fe1f7f476c465c9ccd167024730440220666ebf2c146d4a369971ec1d5b69fce2f3b8e2c0ba689e6077ebed513f91dd760220200e203355156e23abf5b536ac174df4109985feddf86ab065c12f0da8339d6a012102a52d8cf5a89c284bacff90a3d7c30a0166e0074ca3fc385f3efce638c50493b30247304402207d6331026626fc133813ea672147c95feac29a3d7deefb49ef1d0194e061d53802207e4c3a3b8f3c2e11845684d74a5f1d8395da0a8e65e18c7f72155aac82be648e012103c2c2e65556ca4b7371549324b99390725493c8a6792e093a0bdcbb3e2d7df4ab02473044022047f95a95ea8cac78f057e15e37ac5cebd6abcf50d87e5509d30c730cb0f7e89f02201d861acb267c0bc100cac99cad42b067a39614602eef5f9f791c1875f24dd0de0121028cbc37e1816a23086fa738c8415def477e813e20f484dbbd6f5a33a37c32225100000000" + ) + + +@pytest.mark.skip_t1 +@pytest.mark.skip_ui +def test_attack_steal_change(client): + # 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. + + # Original input. + inp1 = messages.TxInputType( + address_n=parse_path("84h/1h/0h/0/0"), + amount=100000, + script_type=messages.InputScriptType.SPENDWITNESS, + prev_hash=TXHASH_e4b5b2, + prev_index=0, + orig_hash=TXHASH_65b768, + orig_index=0, + sequence=1516634, + ) + + # New input for the attacker to steal from. + inp2 = messages.TxInputType( + address_n=parse_path("84h/1h/0h/1/1"), + amount=19899859, + script_type=messages.InputScriptType.SPENDWITNESS, + prev_hash=TXHASH_70f987, + prev_index=1, + ) + + # Original output. + out1 = messages.TxOutputType( + address="tb1qldlynaqp0hy4zc2aag3pkenzvxy65saesxw3wd", + amount=10000, + script_type=messages.OutputScriptType.PAYTOWITNESS, + orig_hash=TXHASH_65b768, + orig_index=0, + ) + + # Original change was 89859. We bump the fee from 141 to 200 and + # attacker gives back what he can't steal. + out2 = messages.TxOutputType( + address_n=parse_path("84h/1h/0h/1/2"), + amount=100000 - 10000 - 200 + (19899859 - 89859), + script_type=messages.OutputScriptType.PAYTOWITNESS, + orig_hash=TXHASH_65b768, + orig_index=1, + ) + + # Attacker's new output. + out3 = messages.TxOutputType( + address="tb1q694ccp5qcc0udmfwgp692u2s2hjpq5h407urtu", + amount=89859, + ) + + # Attacker hides the fact that second output of 65b768 is a change-output. + prev_tx_attack = TX_CACHE_TESTNET[TXHASH_65b768] + prev_tx_attack.outputs[1].address_n = None + prev_tx_attack.outputs[1].address = "tb1qr5p6f5sk09sms57ket074vywfymuthlgud7xyx" + prev_tx_attack.outputs[1].script_type = messages.OutputScriptType.PAYTOADDRESS + prev_txes = {TXHASH_65b768: prev_tx_attack} + + with pytest.raises( + TrezorFailure, match="Original output is missing change-output parameters" + ): + btc.sign_tx( + client, + "Testnet", + [inp1, inp2], + [out1, out2, out3], + lock_time=1516634, + prev_txes=prev_txes, + ) + + +@pytest.mark.skip_t1 +@pytest.mark.skip_ui +def test_attack_false_internal(client): + # 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 + # possible for the attacker to steal the difference. + + inp1 = messages.TxInputType( + address_n=parse_path("49h/1h/0h/0/4"), + amount=100000, + script_type=messages.InputScriptType.SPENDP2SHWITNESS, + prev_hash=TXHASH_5e7667, + prev_index=1, + orig_hash=TXHASH_334cd7, + orig_index=0, + ) + + inp2 = messages.TxInputType( + # Actually 49h/1h/0h/0/3, but we will make it look like it's external, + # while in the original it will show up as intenal. + amount=998060, + script_type=messages.InputScriptType.EXTERNAL, + prev_hash=TXHASH_efaa41, + prev_index=0, + orig_hash=TXHASH_334cd7, + orig_index=1, + script_sig=bytes.fromhex("160014209297fb46272a0b7e05139440dbd39daea3e25a"), + witness=bytes.fromhex( + "024730440220709798e66e44ee76d8b0858407b2098f2f0046703761e2617b2b870a346cb56c022010242f602cd41485934834ecf12c1647d003df8c9d4c0d8637514e1dc8a657a2012103c2c2e65556ca4b7371549324b99390725493c8a6792e093a0bdcbb3e2d7df4ab" + ), + ) + + out1 = messages.TxOutputType( + # Actually m/49'/1'/0'/0/5. + address="2MvUUSiQZDSqyeSdofKX9KrSCio1nANPDTe", + amount=1000000 + 94280, + orig_hash=TXHASH_334cd7, + orig_index=0, + ) + + with pytest.raises( + TrezorFailure, match="Original input does not match current input" + ): + btc.sign_tx( + client, + "Testnet", + [inp1, inp2], + [out1], + prev_txes=TX_CACHE_TESTNET, + ) + + +@pytest.mark.skip_t1 +@pytest.mark.skip_ui +def test_attack_fake_int_input_amount(client): + # 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 + # transaction without the user noticing. + + inp1 = messages.TxInputType( + address_n=parse_path("44h/0h/0h/0/4"), + amount=174998, + prev_hash=TXHASH_beafc7, + prev_index=0, + orig_hash=TXHASH_50f6f1, + orig_index=0, + ) + + out1 = messages.TxOutputType( + address_n=parse_path("44h/0h/0h/1/2"), + amount=174998 + - 50000 + - 111300, # Original fee was 11300, attacker increases it by 100000. + script_type=messages.OutputScriptType.PAYTOADDRESS, + orig_hash=TXHASH_50f6f1, + orig_index=0, + ) + + out2 = messages.TxOutputType( + address="1GA9u9TfCG7SWmKCveBumdA1TZpfom6ZdJ", + amount=50000, + script_type=messages.OutputScriptType.PAYTOADDRESS, + orig_hash=TXHASH_50f6f1, + orig_index=1, + ) + + prev_tx_attack = TX_CACHE_MAINNET[TXHASH_50f6f1] + prev_tx_attack.inputs[ + 0 + ].amount += 100000 # Increase the original input amount by 100000. + prev_txes = { + TXHASH_50f6f1: prev_tx_attack, + TXHASH_beafc7: TX_CACHE_MAINNET[TXHASH_beafc7], + } + + with pytest.raises( + TrezorFailure, match="Original input does not match current input" + ): + btc.sign_tx( + client, + "Bitcoin", + [inp1], + [out1, out2], + prev_txes=prev_txes, + ) + + +@pytest.mark.skip_t1 +@pytest.mark.skip_ui +def test_attack_fake_ext_input_amount(client): + # 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 + # the transaction without the user noticing. + + inp1 = messages.TxInputType( + address_n=parse_path("49h/1h/0h/0/8"), + amount=4973340, + script_type=messages.InputScriptType.SPENDP2SHWITNESS, + prev_hash=TXHASH_6673b7, + prev_index=0, + orig_hash=TXHASH_ed89ac, + orig_index=0, + ) + + inp2 = messages.TxInputType( + # Actually 49h/1h/0h/0/9, but we will make it look like it's external, + # so that we can try out this scenario, i.e. not a part of the attack. + amount=839318869, + script_type=messages.InputScriptType.EXTERNAL, + prev_hash=TXHASH_927784, + prev_index=0, + orig_hash=TXHASH_ed89ac, + orig_index=1, + script_sig=bytes.fromhex("160014681ea49259abb892460bf3373e8a0b43d877fa18"), + witness=bytes.fromhex( + "02483045022100d9c2d4364e104bf0d27886b4d7cd05f9a256bda8acbe84b7b2753f5c054b1a8602206a512575a89da5b5123e2769a5f73675b27b9f43d1a7b54bddeae039f6b83efa0121028cbc37e1816a23086fa738c8415def477e813e20f484dbbd6f5a33a37c322251" + ), + ) + + # Attacker adds 30000, but it could even go to a new output. + out1 = messages.TxOutputType( + address="moE1dVYvebvtaMuNdXQKvu4UxUftLmS1Gt", + amount=100000000 + 30000, + orig_hash=TXHASH_ed89ac, + orig_index=1, + ) + + # Change-output. Original fee was 90720, attacker steals 30000. + out2 = messages.TxOutputType( + address_n=parse_path("49h/1h/0h/1/6"), + amount=4973340 + 839318869 - (100000000 + 30000) - 60720, + script_type=messages.OutputScriptType.PAYTOP2SHWITNESS, + ) + + # Decrease the original amount of inp2 by 30000. + # Also make the original inp2 look external (not a part of the attack). + prev_tx_attack = TX_CACHE_TESTNET[TXHASH_ed89ac] + prev_tx_attack.inputs[1].amount -= 30000 + prev_tx_attack.inputs[1].address_n = None + prev_tx_attack.inputs[1].script_type = messages.InputScriptType.EXTERNAL + prev_txes = { + TXHASH_ed89ac: prev_tx_attack, + TXHASH_6673b7: TX_CACHE_TESTNET[TXHASH_6673b7], + TXHASH_927784: TX_CACHE_TESTNET[TXHASH_927784], + } + + with pytest.raises( + TrezorFailure, match="Original input does not match current input" + ): + btc.sign_tx( + client, + "Testnet", + [inp1, inp2], + [out1, out2], + prev_txes=prev_txes, + ) diff --git a/tests/txcache/bitcoin/50f6f1209ca92d7359564be803cb2c932cde7d370f7cee50fd1fad6790f6206d.json b/tests/txcache/bitcoin/50f6f1209ca92d7359564be803cb2c932cde7d370f7cee50fd1fad6790f6206d.json index d566a86be..af9b0737e 100644 --- a/tests/txcache/bitcoin/50f6f1209ca92d7359564be803cb2c932cde7d370f7cee50fd1fad6790f6206d.json +++ b/tests/txcache/bitcoin/50f6f1209ca92d7359564be803cb2c932cde7d370f7cee50fd1fad6790f6206d.json @@ -13,10 +13,23 @@ { "prev_hash": "beafc7cbd873d06dbee88a7002768ad5864228639db514c81cfb29f108bb1e7a", "prev_index": 0, + "address_n": [2147483692, 2147483648, 2147483648, 0, 4], + "amount": 174998, "script_sig": "47304402204ec6818b86591bbbc2abd5a10d203df49996c4bd5621eb2fa85345bb05458fa602202c9553fb00fc18199af82f4ec8f1055e9aeda6a5bbead1e02303a95a8bc91d31012103f54094da6a0b2e0799286268bb59ca7c83538e81c78e64f6333f40f9e0e222c0", "sequence": 4294967295 } ], "lock_time": 0, + "outputs": [ + { + "address_n": [2147483692, 2147483648, 2147483648, 1, 2], + "amount": 113698 + }, + { + "address": "1GA9u9TfCG7SWmKCveBumdA1TZpfom6ZdJ", + "amount": 50000 + } + ], + "version": 1 } diff --git a/tests/txcache/bitcoin/beafc7cbd873d06dbee88a7002768ad5864228639db514c81cfb29f108bb1e7a.json b/tests/txcache/bitcoin/beafc7cbd873d06dbee88a7002768ad5864228639db514c81cfb29f108bb1e7a.json new file mode 100644 index 000000000..3f30cae81 --- /dev/null +++ b/tests/txcache/bitcoin/beafc7cbd873d06dbee88a7002768ad5864228639db514c81cfb29f108bb1e7a.json @@ -0,0 +1,18 @@ +{ + "bin_outputs": [ + { + "amount": 174998, + "script_pubkey": "76a91430d22ce220a5294b836b68c6c199d79e680ff8f988ac" + } + ], + "inputs": [ + { + "prev_hash": "a5876ef46b8036cd10f93598a2d3dfaaa789ff1f8fe7a532f89c2ca330187936", + "prev_index": 0, + "script_sig": "473044022011d009010619a182ac7bbe21b1918ae5955c47ade7cbaae3c4608b62669b4e2e022036a252020c47a3340299773297114ffac52b83bfad01fbf9cc980051e5d905f3012102e62488c7a4aee638457f8b6afdb6dc41993971b5175dd4b941e14441c2df22b2", + "sequence": 4294967295 + } + ], + "lock_time": 0, + "version": 1 +} diff --git a/tests/txcache/bitcoin/c63e24ed820c5851b60c54613fbc4bcb37df6cd49b4c96143e99580a472f79fb.json b/tests/txcache/bitcoin/c63e24ed820c5851b60c54613fbc4bcb37df6cd49b4c96143e99580a472f79fb.json index 0beacc445..aef1284de 100644 --- a/tests/txcache/bitcoin/c63e24ed820c5851b60c54613fbc4bcb37df6cd49b4c96143e99580a472f79fb.json +++ b/tests/txcache/bitcoin/c63e24ed820c5851b60c54613fbc4bcb37df6cd49b4c96143e99580a472f79fb.json @@ -11,6 +11,7 @@ ], "inputs": [ { + "address_n": [2147483692, 2147483648, 2147483648, 0, 0], "prev_hash": "c6be22d34946593bcad1d2b013e12f74159e69574ffea21581dad115572e031c", "prev_index": 1, "script_sig": "493046022100f773c403b2f85a5c1d6c9c4ad69c43de66930fff4b1bc818eb257af98305546a022100bbc421b41bc60d89593186c99b4b9ca6ac8dce1fe62342d38a8e14e0cbf279dc01210338d78612e990f2eea0c426b5e48a8db70b9d7ed66282b3b26511e0b1c75515a6", diff --git a/tests/txcache/testnet/334cd7ad982b3b15d07dd1c84e939e95efb0803071648048a7f289492e7b4c8a.json b/tests/txcache/testnet/334cd7ad982b3b15d07dd1c84e939e95efb0803071648048a7f289492e7b4c8a.json new file mode 100644 index 000000000..328dd9687 --- /dev/null +++ b/tests/txcache/testnet/334cd7ad982b3b15d07dd1c84e939e95efb0803071648048a7f289492e7b4c8a.json @@ -0,0 +1,36 @@ +{ + "inputs": [ + { + "prev_hash": "5e7667690076ae4737e2f872005de6f6b57592f32108ed9b301eeece6de24ad6", + "prev_index": 1, + "address_n": [2147483697, 2147483649, 2147483648, 0, 4], + "amount": 100000, + "script_type": 4, + "script_sig": "160014039ba06270e6c6c1ad4e6940515aa5cdbad33f9e", + "witness": "0247304402205cfe0d0ca30b23c462f535f0c3670761592ba42517bd65fca959887e131b61c9022017d692c3a24ee7aba1205c9a1ee0df5a3d1fcc6a2906c9a77cf1145edb903f8e012103bb0e339d7495b1f355c49d385b79343e52e68d99de2fe1f7f476c465c9ccd167", + "sequence": 4294967295 + }, + { + "prev_hash": "efaa41ff3e67edf508846c1a1ed56894cfd32725c590300108f40c9edc1aac35", + "prev_index": 0, + "address_n": [2147483697, 2147483649, 2147483648, 0, 3], + "amount": 998060, + "script_type": 4, + "script_sig": "160014209297fb46272a0b7e05139440dbd39daea3e25a", + "sequence": 4294967295 + } + ], + "lock_time": 0, + "outputs": [ + { + "address": "2MvUUSiQZDSqyeSdofKX9KrSCio1nANPDTe", + "amount": 1000000 + }, + { + "address_n": [2147483697, 2147483649, 2147483648, 1, 3], + "amount": 94280, + "script_type": 5 + } + ], + "version": 1 +} diff --git a/tests/txcache/testnet/5e7667690076ae4737e2f872005de6f6b57592f32108ed9b301eeece6de24ad6.json b/tests/txcache/testnet/5e7667690076ae4737e2f872005de6f6b57592f32108ed9b301eeece6de24ad6.json new file mode 100644 index 000000000..1a0b1a22b --- /dev/null +++ b/tests/txcache/testnet/5e7667690076ae4737e2f872005de6f6b57592f32108ed9b301eeece6de24ad6.json @@ -0,0 +1,22 @@ +{ + "bin_outputs": [ + { + "amount": 3891540, + "script_pubkey": "a914e5ad0f8d1428e714f8fcbbde77dccd3cb853ec9c87" + }, + { + "amount": 100000, + "script_pubkey": "a914a67e38250e43b8fc209ce4a3ea1082fb53dc63f787" + } + ], + "inputs": [ + { + "prev_hash": "08c7ffb9d594d9c9f4e8827ca6058b94ff865260aa467c325562a213386be99e", + "prev_index": 0, + "script_sig": "1600145d18464a9d83c5d3294944166f6c94fa2f1aed55", + "sequence": 4294967295 + } + ], + "lock_time": 0, + "version": 1 +} diff --git a/tests/txcache/testnet/65b768dacccfb209eebd95a1fb80a04f1dd6a3abc6d7b41d5e9d9f91605b37d9.json b/tests/txcache/testnet/65b768dacccfb209eebd95a1fb80a04f1dd6a3abc6d7b41d5e9d9f91605b37d9.json index e5b5c2e99..523042c3f 100644 --- a/tests/txcache/testnet/65b768dacccfb209eebd95a1fb80a04f1dd6a3abc6d7b41d5e9d9f91605b37d9.json +++ b/tests/txcache/testnet/65b768dacccfb209eebd95a1fb80a04f1dd6a3abc6d7b41d5e9d9f91605b37d9.json @@ -13,10 +13,26 @@ { "prev_hash": "e4b5b24159856ea18ab5819832da3b4a6330f9c3c0a46d96674e632df504b56b", "prev_index": 0, + "address_n": [2147483732, 2147483649, 2147483648, 0, 0], + "amount": 100000, + "script_type": 3, "script_sig": "", + "witness": "02473044022069571005c302e4a7c3e549405a020e6af6cb4587cf67f6fb5c05abdd71fe15af0220398b6811bba6e202a0d091956b558e7590848ba80cf0fa56f0407caf1569a66c012103adc58245cf28406af0ef5cc24b8afba7f1be6c72f279b642d85c48798685f862", "sequence": 4294967294 } ], "lock_time": 1516634, + "outputs": [ + { + "address": "tb1qldlynaqp0hy4zc2aag3pkenzvxy65saesxw3wd", + "amount": 10000, + "script_type": 4 + }, + { + "address_n": [2147483732, 2147483649, 2147483648, 1, 2], + "amount": 89859, + "script_type": 4 + } + ], "version": 2 } diff --git a/tests/txcache/testnet/6673b7248e324882b2f9d02fdd1ff1d0f9ed216a234e836b8d3ac65661cbb457.json b/tests/txcache/testnet/6673b7248e324882b2f9d02fdd1ff1d0f9ed216a234e836b8d3ac65661cbb457.json new file mode 100644 index 000000000..2f47f19fa --- /dev/null +++ b/tests/txcache/testnet/6673b7248e324882b2f9d02fdd1ff1d0f9ed216a234e836b8d3ac65661cbb457.json @@ -0,0 +1,47 @@ +{ + "bin_outputs": [ + { + "amount": 4973340, + "script_pubkey": "a914d1164e63e196b54842402da4704e6a3e523fe67387" + } + ], + "inputs": [ + { + "prev_hash": "a36f2b752bcba7b4136394195831e3ed2c42d3a7ae94f8db9e2b4ac438423765", + "prev_index": 1, + "script_sig": "16001450e725578c7f0819e4c839cb55c15682e846daa8", + "script_type": "SPENDADDRESS", + "sequence": 4294967295 + }, + { + "prev_hash": "a36f2b752bcba7b4136394195831e3ed2c42d3a7ae94f8db9e2b4ac438423765", + "prev_index": 0, + "script_sig": "160014310888a340bf653c71ee48ec0dd78304a31428f5", + "script_type": "SPENDADDRESS", + "sequence": 4294967295 + }, + { + "prev_hash": "55c0e481f06b14365a6c7cd4f5c0bd1ee658a0fb413d0e7ff37716c1deaf8acc", + "prev_index": 0, + "script_sig": "160014468fc62d24e2fb5a65b61859434e983eb7372469", + "script_type": "SPENDADDRESS", + "sequence": 4294967295 + }, + { + "prev_hash": "334cd7ad982b3b15d07dd1c84e939e95efb0803071648048a7f289492e7b4c8a", + "prev_index": 0, + "script_sig": "160014ed6e3c049de3a9f3b6d876394f7846f67e8c6577", + "script_type": "SPENDADDRESS", + "sequence": 4294967295 + }, + { + "prev_hash": "5e7667690076ae4737e2f872005de6f6b57592f32108ed9b301eeece6de24ad6", + "prev_index": 0, + "script_sig": "16001468b91d44b164c5595a9fe9c772cf1539a1b35819", + "script_type": "SPENDADDRESS", + "sequence": 4294967295 + } + ], + "lock_time": 0, + "version": 1 +} diff --git a/tests/txcache/testnet/927784e07bbcefc4c738f5c31c7a739978fc86f35514edf7e7da25d53d83030b.json b/tests/txcache/testnet/927784e07bbcefc4c738f5c31c7a739978fc86f35514edf7e7da25d53d83030b.json new file mode 100644 index 000000000..e3b60da6f --- /dev/null +++ b/tests/txcache/testnet/927784e07bbcefc4c738f5c31c7a739978fc86f35514edf7e7da25d53d83030b.json @@ -0,0 +1,33 @@ +{ + "bin_outputs": [ + { + "amount": 839318869, + "script_pubkey": "a914eb227e547838e56792d92ef597244d8b33767c8f87" + } + ], + "inputs": [ + { + "prev_hash": "0e480a97c7a545c85e101a2f13c9af0e115d43734e1448f0cac3e55fe8e7399d", + "prev_index": 2, + "script_sig": "47304402203b94f1a26e63df828cfc715234cc06dba862bd7547978d68e28312d336e2a15d02207a400b6e2f8a87643dd8f382ed3556acefa1b750b08ef85bc380a637239167640121030e669acac1f280d1ddf441cd2ba5e97417bf2689e4bbec86df4f831bf9f7ffd0", + "script_type": "SPENDADDRESS", + "sequence": 4294967295 + }, + { + "prev_hash": "d830b877c3d9237a0a68be88825a296da01ac282a2efd2f671d8f17f15117b74", + "prev_index": 0, + "script_sig": "473044022071455b3f211f669e17e0f72b879dcb93c40354992b738310ed03a225d82709540220117836c08eb458f95ca049e5c99f57ad36e38a82bc508fa76036f85549ab45c90121030e669acac1f280d1ddf441cd2ba5e97417bf2689e4bbec86df4f831bf9f7ffd0", + "script_type": "SPENDADDRESS", + "sequence": 4294967295 + }, + { + "prev_hash": "e000ab18d6531bee500221f8bca532bb69ec0f48a547b49aaab08e56b54276e8", + "prev_index": 0, + "script_sig": "483045022100bae78d7974ea6983a2a9de0839032366477488b25fe19c49792ac934036bdb9f022067e98f77ae75dc7e83068d2a1f611cb460ab4e2cb411927f5aec086f5579599201210294e3e5e77e22eea0e4c0d30d89beb4db7f69b4bf1ae709e411d6a06618b8f852", + "script_type": "SPENDADDRESS", + "sequence": 4294967295 + } + ], + "lock_time": 0, + "version": 1 +} diff --git a/tests/txcache/testnet/e4b5b24159856ea18ab5819832da3b4a6330f9c3c0a46d96674e632df504b56b.json b/tests/txcache/testnet/e4b5b24159856ea18ab5819832da3b4a6330f9c3c0a46d96674e632df504b56b.json new file mode 100644 index 000000000..a34190ba5 --- /dev/null +++ b/tests/txcache/testnet/e4b5b24159856ea18ab5819832da3b4a6330f9c3c0a46d96674e632df504b56b.json @@ -0,0 +1,22 @@ +{ + "bin_outputs": [ + { + "amount": 100000, + "script_pubkey": "0014b31dc2a236505a6cb9201fa0411ca38a254a7bf1" + }, + { + "amount": 899585, + "script_pubkey": "76a9148071b2af42e167ec58e422e784358ec71f80274b88ac" + } + ], + "inputs": [ + { + "prev_hash": "ad04d5c0d284745ce7e88e7827c0a3a511348d29abdbc5a62aa7942f5e3dcb35", + "prev_index": 0, + "script_sig": "4730440220536f9c20c42cb50472d76fb20aa55d9f9996da0881e6f12be8ad6f657844f993022076bd3e01ab8d17eba22718d2be1cdd9649e61754651dda5e062d27540e789a4001210234ec664aae13ced11d4676d33c8603e01a2ba7c6acdbbe4097323f0c4744ad56", + "sequence": 4294967294 + } + ], + "lock_time": 1516634, + "version": 2 +} diff --git a/tests/txcache/testnet/ed89acb52cfa438e3653007478e7c7feae89fdde12867943eec91293139730d1.json b/tests/txcache/testnet/ed89acb52cfa438e3653007478e7c7feae89fdde12867943eec91293139730d1.json new file mode 100644 index 000000000..dba775af5 --- /dev/null +++ b/tests/txcache/testnet/ed89acb52cfa438e3653007478e7c7feae89fdde12867943eec91293139730d1.json @@ -0,0 +1,46 @@ +{ + "bin_outputs": [ + { + "amount": 744201489, + "script_pubkey": "a9145a699f6166aa26037e367d5edd44e07d676f921d87" + }, + { + "amount": 100000000, + "script_pubkey": "76a914548cb80e45b1d36312fe0cb075e5e337e3c54cef88ac" + } + ], + "inputs": [ + { + "prev_hash": "6673b7248e324882b2f9d02fdd1ff1d0f9ed216a234e836b8d3ac65661cbb457", + "prev_index": 0, + "address_n": [2147483697, 2147483649, 2147483648, 0, 8], + "amount": 4973340, + "script_type": 4, + "script_sig": "160014adbbadefe594e9e4bfccb9c699ae5d4f18716772", + "witness": "02483045022100e01560fee1583c8009c24ff431ecb1e21ac17852e0e8fc6cadee05472b135312022048943a660b52988362320211e91ca08bd35f28b8b7e55cf2b2c15692c662d8fa012102a52d8cf5a89c284bacff90a3d7c30a0166e0074ca3fc385f3efce638c50493b3", + "sequence": 4294967295 + }, + { + "prev_hash": "927784e07bbcefc4c738f5c31c7a739978fc86f35514edf7e7da25d53d83030b", + "prev_index": 0, + "address_n": [2147483697, 2147483649, 2147483648, 0, 9], + "amount": 839318869, + "script_type": 4, + "script_sig": "160014681ea49259abb892460bf3373e8a0b43d877fa18", + "sequence": 4294967295 + } + ], + "lock_time": 0, + "outputs": [ + { + "address_n": [2147483697, 2147483649, 2147483648, 1, 6], + "amount": 744201489, + "script_type": 5 + }, + { + "address": "moE1dVYvebvtaMuNdXQKvu4UxUftLmS1Gt", + "amount": 100000000 + } + ], + "version": 1 +} diff --git a/tests/txcache/testnet/efaa41ff3e67edf508846c1a1ed56894cfd32725c590300108f40c9edc1aac35.json b/tests/txcache/testnet/efaa41ff3e67edf508846c1a1ed56894cfd32725c590300108f40c9edc1aac35.json new file mode 100644 index 000000000..13b0cf70d --- /dev/null +++ b/tests/txcache/testnet/efaa41ff3e67edf508846c1a1ed56894cfd32725c590300108f40c9edc1aac35.json @@ -0,0 +1,18 @@ +{ + "bin_outputs": [ + { + "amount": 998060, + "script_pubkey": "a914b9170a062fafcf4379729d104dd04859b1ce955887" + } + ], + "inputs": [ + { + "prev_hash": "08c7ffb9d594d9c9f4e8827ca6058b94ff865260aa467c325562a213386be99e", + "prev_index": 1, + "script_sig": "160014a33c6e24c99e108b97bc411e7e9ef31e9d5d6164", + "sequence": 4294967295 + } + ], + "lock_time": 0, + "version": 1 +} diff --git a/tests/ui_tests/fixtures.json b/tests/ui_tests/fixtures.json index bfdbfe4d0..e490e0e79 100644 --- a/tests/ui_tests/fixtures.json +++ b/tests/ui_tests/fixtures.json @@ -326,6 +326,14 @@ "test_msg_signtx_komodo.py-test_one_one_fee_sapling": "14bad8852ee51f6fec12677cced9ffafa0cbae91b4ba94e988a800544072ed21", "test_msg_signtx_komodo.py-test_one_one_rewards_claim": "751e83d63bf01c6c57047b5e004629d613df75342371cd43a7b4b80a07f4b88d", "test_msg_signtx_peercoin.py::test_timestamp_included": "825b9bdf5238c5c6415a254a6bae4b2bd9df8fc5cb31f66f0c20145cb4e60bbb", +"test_msg_signtx_replacement.py::test_p2pkh_fee_bump": "881f6491e9f4417cd747dda2dc0eaafdf1a4769a5e53aa303bb06547d6a9133b", +"test_msg_signtx_replacement.py::test_p2wpkh_in_p2sh_remove_change": "f66437cc88d016ddb0b3fd4e6d2c6536d9a1745dfc92ce9cd334c3cbaaefb4a9", +"test_msg_signtx_replacement.py::test_p2wpkh_payjoin[19909659-90000-02483045022100aa1b91fb25cc9a0ace4": "d3705fbba66a2ed819fa65a99516f7a49f2e0a709337237fa09718dca0bcd7a1", +"test_msg_signtx_replacement.py::test_p2wpkh_payjoin[19909718-90000-024730440220753f53049ca43d55f6563": "2f6a57db7c072e2c76b6aa8e3c07f6d67310f14eba42c013c7584f89a64414da", +"test_msg_signtx_replacement.py::test_p2wpkh_payjoin[19909800-89859-0248304502210097a42b35d3d16fa1696": "e26e835e699369f8cf697c36334189f376727eee366c0beb5ed4a5670e21dd66", +"test_msg_signtx_replacement.py::test_p2wpkh_payjoin[19909859-89800-02483045022100af3a874c966ee595321": "fa89cef11f68c2c856b441728f70a86d4c9419cf9e327cfd3330eafb8790bc2d", +"test_msg_signtx_replacement.py::test_p2wpkh_payjoin[19909859-89859-02483045022100eb74abb36f317d707c3": "09609aa74f3d0a0438e6c5e1085e0c0a93edfd8c95068e92dc6b6cd1e932814c", +"test_msg_signtx_replacement.py::test_tx_meld": "5250c11a75781fa1c845f7b405b7808c5b7dce3e8405fe69096db5c723457f48", "test_msg_signtx_segwit.py-test_attack_change_input_address": "5ae71202c062ef7942626a80a4ceeb8d8c4ea5065a97f0de6a97505e9cb82c2c", "test_msg_signtx_segwit.py-test_attack_mixed_inputs": "f127a4766b23d9b6dfe0c41f9cf1ed13c0a883ea4e92e55961bcaf44bd152c02", "test_msg_signtx_segwit.py-test_send_multisig_1": "958a0741070e057dcb889b2000e5487d391bc513e4a5d86193a355261c5f361b",