Browse Source

tests: sends between wallets

3.2.x
SomberNight 7 years ago
parent
commit
68d8919416
No known key found for this signature in database GPG Key ID: B33B5F232C6271E9
  1. 225
      lib/tests/test_wallet_vertical.py

225
lib/tests/test_wallet_vertical.py

@ -1,11 +1,11 @@
import unittest import unittest
from unittest import mock from unittest import mock
import lib.bitcoin as bitcoin import lib
import lib.keystore as keystore from lib import storage, bitcoin, keystore, constants
import lib.storage as storage from lib.transaction import Transaction
import lib.wallet as wallet from lib.simple_config import SimpleConfig
from lib import constants from lib.wallet import TX_HEIGHT_UNCONFIRMED, TX_HEIGHT_UNCONF_PARENT
from plugins.trustedcoin import trustedcoin from plugins.trustedcoin import trustedcoin
@ -31,16 +31,16 @@ class WalletIntegrityHelper:
test_obj.assertFalse(ks.has_seed()) test_obj.assertFalse(ks.has_seed())
@classmethod @classmethod
def create_standard_wallet(cls, ks): def create_standard_wallet(cls, ks, gap_limit=None):
store = storage.WalletStorage('if_this_exists_mocking_failed_648151893') store = storage.WalletStorage('if_this_exists_mocking_failed_648151893')
store.put('keystore', ks.dump()) store.put('keystore', ks.dump())
store.put('gap_limit', cls.gap_limit) store.put('gap_limit', gap_limit or cls.gap_limit)
w = wallet.Standard_Wallet(store) w = lib.wallet.Standard_Wallet(store)
w.synchronize() w.synchronize()
return w return w
@classmethod @classmethod
def create_multisig_wallet(cls, ks1, ks2, ks3=None): def create_multisig_wallet(cls, ks1, ks2, ks3=None, gap_limit=None):
"""Creates a 2-of-2 or 2-of-3 multisig wallet.""" """Creates a 2-of-2 or 2-of-3 multisig wallet."""
store = storage.WalletStorage('if_this_exists_mocking_failed_648151893') store = storage.WalletStorage('if_this_exists_mocking_failed_648151893')
store.put('x%d/' % 1, ks1.dump()) store.put('x%d/' % 1, ks1.dump())
@ -51,8 +51,8 @@ class WalletIntegrityHelper:
multisig_type = "%dof%d" % (2, 3) multisig_type = "%dof%d" % (2, 3)
store.put('x%d/' % 3, ks3.dump()) store.put('x%d/' % 3, ks3.dump())
store.put('wallet_type', multisig_type) store.put('wallet_type', multisig_type)
store.put('gap_limit', cls.gap_limit) store.put('gap_limit', gap_limit or cls.gap_limit)
w = wallet.Multisig_Wallet(store) w = lib.wallet.Multisig_Wallet(store)
w.synchronize() w.synchronize()
return w return w
@ -314,3 +314,206 @@ class TestWalletKeystoreAddressIntegrityForTestnet(TestCaseForTestnet):
self.assertEqual(w.get_receiving_addresses()[0], '2MzsfTfTGomPRne6TkctMmoDj6LwmVkDrMt') self.assertEqual(w.get_receiving_addresses()[0], '2MzsfTfTGomPRne6TkctMmoDj6LwmVkDrMt')
self.assertEqual(w.get_change_addresses()[0], '2NFp9w8tbYYP9Ze2xQpeYBJQjx3gbXymHX7') self.assertEqual(w.get_change_addresses()[0], '2NFp9w8tbYYP9Ze2xQpeYBJQjx3gbXymHX7')
class TestWalletSending(TestCaseForTestnet):
config = SimpleConfig()
def create_standard_wallet_from_seed(self, seed_words):
ks = keystore.from_seed(seed_words, '', False)
return WalletIntegrityHelper.create_standard_wallet(ks, gap_limit=2)
@mock.patch.object(storage.WalletStorage, '_write')
def test_sending_between_p2wpkh_and_compressed_p2pkh(self, mock_write):
wallet1 = self.create_standard_wallet_from_seed('bitter grass shiver impose acquire brush forget axis eager alone wine silver')
wallet2 = self.create_standard_wallet_from_seed('cycle rocket west magnet parrot shuffle foot correct salt library feed song')
# bootstrap wallet1
funding_tx = Transaction('01000000014576dacce264c24d81887642b726f5d64aa7825b21b350c7b75a57f337da6845010000006b483045022100a3f8b6155c71a98ad9986edd6161b20d24fad99b6463c23b463856c0ee54826d02200f606017fd987696ebbe5200daedde922eee264325a184d5bbda965ba5160821012102e5c473c051dae31043c335266d0ef89c1daab2f34d885cc7706b267f3269c609ffffffff0240420f00000000001600148a28bddb7f61864bdcf58b2ad13d5aeb3abc3c42a2ddb90e000000001976a914c384950342cb6f8df55175b48586838b03130fad88ac00000000')
funding_txid = funding_tx.txid()
funding_output_value = 1000000
self.assertEqual('add2535aedcbb5ba79cc2260868bb9e57f328738ca192937f2c92e0e94c19203', funding_txid)
wallet1.receive_tx_callback(funding_txid, funding_tx, TX_HEIGHT_UNCONFIRMED)
# wallet1 -> wallet2
outputs = [(bitcoin.TYPE_ADDRESS, wallet2.get_receiving_address(), 250000)]
tx = wallet1.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(wallet1.is_mine(tx.inputs()[0]['address']), wallet1.is_mine(tx_copy.inputs()[0]['address']))
self.assertTrue(wallet1.is_mine(tx.inputs()[0]['address']))
self.assertEqual(wallet1.txin_type, tx_copy.inputs()[0]['type'])
self.assertEqual(tx.wtxid(), tx_copy.wtxid())
self.assertEqual('3c06ae4d9be8226a472b3e7f7c127c7e3016f525d658d26106b80b4c7e3228e2', tx_copy.txid())
wallet1.receive_tx_callback(tx.txid(), tx, TX_HEIGHT_UNCONFIRMED) # TX_HEIGHT_UNCONF_PARENT but nvm
wallet2.receive_tx_callback(tx.txid(), tx, TX_HEIGHT_UNCONFIRMED)
# wallet2 -> wallet1
outputs = [(bitcoin.TYPE_ADDRESS, wallet1.get_receiving_address(), 100000)]
tx = wallet2.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(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('5f25707571eb776bdf14142f9966bf2a681906e0a79501edbb99a972c2ceb972', tx_copy.txid())
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, funding_output_value - 250000 - 5000 + 100000, 0), wallet1.get_balance())
self.assertEqual((0, 250000 - 5000 - 100000, 0), wallet2.get_balance())
@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
)
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
)
# ^ 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')
# bootstrap wallet1
funding_tx = Transaction('010000000001014121f99dc02f0364d2dab3d08905ff4c36fc76c55437fd90b769c35cc18618280100000000fdffffff02d4c22d00000000001600143fd1bc5d32245850c8cb5be5b09c73ccbb9a0f75001bb7000000000017a91480c2353f6a7bc3c71e99e062655b19adb3dd2e4887024830450221008781c78df0c9d4b5ea057333195d5d76bc29494d773f14fa80e27d2f288b2c360220762531614799b6f0fb8d539b18cb5232ab4253dd4385435157b28a44ff63810d0121033de77d21926e09efd04047ae2d39dbd3fb9db446e8b7ed53e0f70f9c9478f735dac11300')
funding_txid = funding_tx.txid()
funding_output_value = 12000000
self.assertEqual('b25cd55687c9e528c2cfd546054f35fb6741f7cf32d600f07dfecdf2e1d42071', funding_txid)
wallet1a.receive_tx_callback(funding_txid, funding_tx, TX_HEIGHT_UNCONFIRMED)
# wallet1 -> wallet2
outputs = [(bitcoin.TYPE_ADDRESS, wallet2.get_receiving_address(), 370000)]
tx = wallet1a.mktx(outputs=outputs, password=None, config=self.config, fee=5000)
tx = Transaction(tx.serialize()) # simulates moving partial txn between cosigners
self.assertFalse(tx.is_complete())
wallet1b.sign_transaction(tx, password=None)
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('26f3bdd0402e1cff19126244ebe3d32722cef0db507c7229ca8754f5e06ef25d', 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(), 100000)]
tx = wallet2.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(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('c573b3f8464a4ed40dfc79d0889a780f44e917beef7a75883b2427c2987f3e95', 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 - 370000 - 5000 + 100000, 0), wallet1a.get_balance())
self.assertEqual((0, 370000 - 5000 - 100000, 0), wallet2.get_balance())
@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
)
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
)
# ^ 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
)
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
)
# bootstrap wallet1
funding_tx = Transaction('01000000000101a41aae475d026c9255200082c7fad26dc47771275b0afba238dccda98a597bd20000000000fdffffff02400d0300000000002200203c43ac80d6e3015cf378bf6bac0c22456723d6050bef324ec641e7762440c63c9dcd410000000000160014824626055515f3ed1d2cfc9152d2e70685c71e8f02483045022100b9f39fad57d07ce1e18251424034f21f10f20e59931041b5167ae343ce973cf602200fefb727fa0ffd25b353f1bcdae2395898fe407b692c62f5885afbf52fa06f5701210301a28f68511ace43114b674371257bb599fd2c686c4b19544870b1799c954b40e9c11300')
funding_txid = funding_tx.txid()
funding_output_value = 200000
self.assertEqual('d2bd6c9d332db8e2c50aa521cd50f963fba214645aab2f7556e061a412103e21', funding_txid)
wallet1a.receive_tx_callback(funding_txid, funding_tx, TX_HEIGHT_UNCONFIRMED)
# wallet1 -> wallet2
outputs = [(bitcoin.TYPE_ADDRESS, wallet2a.get_receiving_address(), 165000)]
tx = wallet1a.mktx(outputs=outputs, password=None, config=self.config, fee=5000)
tx = Transaction(tx.serialize()) # simulates moving partial txn between cosigners
self.assertFalse(tx.is_complete())
wallet1b.sign_transaction(tx, password=None)
self.assertTrue(tx.is_complete())
self.assertTrue(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('6e9c3cd8788bdb970a124ea06136d52bc01cec4f9b1e217627d5e90ebe77d049', tx_copy.txid())
wallet1a.receive_tx_callback(tx.txid(), tx, TX_HEIGHT_UNCONFIRMED)
wallet2a.receive_tx_callback(tx.txid(), tx, TX_HEIGHT_UNCONFIRMED)
# wallet2 -> wallet1
outputs = [(bitcoin.TYPE_ADDRESS, wallet1a.get_receiving_address(), 100000)]
tx = wallet2a.mktx(outputs=outputs, password=None, config=self.config, fee=5000)
tx = Transaction(tx.serialize()) # simulates moving partial txn between cosigners
self.assertFalse(tx.is_complete())
wallet2b.sign_transaction(tx, password=None)
self.assertTrue(tx.is_complete())
self.assertTrue(tx.is_segwit())
self.assertEqual(1, len(tx.inputs()))
tx_copy = Transaction(tx.serialize())
self.assertEqual(wallet2a.is_mine(tx.inputs()[0]['address']), wallet2a.is_mine(tx_copy.inputs()[0]['address']))
self.assertTrue(wallet2a.is_mine(tx.inputs()[0]['address']))
self.assertEqual(wallet2a.txin_type, tx_copy.inputs()[0]['type'])
self.assertEqual(tx.wtxid(), tx_copy.wtxid())
self.assertEqual('84b0dcb43022385f7a10e2710e5625a2be3cd6e390387b6100b55500d5eea8f6', tx_copy.txid())
wallet1a.receive_tx_callback(tx.txid(), tx, TX_HEIGHT_UNCONFIRMED)
wallet2a.receive_tx_callback(tx.txid(), tx, TX_HEIGHT_UNCONFIRMED)
# 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())

Loading…
Cancel
Save