|
|
|
|
@ -1419,6 +1419,91 @@ class TestWalletSending(TestCaseForTestnet):
|
|
|
|
|
self.assertEqual('7f827fc5256c274fd1094eb7e020c8ded0baf820356f61aa4f14a9093b0ea0ee', tx_copy.txid()) |
|
|
|
|
self.assertEqual('7f827fc5256c274fd1094eb7e020c8ded0baf820356f61aa4f14a9093b0ea0ee', tx_copy.wtxid()) |
|
|
|
|
|
|
|
|
|
@needs_test_with_all_ecc_implementations |
|
|
|
|
@mock.patch.object(storage.WalletStorage, '_write') |
|
|
|
|
def test_coinjoin_between_two_p2wpkh_electrum_seeds(self, mock_write): |
|
|
|
|
wallet1 = WalletIntegrityHelper.create_standard_wallet( |
|
|
|
|
keystore.from_seed('humor argue expand gain goat shiver remove morning security casual leopard degree', ''), |
|
|
|
|
gap_limit=2, |
|
|
|
|
config=self.config |
|
|
|
|
) |
|
|
|
|
wallet2 = WalletIntegrityHelper.create_standard_wallet( |
|
|
|
|
keystore.from_seed('couple fade lift useless text thank badge act august roof drastic violin', ''), |
|
|
|
|
gap_limit=2, |
|
|
|
|
config=self.config |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
# bootstrap wallet1 |
|
|
|
|
funding_tx = Transaction('0200000000010162ecbac2f0c8662f53505d9410fdc56c84c5642ddbd3358d9a27d564e26731130200000000fdffffff02c0d8a70000000000160014aba1c9faecc3f8882e641583e8734a3f9d01b15ab89ed5000000000016001470afbd97b2dc351bd167f714e294b2fd3b60aedf02483045022100c93449989510e279eb14a0193d5c262ae93034b81376a1f6be259c6080d3ba5d0220536ab394f7c20f301d7ec2ef11be6e7b6d492053dce56458931c1b54218ec0fd012103b8f5a11df8e68cf335848e83a41fdad3c7413dc42148248a3799b58c93919ca010851800') |
|
|
|
|
funding_txid = funding_tx.txid() |
|
|
|
|
self.assertEqual('d8f8186379085cffc9a3fd747e7a7527435db974d1e2941f52f063be8e4fbdd5', funding_txid) |
|
|
|
|
wallet1.receive_tx_callback(funding_txid, funding_tx, TX_HEIGHT_UNCONFIRMED) |
|
|
|
|
|
|
|
|
|
# bootstrap wallet2 |
|
|
|
|
funding_tx = Transaction('02000000000101d5bd4f8ebe63f0521f94e2d174b95d4327757a7e74fda3c9ff5c08796318f8d80100000000fdffffff025066350000000000160014e3aa82aa2e754507d5585c0b6db06cc0cb4927b7a037a000000000001600140719d12228c61cab793ecd659c09cfe565a845c302483045022100f42e27519bd2379c22951c16b038fa6d49164fe6802854f2fdc7ee87fe31a8bc02204ea71e9324781b44bf7fea2f318caf3bedc5b497cbd1b4313fa71f833500bcb7012103a7853e1ee02a1629c8e870ec694a1420aeb98e6f5d071815257028f62d6f784169851800') |
|
|
|
|
funding_txid = funding_tx.txid() |
|
|
|
|
self.assertEqual('934f26a72c840293f06c37dc10a358df056dfe245cdf072ae836977c0abc46e5', funding_txid) |
|
|
|
|
wallet2.receive_tx_callback(funding_txid, funding_tx, TX_HEIGHT_UNCONFIRMED) |
|
|
|
|
|
|
|
|
|
# wallet1 creates tx1, with output back to himself |
|
|
|
|
outputs = [PartialTxOutput.from_address_and_value("tb1qhye4wfp26kn0l7ynpn5a4hvt539xc3zf0n76t3", 10_000_000)] |
|
|
|
|
tx1 = wallet1.mktx(outputs=outputs, fee=5000, tx_version=2, rbf=True, sign=False) |
|
|
|
|
tx1.locktime = 1607022 |
|
|
|
|
partial_tx1 = tx1.serialize_as_bytes().hex() |
|
|
|
|
self.assertEqual("70736274ff0100710200000001d5bd4f8ebe63f0521f94e2d174b95d4327757a7e74fda3c9ff5c08796318f8d80000000000fdffffff02b82e0f0000000000160014250dbabd5761d7e0773d6147699938dd08ec2eb88096980000000000160014b93357242ad5a6fff8930ce9dadd8ba44a6c44496e8518000001011fc0d8a70000000000160014aba1c9faecc3f8882e641583e8734a3f9d01b15a22060205e8db1b1906219782fadb18e763c0874a3118a17ce931e01707cbde194e04150ca6046cbd00000000000000000022020240ef5d2efee3b04b313a254df1b13a0b155451581e73943b21f3346bf6e1ba350ca6046cbd0100000000000000002202024a410b1212e88573561887b2bc38c90c074e4be425b9f3d971a9207825d9d3c80ca6046cbd000000000100000000", |
|
|
|
|
partial_tx1) |
|
|
|
|
tx1.prepare_for_export_for_coinjoin() |
|
|
|
|
partial_tx1 = tx1.serialize_as_bytes().hex() |
|
|
|
|
self.assertEqual("70736274ff0100710200000001d5bd4f8ebe63f0521f94e2d174b95d4327757a7e74fda3c9ff5c08796318f8d80000000000fdffffff02b82e0f0000000000160014250dbabd5761d7e0773d6147699938dd08ec2eb88096980000000000160014b93357242ad5a6fff8930ce9dadd8ba44a6c44496e8518000001011fc0d8a70000000000160014aba1c9faecc3f8882e641583e8734a3f9d01b15a000000", |
|
|
|
|
partial_tx1) |
|
|
|
|
|
|
|
|
|
# wallet2 creates tx2, with output back to himself |
|
|
|
|
outputs = [PartialTxOutput.from_address_and_value("tb1qufnj5k2rrsnpjq7fg6d2pq3q9um6skdyyehw5m", 10_000_000)] |
|
|
|
|
tx2 = wallet2.mktx(outputs=outputs, fee=5000, tx_version=2, rbf=True, sign=False) |
|
|
|
|
tx2.locktime = 1607023 |
|
|
|
|
partial_tx2 = tx2.serialize_as_bytes().hex() |
|
|
|
|
self.assertEqual("70736274ff0100710200000001e546bc0a7c9736e82a07df5c24fe6d05df58a310dc376cf09302842ca7264f930100000000fdffffff02988d07000000000016001453675a59be834aa6d139c3ebea56646a9b160c4c8096980000000000160014e2672a59431c261903c9469aa082202f37a859a46f8518000001011fa037a000000000001600140719d12228c61cab793ecd659c09cfe565a845c3220602275b4fba18bb34e5198a9cfb3e940306658839079b3bda50d504a9cf2bae36f40c467882350000000001000000002202036e4d0a5fb845b2f1c3c868c2ce7212b155b73e91c05be1b7a77c48830831ba4f0c4678823501000000000000000022020200062fdea2b0a056b17fa6b91dd87f5b5d838fe1ee84d636a5022f9a340eebcc0c46788235000000000000000000", |
|
|
|
|
partial_tx2) |
|
|
|
|
|
|
|
|
|
# wallet2 gets raw partial tx1, merges it into his own tx2 |
|
|
|
|
tx2.join_with_other_psbt(tx_from_any(partial_tx1)) |
|
|
|
|
partial_tx2 = tx2.serialize_as_bytes().hex() |
|
|
|
|
self.assertEqual("70736274ff0100d80200000002e546bc0a7c9736e82a07df5c24fe6d05df58a310dc376cf09302842ca7264f930100000000fdffffffd5bd4f8ebe63f0521f94e2d174b95d4327757a7e74fda3c9ff5c08796318f8d80000000000fdffffff04988d07000000000016001453675a59be834aa6d139c3ebea56646a9b160c4cb82e0f0000000000160014250dbabd5761d7e0773d6147699938dd08ec2eb88096980000000000160014b93357242ad5a6fff8930ce9dadd8ba44a6c44498096980000000000160014e2672a59431c261903c9469aa082202f37a859a46f8518000001011fa037a000000000001600140719d12228c61cab793ecd659c09cfe565a845c3220602275b4fba18bb34e5198a9cfb3e940306658839079b3bda50d504a9cf2bae36f40c4678823500000000010000000001011fc0d8a70000000000160014aba1c9faecc3f8882e641583e8734a3f9d01b15a002202036e4d0a5fb845b2f1c3c868c2ce7212b155b73e91c05be1b7a77c48830831ba4f0c46788235010000000000000000000022020200062fdea2b0a056b17fa6b91dd87f5b5d838fe1ee84d636a5022f9a340eebcc0c46788235000000000000000000", |
|
|
|
|
partial_tx2) |
|
|
|
|
tx2.prepare_for_export_for_coinjoin() |
|
|
|
|
partial_tx2 = tx2.serialize_as_bytes().hex() |
|
|
|
|
self.assertEqual("70736274ff0100d80200000002e546bc0a7c9736e82a07df5c24fe6d05df58a310dc376cf09302842ca7264f930100000000fdffffffd5bd4f8ebe63f0521f94e2d174b95d4327757a7e74fda3c9ff5c08796318f8d80000000000fdffffff04988d07000000000016001453675a59be834aa6d139c3ebea56646a9b160c4cb82e0f0000000000160014250dbabd5761d7e0773d6147699938dd08ec2eb88096980000000000160014b93357242ad5a6fff8930ce9dadd8ba44a6c44498096980000000000160014e2672a59431c261903c9469aa082202f37a859a46f8518000001011fa037a000000000001600140719d12228c61cab793ecd659c09cfe565a845c30001011fc0d8a70000000000160014aba1c9faecc3f8882e641583e8734a3f9d01b15a0000000000", |
|
|
|
|
partial_tx2) |
|
|
|
|
|
|
|
|
|
# wallet2 signs |
|
|
|
|
wallet2.sign_transaction(tx2, password=None) |
|
|
|
|
partial_tx2 = tx2.serialize_as_bytes().hex() |
|
|
|
|
self.assertEqual("70736274ff0100d80200000002e546bc0a7c9736e82a07df5c24fe6d05df58a310dc376cf09302842ca7264f930100000000fdffffffd5bd4f8ebe63f0521f94e2d174b95d4327757a7e74fda3c9ff5c08796318f8d80000000000fdffffff04988d07000000000016001453675a59be834aa6d139c3ebea56646a9b160c4cb82e0f0000000000160014250dbabd5761d7e0773d6147699938dd08ec2eb88096980000000000160014b93357242ad5a6fff8930ce9dadd8ba44a6c44498096980000000000160014e2672a59431c261903c9469aa082202f37a859a46f8518000001011fa037a000000000001600140719d12228c61cab793ecd659c09cfe565a845c301070001086c02483045022100b87a557003acf04e2b328df6e4fa2bc387ba1a072d9325bd84f162d495720b24022042513f12244318cf94ad7944e8c135c6f47dcfe13ad08a77dca63a76facbe0b8012102275b4fba18bb34e5198a9cfb3e940306658839079b3bda50d504a9cf2bae36f40001011fc0d8a70000000000160014aba1c9faecc3f8882e641583e8734a3f9d01b15a002202036e4d0a5fb845b2f1c3c868c2ce7212b155b73e91c05be1b7a77c48830831ba4f0c46788235010000000000000000000022020200062fdea2b0a056b17fa6b91dd87f5b5d838fe1ee84d636a5022f9a340eebcc0c46788235000000000000000000", |
|
|
|
|
partial_tx2) |
|
|
|
|
tx2.prepare_for_export_for_coinjoin() |
|
|
|
|
partial_tx2 = tx2.serialize_as_bytes().hex() |
|
|
|
|
self.assertEqual("70736274ff0100d80200000002e546bc0a7c9736e82a07df5c24fe6d05df58a310dc376cf09302842ca7264f930100000000fdffffffd5bd4f8ebe63f0521f94e2d174b95d4327757a7e74fda3c9ff5c08796318f8d80000000000fdffffff04988d07000000000016001453675a59be834aa6d139c3ebea56646a9b160c4cb82e0f0000000000160014250dbabd5761d7e0773d6147699938dd08ec2eb88096980000000000160014b93357242ad5a6fff8930ce9dadd8ba44a6c44498096980000000000160014e2672a59431c261903c9469aa082202f37a859a46f8518000001011fa037a000000000001600140719d12228c61cab793ecd659c09cfe565a845c301070001086c02483045022100b87a557003acf04e2b328df6e4fa2bc387ba1a072d9325bd84f162d495720b24022042513f12244318cf94ad7944e8c135c6f47dcfe13ad08a77dca63a76facbe0b8012102275b4fba18bb34e5198a9cfb3e940306658839079b3bda50d504a9cf2bae36f40001011fc0d8a70000000000160014aba1c9faecc3f8882e641583e8734a3f9d01b15a0000000000", |
|
|
|
|
partial_tx2) |
|
|
|
|
|
|
|
|
|
# wallet1 gets raw partial tx2, and signs |
|
|
|
|
tx2 = tx_from_any(partial_tx2) |
|
|
|
|
wallet1.sign_transaction(tx2, password=None) |
|
|
|
|
tx = tx_from_any(tx2.serialize_as_bytes().hex()) # simulates moving partial txn between cosigners |
|
|
|
|
|
|
|
|
|
self.assertTrue(tx.is_complete()) |
|
|
|
|
self.assertTrue(tx.is_segwit()) |
|
|
|
|
self.assertEqual("02000000000102e546bc0a7c9736e82a07df5c24fe6d05df58a310dc376cf09302842ca7264f930100000000fdffffffd5bd4f8ebe63f0521f94e2d174b95d4327757a7e74fda3c9ff5c08796318f8d80000000000fdffffff04988d07000000000016001453675a59be834aa6d139c3ebea56646a9b160c4cb82e0f0000000000160014250dbabd5761d7e0773d6147699938dd08ec2eb88096980000000000160014b93357242ad5a6fff8930ce9dadd8ba44a6c44498096980000000000160014e2672a59431c261903c9469aa082202f37a859a402483045022100b87a557003acf04e2b328df6e4fa2bc387ba1a072d9325bd84f162d495720b24022042513f12244318cf94ad7944e8c135c6f47dcfe13ad08a77dca63a76facbe0b8012102275b4fba18bb34e5198a9cfb3e940306658839079b3bda50d504a9cf2bae36f402473044022003010ece3471f7a23f31b2a0fd157f88f7d436c0c73ec408043c7f5dd2b7ccbb02204bd21f5829555c3f94fbd0b5295d1071f739c6b8f2682f8a688e34d0ad26c90101210205e8db1b1906219782fadb18e763c0874a3118a17ce931e01707cbde194e04156f851800", |
|
|
|
|
str(tx)) |
|
|
|
|
self.assertEqual('4a33546eeaed0e25f9e6a58968be92a804a7e70a5332360dabc79f93cd059752', tx.txid()) |
|
|
|
|
self.assertEqual('868c9f396cc8f998b80e47f199cc85eab971638ecf892b5024cb218bc2025137', tx.wtxid()) |
|
|
|
|
|
|
|
|
|
wallet1.receive_tx_callback(tx.txid(), tx, TX_HEIGHT_UNCONFIRMED) |
|
|
|
|
wallet2.receive_tx_callback(tx.txid(), tx, TX_HEIGHT_UNCONFIRMED) |
|
|
|
|
|
|
|
|
|
# wallet level checks |
|
|
|
|
self.assertEqual((0, 10995000, 0), wallet1.get_balance()) |
|
|
|
|
self.assertEqual((0, 10495000, 0), wallet2.get_balance()) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class TestWalletOfflineSigning(TestCaseForTestnet): |
|
|
|
|
|
|
|
|
|
|