commit 7c7aa5828b6dec4e79cdab0f19f674d6609a7878
parent f12798e91c158275f910946c327d21f67e111e8c
Author: SomberNight <somber.night@protonmail.com>
Date: Mon, 14 May 2018 18:33:14 +0200
tests: added p2wpkh-p2sh wallet to TestWalletSending
Diffstat:
1 file changed, 109 insertions(+), 39 deletions(-)
diff --git a/lib/tests/test_wallet_vertical.py b/lib/tests/test_wallet_vertical.py
@@ -2,6 +2,7 @@ import unittest
from unittest import mock
import shutil
import tempfile
+from typing import Sequence
import lib
from lib import storage, bitcoin, keystore, constants
@@ -42,16 +43,12 @@ class WalletIntegrityHelper:
return w
@classmethod
- def create_multisig_wallet(cls, ks1, ks2, ks3=None, gap_limit=None):
- """Creates a 2-of-2 or 2-of-3 multisig wallet."""
+ def create_multisig_wallet(cls, keystores: Sequence, multisig_type: str, gap_limit=None):
+ """Creates a multisig wallet."""
store = storage.WalletStorage('if_this_exists_mocking_failed_648151893')
- store.put('x%d/' % 1, ks1.dump())
- store.put('x%d/' % 2, ks2.dump())
- if ks3 is None:
- multisig_type = "%dof%d" % (2, 2)
- else:
- multisig_type = "%dof%d" % (2, 3)
- store.put('x%d/' % 3, ks3.dump())
+ for i, ks in enumerate(keystores):
+ cosigner_index = i + 1
+ store.put('x%d/' % cosigner_index, ks.dump())
store.put('wallet_type', multisig_type)
store.put('gap_limit', gap_limit or cls.gap_limit)
w = lib.wallet.Multisig_Wallet(store)
@@ -145,7 +142,7 @@ class TestWalletKeystoreAddressIntegrityForMainnet(unittest.TestCase):
WalletIntegrityHelper.check_xpub_keystore_sanity(self, ks3)
self.assertTrue(isinstance(ks3, keystore.BIP32_KeyStore))
- w = WalletIntegrityHelper.create_multisig_wallet(ks1, ks2, ks3)
+ w = WalletIntegrityHelper.create_multisig_wallet([ks1, ks2, ks3], '2of3')
self.assertEqual(w.txin_type, 'p2sh')
self.assertEqual(w.get_receiving_addresses()[0], '35L8XmCDoEBKeaWRjvmZvoZvhp8BXMMMPV')
@@ -222,7 +219,7 @@ class TestWalletKeystoreAddressIntegrityForMainnet(unittest.TestCase):
WalletIntegrityHelper.check_xpub_keystore_sanity(self, ks2)
self.assertTrue(isinstance(ks2, keystore.BIP32_KeyStore))
- w = WalletIntegrityHelper.create_multisig_wallet(ks1, ks2)
+ w = WalletIntegrityHelper.create_multisig_wallet([ks1, ks2], '2of2')
self.assertEqual(w.txin_type, 'p2sh')
self.assertEqual(w.get_receiving_addresses()[0], '32ji3QkAgXNz6oFoRfakyD3ys1XXiERQYN')
@@ -244,7 +241,7 @@ class TestWalletKeystoreAddressIntegrityForMainnet(unittest.TestCase):
WalletIntegrityHelper.check_xpub_keystore_sanity(self, ks2)
self.assertTrue(isinstance(ks2, keystore.BIP32_KeyStore))
- w = WalletIntegrityHelper.create_multisig_wallet(ks1, ks2)
+ w = WalletIntegrityHelper.create_multisig_wallet([ks1, ks2], '2of2')
self.assertEqual(w.txin_type, 'p2wsh')
self.assertEqual(w.get_receiving_addresses()[0], 'bc1qvzezdcv6vs5h45ugkavp896e0nde5c5lg5h0fwe2xyfhnpkxq6gq7pnwlc')
@@ -266,7 +263,7 @@ class TestWalletKeystoreAddressIntegrityForMainnet(unittest.TestCase):
WalletIntegrityHelper.check_xpub_keystore_sanity(self, ks2)
self.assertTrue(isinstance(ks2, keystore.BIP32_KeyStore))
- w = WalletIntegrityHelper.create_multisig_wallet(ks1, ks2)
+ w = WalletIntegrityHelper.create_multisig_wallet([ks1, ks2], '2of2')
self.assertEqual(w.txin_type, 'p2sh')
self.assertEqual(w.get_receiving_addresses()[0], '3JPTQ2nitVxXBJ1yhMeDwH6q417UifE3bN')
@@ -287,7 +284,7 @@ class TestWalletKeystoreAddressIntegrityForMainnet(unittest.TestCase):
WalletIntegrityHelper.check_xpub_keystore_sanity(self, ks2)
self.assertTrue(isinstance(ks2, keystore.BIP32_KeyStore))
- w = WalletIntegrityHelper.create_multisig_wallet(ks1, ks2)
+ w = WalletIntegrityHelper.create_multisig_wallet([ks1, ks2], '2of2')
self.assertEqual(w.txin_type, 'p2wsh-p2sh')
self.assertEqual(w.get_receiving_addresses()[0], '35LeC45QgCVeRor1tJD6LiDgPbybBXisns')
@@ -311,7 +308,7 @@ class TestWalletKeystoreAddressIntegrityForTestnet(TestCaseForTestnet):
WalletIntegrityHelper.check_xpub_keystore_sanity(self, ks2)
self.assertTrue(isinstance(ks2, keystore.BIP32_KeyStore))
- w = WalletIntegrityHelper.create_multisig_wallet(ks1, ks2)
+ w = WalletIntegrityHelper.create_multisig_wallet([ks1, ks2], '2of2')
self.assertEqual(w.txin_type, 'p2wsh-p2sh')
self.assertEqual(w.get_receiving_addresses()[0], '2MzsfTfTGomPRne6TkctMmoDj6LwmVkDrMt')
@@ -388,16 +385,20 @@ class TestWalletSending(TestCaseForTestnet):
@mock.patch.object(storage.WalletStorage, '_write')
def test_sending_between_p2sh_2of3_and_uncompressed_p2pkh(self, mock_write):
wallet1a = WalletIntegrityHelper.create_multisig_wallet(
- keystore.from_seed('blast uniform dragon fiscal ensure vast young utility dinosaur abandon rookie sure', '', True),
- keystore.from_xpub('tpubD6NzVbkrYhZ4YTPEgwk4zzr8wyo7pXGmbbVUnfYNtx6SgAMF5q3LN3Kch58P9hxGNsTmP7Dn49nnrmpE6upoRb1Xojg12FGLuLHkVpVtS44'),
- keystore.from_xpub('tpubD6NzVbkrYhZ4XJzYkhsCbDCcZRmDAKSD7bXi9mdCni7acVt45fxbTVZyU6jRGh29ULKTjoapkfFsSJvQHitcVKbQgzgkkYsAmaovcro7Mhf'),
- gap_limit=2
+ [
+ keystore.from_seed('blast uniform dragon fiscal ensure vast young utility dinosaur abandon rookie sure', '', True),
+ keystore.from_xpub('tpubD6NzVbkrYhZ4YTPEgwk4zzr8wyo7pXGmbbVUnfYNtx6SgAMF5q3LN3Kch58P9hxGNsTmP7Dn49nnrmpE6upoRb1Xojg12FGLuLHkVpVtS44'),
+ keystore.from_xpub('tpubD6NzVbkrYhZ4XJzYkhsCbDCcZRmDAKSD7bXi9mdCni7acVt45fxbTVZyU6jRGh29ULKTjoapkfFsSJvQHitcVKbQgzgkkYsAmaovcro7Mhf')
+ ],
+ '2of3', gap_limit=2
)
wallet1b = WalletIntegrityHelper.create_multisig_wallet(
- keystore.from_seed('cycle rocket west magnet parrot shuffle foot correct salt library feed song', '', True),
- keystore.from_xpub('tpubD6NzVbkrYhZ4YTPEgwk4zzr8wyo7pXGmbbVUnfYNtx6SgAMF5q3LN3Kch58P9hxGNsTmP7Dn49nnrmpE6upoRb1Xojg12FGLuLHkVpVtS44'),
- keystore.from_xpub('tpubD6NzVbkrYhZ4YARFMEZPckrqJkw59GZD1PXtQnw14ukvWDofR7Z1HMeSCxfYEZVvg4VdZ8zGok5VxHwdrLqew5cMdQntWc5mT7mh1CSgrnX'),
- gap_limit=2
+ [
+ keystore.from_seed('cycle rocket west magnet parrot shuffle foot correct salt library feed song', '', True),
+ keystore.from_xpub('tpubD6NzVbkrYhZ4YTPEgwk4zzr8wyo7pXGmbbVUnfYNtx6SgAMF5q3LN3Kch58P9hxGNsTmP7Dn49nnrmpE6upoRb1Xojg12FGLuLHkVpVtS44'),
+ keystore.from_xpub('tpubD6NzVbkrYhZ4YARFMEZPckrqJkw59GZD1PXtQnw14ukvWDofR7Z1HMeSCxfYEZVvg4VdZ8zGok5VxHwdrLqew5cMdQntWc5mT7mh1CSgrnX')
+ ],
+ '2of3', gap_limit=2
)
# ^ third seed: ghost into match ivory badge robot record tackle radar elbow traffic loud
wallet2 = self.create_standard_wallet_from_seed('powerful random nobody notice nothing important anyway look away hidden message over')
@@ -453,29 +454,37 @@ class TestWalletSending(TestCaseForTestnet):
@mock.patch.object(storage.WalletStorage, '_write')
def test_sending_between_p2wsh_2of3_and_p2wsh_p2sh_2of2(self, mock_write):
wallet1a = WalletIntegrityHelper.create_multisig_wallet(
- keystore.from_seed('bitter grass shiver impose acquire brush forget axis eager alone wine silver', '', True),
- keystore.from_xpub('Vpub5fcdcgEwTJmbmqAktuK8Kyq92fMf7sWkcP6oqAii2tG47dNbfkGEGUbfS9NuZaRywLkHE6EmUksrqo32ZL3ouLN1HTar6oRiHpDzKMAF1tf'),
- keystore.from_xpub('Vpub5fjkKyYnvSS4wBuakWTkNvZDaBM2vQ1MeXWq368VJHNr2eT8efqhpmZ6UUkb7s2dwCXv2Vuggjdhk4vZVyiAQTwUftvff73XcUGq2NQmWra'),
- gap_limit=2
+ [
+ keystore.from_seed('bitter grass shiver impose acquire brush forget axis eager alone wine silver', '', True),
+ keystore.from_xpub('Vpub5fcdcgEwTJmbmqAktuK8Kyq92fMf7sWkcP6oqAii2tG47dNbfkGEGUbfS9NuZaRywLkHE6EmUksrqo32ZL3ouLN1HTar6oRiHpDzKMAF1tf'),
+ keystore.from_xpub('Vpub5fjkKyYnvSS4wBuakWTkNvZDaBM2vQ1MeXWq368VJHNr2eT8efqhpmZ6UUkb7s2dwCXv2Vuggjdhk4vZVyiAQTwUftvff73XcUGq2NQmWra')
+ ],
+ '2of3', gap_limit=2
)
wallet1b = WalletIntegrityHelper.create_multisig_wallet(
- keystore.from_seed('snow nest raise royal more walk demise rotate smooth spirit canyon gun', '', True),
- keystore.from_xpub('Vpub5fjkKyYnvSS4wBuakWTkNvZDaBM2vQ1MeXWq368VJHNr2eT8efqhpmZ6UUkb7s2dwCXv2Vuggjdhk4vZVyiAQTwUftvff73XcUGq2NQmWra'),
- keystore.from_xpub('Vpub5gSKXzxK7FeKQedu2q1z9oJWxqvX72AArW3HSWpEhc8othDH8xMDu28gr7gf17sp492BuJod8Tn7anjvJrKpETwqnQqX7CS8fcYyUtedEMk'),
- gap_limit=2
+ [
+ keystore.from_seed('snow nest raise royal more walk demise rotate smooth spirit canyon gun', '', True),
+ keystore.from_xpub('Vpub5fjkKyYnvSS4wBuakWTkNvZDaBM2vQ1MeXWq368VJHNr2eT8efqhpmZ6UUkb7s2dwCXv2Vuggjdhk4vZVyiAQTwUftvff73XcUGq2NQmWra'),
+ keystore.from_xpub('Vpub5gSKXzxK7FeKQedu2q1z9oJWxqvX72AArW3HSWpEhc8othDH8xMDu28gr7gf17sp492BuJod8Tn7anjvJrKpETwqnQqX7CS8fcYyUtedEMk')
+ ],
+ '2of3', gap_limit=2
)
# ^ third seed: hedgehog sunset update estate number jungle amount piano friend donate upper wool
wallet2a = WalletIntegrityHelper.create_multisig_wallet(
- # bip39: finish seminar arrange erosion sunny coil insane together pretty lunch lunch rose, der: m/1234'/1'/0', p2wsh-p2sh multisig
- keystore.from_xprv('Uprv9CvELvByqm8k2dpecJVjgLMX1z5DufEjY4fBC5YvdGF5WjGCa7GVJJ2fYni1tyuF7Hw83E6W2ZBjAhaFLZv2ri3rEsubkCd5avg4EHKoDBN'),
- keystore.from_xpub('Upub5Qb8ik4Cnu8g97KLXKgVXHqY6tH8emQvqtBncjSKsyfTZuorPtTZgX7ovKKZHuuVGBVd1MTTBkWez1XXt2weN1sWBz6SfgRPQYEkNgz81QF'),
- gap_limit=2
+ [
+ # bip39: finish seminar arrange erosion sunny coil insane together pretty lunch lunch rose, der: m/1234'/1'/0', p2wsh-p2sh multisig
+ keystore.from_xprv('Uprv9CvELvByqm8k2dpecJVjgLMX1z5DufEjY4fBC5YvdGF5WjGCa7GVJJ2fYni1tyuF7Hw83E6W2ZBjAhaFLZv2ri3rEsubkCd5avg4EHKoDBN'),
+ keystore.from_xpub('Upub5Qb8ik4Cnu8g97KLXKgVXHqY6tH8emQvqtBncjSKsyfTZuorPtTZgX7ovKKZHuuVGBVd1MTTBkWez1XXt2weN1sWBz6SfgRPQYEkNgz81QF')
+ ],
+ '2of2', gap_limit=2
)
wallet2b = WalletIntegrityHelper.create_multisig_wallet(
- # bip39: square page wood spy oil story rebel give milk screen slide shuffle, der: m/1234'/1'/0', p2wsh-p2sh multisig
- keystore.from_xprv('Uprv9BbnKEXJxXaNvdEsRJ9VA9toYrSeFJh5UfGBpM2iKe8Uh7UhrM9K8ioL53s8gvCoGfirHHaqpABDAE7VUNw8LNU1DMJKVoWyeNKu9XcDC19'),
- keystore.from_xpub('Upub5RuakRisg8h3F7u7iL2k3UJFa1uiK7xauHamzTxYBbn4PXbM7eajr6M9Q2VCr6cVGhfhqWQqxnABvtSATuVM1xzxk4nA189jJwzaMn1QX7V'),
- gap_limit=2
+ [
+ # bip39: square page wood spy oil story rebel give milk screen slide shuffle, der: m/1234'/1'/0', p2wsh-p2sh multisig
+ keystore.from_xprv('Uprv9BbnKEXJxXaNvdEsRJ9VA9toYrSeFJh5UfGBpM2iKe8Uh7UhrM9K8ioL53s8gvCoGfirHHaqpABDAE7VUNw8LNU1DMJKVoWyeNKu9XcDC19'),
+ keystore.from_xpub('Upub5RuakRisg8h3F7u7iL2k3UJFa1uiK7xauHamzTxYBbn4PXbM7eajr6M9Q2VCr6cVGhfhqWQqxnABvtSATuVM1xzxk4nA189jJwzaMn1QX7V')
+ ],
+ '2of2', gap_limit=2
)
# bootstrap wallet1
@@ -528,3 +537,64 @@ class TestWalletSending(TestCaseForTestnet):
# wallet level checks
self.assertEqual((0, funding_output_value - 165000 - 5000 + 100000, 0), wallet1a.get_balance())
self.assertEqual((0, 165000 - 5000 - 100000, 0), wallet2a.get_balance())
+
+ @mock.patch.object(storage.WalletStorage, '_write')
+ def test_sending_between_p2sh_1of2_and_p2wpkh_p2sh(self, mock_write):
+ wallet1a = WalletIntegrityHelper.create_multisig_wallet(
+ [
+ keystore.from_seed('phone guilt ancient scan defy gasp off rotate approve ill word exchange', '', True),
+ keystore.from_xpub('tpubD6NzVbkrYhZ4YPZ3ntVjqSCxiUUv2jikrUBU73Q3iJ7Y8iR41oYf991L5fanv7ciHjbjokdK2bjYqg1BzEUDxucU9qM5WRdBiY738wmgLP4')
+ ],
+ '1of2', gap_limit=2
+ )
+ # ^ second seed: kingdom now gift initial age right velvet exotic harbor enforce kingdom kick
+ wallet2 = WalletIntegrityHelper.create_standard_wallet(
+ # bip39: uniform tank success logic lesson awesome stove elegant regular desert drip device, der: m/49'/1'/0'
+ keystore.from_xprv('uprv91HGbrNZTK4x8u22nbdYGzEuWPxjaHMREUi7CNhY64KsG5ZGnVM99uCa16EMSfrnaPTFxjbRdBZ2WiBkokoM8anzAy3Vpc52o88WPkitnxi'),
+ gap_limit=2
+ )
+
+ # bootstrap wallet1
+ funding_tx = Transaction('010000000001027e20990282eb29588375ad04936e1e991af3bc5b9c6f1ab62eca8c25becaef6a01000000171600140e6a17fadc8bafba830f3467a889f6b211d69a00fdffffff51847fd6bcbdfd1d1ea2c2d95c2d8de1e34c5f2bd9493e88a96a4e229f564e800100000017160014ecdf9fa06856f9643b1a73144bc76c24c67774a6fdffffff021e8501000000000017a91451991bfa68fbcb1e28aa0b1e060b7d24003352e38700093d000000000017a914b0b9f31bace76cdfae2c14abc03e223403d7dc4b870247304402205e19721b92c6afd70cd932acb50815a36ee32ab46a934147d62f02c13aeacf4702207289c4a4131ef86e27058ff70b6cb6bf0e8e81c6cbab6dddd7b0a9bc732960e4012103fe504411c21f7663caa0bbf28931f03fae7e0def7bc54851e0194dfb1e2c85ef02483045022100e969b65096fba4f8b24eb5bc622d2282076241621f3efe922cc2067f7a8a6be702203ec4047dd2a71b9c83eb6a0875a6d66b4d65864637576c06ed029d3d1a8654b0012102bbc8100dca67ba0297aba51296a4184d714204a5fc2eda34708360f37019a3dccfcc1300')
+ funding_txid = funding_tx.txid()
+ funding_output_value = 4000000
+ self.assertEqual('1137c12de4ce0f5b08de8846ba14c0814351a7f0f31457c8ea51a5d4b3c891a3', funding_txid)
+ wallet1a.receive_tx_callback(funding_txid, funding_tx, TX_HEIGHT_UNCONFIRMED)
+
+ # wallet1 -> wallet2
+ outputs = [(bitcoin.TYPE_ADDRESS, wallet2.get_receiving_address(), 1000000)]
+ tx = wallet1a.mktx(outputs=outputs, password=None, config=self.config, fee=5000)
+
+ self.assertTrue(tx.is_complete())
+ self.assertFalse(tx.is_segwit())
+ self.assertEqual(1, len(tx.inputs()))
+ tx_copy = Transaction(tx.serialize())
+ self.assertEqual(wallet1a.is_mine(tx.inputs()[0]['address']), wallet1a.is_mine(tx_copy.inputs()[0]['address']))
+ self.assertTrue(wallet1a.is_mine(tx.inputs()[0]['address']))
+ self.assertEqual(wallet1a.txin_type, tx_copy.inputs()[0]['type'])
+ self.assertEqual(tx.wtxid(), tx_copy.wtxid())
+ self.assertEqual('1b7e94860b9681d4e371928d40fdbd4641e991aa74f1a211f239c887047e4a2a', tx_copy.txid())
+
+ wallet1a.receive_tx_callback(tx.txid(), tx, TX_HEIGHT_UNCONFIRMED)
+ wallet2.receive_tx_callback(tx.txid(), tx, TX_HEIGHT_UNCONFIRMED)
+
+ # wallet2 -> wallet1
+ outputs = [(bitcoin.TYPE_ADDRESS, wallet1a.get_receiving_address(), 300000)]
+ tx = wallet2.mktx(outputs=outputs, password=None, config=self.config, fee=5000)
+
+ self.assertTrue(tx.is_complete())
+ self.assertTrue(tx.is_segwit())
+ self.assertEqual(1, len(tx.inputs()))
+ tx_copy = Transaction(tx.serialize())
+ self.assertEqual(wallet2.is_mine(tx.inputs()[0]['address']), wallet2.is_mine(tx_copy.inputs()[0]['address']))
+ self.assertTrue(wallet2.is_mine(tx.inputs()[0]['address']))
+ self.assertEqual(wallet2.txin_type, tx_copy.inputs()[0]['type'])
+ self.assertEqual(tx.wtxid(), tx_copy.wtxid())
+ self.assertEqual('f65edb0843ff44436dc5964fb6b298e157502b9b4a83dac6b82dd2d2a3247d0a', tx_copy.txid())
+
+ wallet1a.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, funding_output_value - 1000000 - 5000 + 300000, 0), wallet1a.get_balance())
+ self.assertEqual((0, 1000000 - 5000 - 300000, 0), wallet2.get_balance())