Browse Source

Update tests to use 1/0 not True/False addr type

Prior to this commit, several test functions were using
"True" to flag internal and "False" to flag external for
the HD branch for the wallet, but we now use BaseWallet vars
ADDRESS_TYPE_[IN/EX]TERNAL (1/0), so this
is changed to explicitly reference those. There is no change
to the live code (which calls get_[internal/external]_addr).
In addition _index_cache updates in wallet are protected
with a wrapper function to ensure that the branch requested
is valid.
Tests pass both before and after this change.
master
Adam Gibson 5 years ago committed by Kristaps Kaupe
parent
commit
47b2a9cf0b
No known key found for this signature in database
GPG Key ID: 33E472FE870C7E5D
  1. 18
      jmclient/jmclient/wallet.py
  2. 8
      jmclient/jmclient/wallet_service.py
  3. 7
      jmclient/jmclient/wallet_utils.py
  4. 8
      jmclient/test/commontest.py
  5. 62
      jmclient/test/test_blockchaininterface.py
  6. 11
      jmclient/test/test_core_nohistory_sync.py
  7. 6
      jmclient/test/test_snicker.py
  8. 45
      jmclient/test/test_wallet.py
  9. 8
      scripts/convert_old_wallet.py
  10. 9
      test/common.py
  11. 8
      test/test_segwit.py

18
jmclient/jmclient/wallet.py

@ -1824,7 +1824,7 @@ class BIP32Wallet(BaseWallet):
def _get_key_ident(self): def _get_key_ident(self):
return sha256(sha256( return sha256(sha256(
self.get_bip32_priv_export(0, 0).encode('ascii')).digest())\ self.get_bip32_priv_export(0, self.BIP32_EXT_ID).encode('ascii')).digest())\
.digest()[:3] .digest()[:3]
def _populate_script_map(self): def _populate_script_map(self):
@ -1976,10 +1976,18 @@ class BIP32Wallet(BaseWallet):
index = self.get_index_cache_and_increment(mixdepth, address_type) index = self.get_index_cache_and_increment(mixdepth, address_type)
return self.get_script_and_update_map(mixdepth, address_type, index) return self.get_script_and_update_map(mixdepth, address_type, index)
def _set_index_cache(self, mixdepth, address_type, index):
""" Ensures that any update to index_cache dict only applies
to valid address types.
"""
assert address_type in self._get_supported_address_types()
self._index_cache[mixdepth][address_type] = index
def get_index_cache_and_increment(self, mixdepth, address_type): def get_index_cache_and_increment(self, mixdepth, address_type):
index = self._index_cache[mixdepth][address_type] index = self._index_cache[mixdepth][address_type]
self._index_cache[mixdepth][address_type] += 1 cur_index = self._index_cache[mixdepth][address_type]
return index self._set_index_cache(mixdepth, address_type, cur_index + 1)
return cur_index
def get_script_and_update_map(self, *args): def get_script_and_update_map(self, *args):
path = self.get_path(*args) path = self.get_path(*args)
@ -2052,7 +2060,7 @@ class BIP32Wallet(BaseWallet):
def set_next_index(self, mixdepth, address_type, index, force=False): def set_next_index(self, mixdepth, address_type, index, force=False):
if not (force or index <= self._index_cache[mixdepth][address_type]): if not (force or index <= self._index_cache[mixdepth][address_type]):
raise Exception("cannot advance index without force=True") raise Exception("cannot advance index without force=True")
self._index_cache[mixdepth][address_type] = index self._set_index_cache(mixdepth, address_type, index)
def get_details(self, path): def get_details(self, path):
if not self._is_my_bip32_path(path): if not self._is_my_bip32_path(path):
@ -2176,7 +2184,7 @@ class FidelityBondMixin(object):
return len(path) > 4 and path[4] == cls.BIP32_TIMELOCK_ID return len(path) > 4 and path[4] == cls.BIP32_TIMELOCK_ID
def _get_key_ident(self): def _get_key_ident(self):
first_path = self.get_path(0, 0) first_path = self.get_path(0, BIP32Wallet.BIP32_EXT_ID)
priv, engine = self._get_key_from_path(first_path) priv, engine = self._get_key_from_path(first_path)
pub = engine.privkey_to_pubkey(priv) pub = engine.privkey_to_pubkey(priv)
return sha256(sha256(pub).digest()).digest()[:3] return sha256(sha256(pub).digest()).digest()[:3]

8
jmclient/jmclient/wallet_service.py

@ -14,7 +14,7 @@ from jmclient.configure import jm_single, get_log
from jmclient.output import fmt_tx_data from jmclient.output import fmt_tx_data
from jmclient.blockchaininterface import (INF_HEIGHT, BitcoinCoreInterface, from jmclient.blockchaininterface import (INF_HEIGHT, BitcoinCoreInterface,
BitcoinCoreNoHistoryInterface) BitcoinCoreNoHistoryInterface)
from jmclient.wallet import FidelityBondMixin from jmclient.wallet import FidelityBondMixin, BaseWallet
from jmbase import stop_reactor from jmbase import stop_reactor
from jmbase.support import jmprint, EXIT_SUCCESS, utxo_to_utxostr, hextobin from jmbase.support import jmprint, EXIT_SUCCESS, utxo_to_utxostr, hextobin
@ -867,7 +867,8 @@ class WalletService(Service):
for md in range(self.max_mixdepth + 1): for md in range(self.max_mixdepth + 1):
saved_indices[md] = [0, 0] saved_indices[md] = [0, 0]
for address_type in (0, 1): for address_type in (BaseWallet.ADDRESS_TYPE_EXTERNAL,
BaseWallet.ADDRESS_TYPE_INTERNAL):
next_unused = self.get_next_unused_index(md, address_type) next_unused = self.get_next_unused_index(md, address_type)
for index in range(next_unused): for index in range(next_unused):
addresses.add(self.get_addr(md, address_type, index)) addresses.add(self.get_addr(md, address_type, index))
@ -904,7 +905,8 @@ class WalletService(Service):
addresses = set() addresses = set()
for md in range(self.max_mixdepth + 1): for md in range(self.max_mixdepth + 1):
for address_type in (1, 0): for address_type in (BaseWallet.ADDRESS_TYPE_INTERNAL,
BaseWallet.ADDRESS_TYPE_EXTERNAL):
old_next = self.get_next_unused_index(md, address_type) old_next = self.get_next_unused_index(md, address_type)
for index in range(gap_limit): for index in range(gap_limit):
addresses.add(self.get_new_addr(md, address_type)) addresses.add(self.get_new_addr(md, address_type))

7
jmclient/jmclient/wallet_utils.py

@ -11,7 +11,7 @@ from numbers import Integral
from collections import Counter from collections import Counter
from itertools import islice from itertools import islice
from jmclient import (get_network, WALLET_IMPLEMENTATIONS, Storage, podle, from jmclient import (get_network, WALLET_IMPLEMENTATIONS, Storage, podle,
jm_single, BitcoinCoreInterface, WalletError, jm_single, BitcoinCoreInterface, WalletError, BaseWallet,
VolatileStorage, StoragePasswordError, is_segwit_mode, SegwitLegacyWallet, VolatileStorage, StoragePasswordError, is_segwit_mode, SegwitLegacyWallet,
LegacyWallet, SegwitWallet, FidelityBondMixin, FidelityBondWatchonlyWallet, LegacyWallet, SegwitWallet, FidelityBondMixin, FidelityBondWatchonlyWallet,
is_native_segwit_mode, load_program_config, add_base_options, check_regtest) is_native_segwit_mode, load_program_config, add_base_options, check_regtest)
@ -452,9 +452,10 @@ def wallet_display(wallet_service, showprivkey, displayall=False,
utxos = wallet_service.get_utxos_by_mixdepth(include_disabled=True) utxos = wallet_service.get_utxos_by_mixdepth(include_disabled=True)
for m in range(wallet_service.mixdepth + 1): for m in range(wallet_service.mixdepth + 1):
branchlist = [] branchlist = []
for address_type in [0, 1]: for address_type in [BaseWallet.ADDRESS_TYPE_EXTERNAL,
BaseWallet.ADDRESS_TYPE_INTERNAL]:
entrylist = [] entrylist = []
if address_type == 0: if address_type == BaseWallet.ADDRESS_TYPE_EXTERNAL:
# users would only want to hand out the xpub for externals # users would only want to hand out the xpub for externals
xpub_key = wallet_service.get_bip32_pub_export(m, address_type) xpub_key = wallet_service.get_bip32_pub_export(m, address_type)
else: else:

8
jmclient/test/commontest.py

@ -10,7 +10,7 @@ from jmbase import (get_log, hextobin, bintohex, dictchanger)
from jmclient import ( from jmclient import (
jm_single, open_test_wallet_maybe, estimate_tx_fee, jm_single, open_test_wallet_maybe, estimate_tx_fee,
BlockchainInterface, BIP32Wallet, BlockchainInterface, BIP32Wallet, BaseWallet,
SegwitWallet, WalletService, BTC_P2SH_P2WPKH) SegwitWallet, WalletService, BTC_P2SH_P2WPKH)
from jmbase.support import chunks from jmbase.support import chunks
import jmbitcoin as btc import jmbitcoin as btc
@ -146,8 +146,8 @@ def make_sign_and_push(ins_full,
total = sum(x['value'] for x in ins_full.values()) total = sum(x['value'] for x in ins_full.values())
ins = list(ins_full.keys()) ins = list(ins_full.keys())
#random output address and change addr #random output address and change addr
output_addr = wallet_service.get_new_addr(1, 1) if not output_addr else output_addr output_addr = wallet_service.get_new_addr(1, BaseWallet.ADDRESS_TYPE_INTERNAL) if not output_addr else output_addr
change_addr = wallet_service.get_new_addr(0, 1) if not change_addr else change_addr change_addr = wallet_service.get_new_addr(0, BaseWallet.ADDRESS_TYPE_INTERNAL) if not change_addr else change_addr
fee_est = estimate_tx_fee(len(ins), 2) if estimate_fee else 10000 fee_est = estimate_tx_fee(len(ins), 2) if estimate_fee else 10000
outs = [{'value': amount, outs = [{'value': amount,
'address': output_addr}, {'value': total - amount - fee_est, 'address': output_addr}, {'value': total - amount - fee_est,
@ -179,7 +179,7 @@ def make_wallets(n,
fixed_seeds=None, fixed_seeds=None,
wallet_cls=SegwitWallet, wallet_cls=SegwitWallet,
mixdepths=5, mixdepths=5,
populate_internal=False): populate_internal=BaseWallet.ADDRESS_TYPE_EXTERNAL):
'''n: number of wallets to be created '''n: number of wallets to be created
wallet_structure: array of n arrays , each subarray wallet_structure: array of n arrays , each subarray
specifying the number of addresses to be populated with coins specifying the number of addresses to be populated with coins

62
jmclient/test/test_blockchaininterface.py

@ -6,7 +6,7 @@ from commontest import create_wallet_for_sync
import pytest import pytest
from jmbase import get_log from jmbase import get_log
from jmclient import load_test_config, jm_single from jmclient import load_test_config, jm_single, BaseWallet
log = get_log() log = get_log()
@ -30,15 +30,18 @@ def test_empty_wallet_sync(setup_wallets, fast):
broken = True broken = True
for md in range(wallet_service.max_mixdepth + 1): for md in range(wallet_service.max_mixdepth + 1):
for internal in (True, False): for internal in (BaseWallet.ADDRESS_TYPE_INTERNAL,
BaseWallet.ADDRESS_TYPE_EXTERNAL):
broken = False broken = False
assert 0 == wallet_service.get_next_unused_index(md, internal) assert 0 == wallet_service.get_next_unused_index(md, internal)
assert not broken assert not broken
@pytest.mark.parametrize('fast,internal', ( @pytest.mark.parametrize('fast,internal', (
(False, False), (False, True), (False, BaseWallet.ADDRESS_TYPE_EXTERNAL),
(True, False), (True, True))) (False, BaseWallet.ADDRESS_TYPE_INTERNAL),
(True, BaseWallet.ADDRESS_TYPE_EXTERNAL),
(True, BaseWallet.ADDRESS_TYPE_INTERNAL)))
def test_sequentially_used_wallet_sync(setup_wallets, fast, internal): def test_sequentially_used_wallet_sync(setup_wallets, fast, internal):
used_count = [1, 3, 6, 2, 23] used_count = [1, 3, 6, 2, 23]
wallet_service = create_wallet_for_sync( wallet_service = create_wallet_for_sync(
@ -72,23 +75,27 @@ def test_gap_used_wallet_sync(setup_wallets, fast):
for x in range(md): for x in range(md):
assert x <= wallet_service.gap_limit, "test broken" assert x <= wallet_service.gap_limit, "test broken"
# create some unused addresses # create some unused addresses
wallet_service.get_new_script(md, True) wallet_service.get_new_script(md, BaseWallet.ADDRESS_TYPE_INTERNAL)
wallet_service.get_new_script(md, False) wallet_service.get_new_script(md, BaseWallet.ADDRESS_TYPE_EXTERNAL)
used_count[md] += x + 2 used_count[md] += x + 2
jm_single().bc_interface.grab_coins(wallet_service.get_new_addr(md, True), 1) jm_single().bc_interface.grab_coins(wallet_service.get_new_addr(md,
jm_single().bc_interface.grab_coins(wallet_service.get_new_addr(md, False), 1) BaseWallet.ADDRESS_TYPE_INTERNAL), 1)
jm_single().bc_interface.grab_coins(wallet_service.get_new_addr(md,
BaseWallet.ADDRESS_TYPE_EXTERNAL), 1)
# reset indices to simulate completely unsynced wallet # reset indices to simulate completely unsynced wallet
for md in range(wallet_service.max_mixdepth + 1): for md in range(wallet_service.max_mixdepth + 1):
wallet_service.set_next_index(md, True, 0) wallet_service.set_next_index(md, BaseWallet.ADDRESS_TYPE_INTERNAL, 0)
wallet_service.set_next_index(md, False, 0) wallet_service.set_next_index(md, BaseWallet.ADDRESS_TYPE_EXTERNAL, 0)
sync_test_wallet(fast, wallet_service) sync_test_wallet(fast, wallet_service)
broken = True broken = True
for md in range(len(used_count)): for md in range(len(used_count)):
broken = False broken = False
assert md + 1 == wallet_service.get_next_unused_index(md, True) assert md + 1 == wallet_service.get_next_unused_index(md,
assert used_count[md] == wallet_service.get_next_unused_index(md, False) BaseWallet.ADDRESS_TYPE_INTERNAL)
assert used_count[md] == wallet_service.get_next_unused_index(md,
BaseWallet.ADDRESS_TYPE_EXTERNAL)
assert not broken assert not broken
@ -107,34 +114,43 @@ def test_multigap_used_wallet_sync(setup_wallets, fast):
for x in range(int(wallet_service.gap_limit * 0.6)): for x in range(int(wallet_service.gap_limit * 0.6)):
assert x <= wallet_service.gap_limit, "test broken" assert x <= wallet_service.gap_limit, "test broken"
# create some unused addresses # create some unused addresses
wallet_service.get_new_script(mixdepth, True) wallet_service.get_new_script(mixdepth,
wallet_service.get_new_script(mixdepth, False) BaseWallet.ADDRESS_TYPE_INTERNAL)
wallet_service.get_new_script(mixdepth,
BaseWallet.ADDRESS_TYPE_EXTERNAL)
used_count[mixdepth] += x + 2 used_count[mixdepth] += x + 2
jm_single().bc_interface.grab_coins(wallet_service.get_new_addr(mixdepth, True), 1) jm_single().bc_interface.grab_coins(wallet_service.get_new_addr(
jm_single().bc_interface.grab_coins(wallet_service.get_new_addr(mixdepth, False), 1) mixdepth, BaseWallet.ADDRESS_TYPE_INTERNAL), 1)
jm_single().bc_interface.grab_coins(wallet_service.get_new_addr(
mixdepth, BaseWallet.ADDRESS_TYPE_EXTERNAL), 1)
# reset indices to simulate completely unsynced wallet # reset indices to simulate completely unsynced wallet
for md in range(wallet_service.max_mixdepth + 1): for md in range(wallet_service.max_mixdepth + 1):
wallet_service.set_next_index(md, True, 0) wallet_service.set_next_index(md, BaseWallet.ADDRESS_TYPE_INTERNAL, 0)
wallet_service.set_next_index(md, False, 0) wallet_service.set_next_index(md, BaseWallet.ADDRESS_TYPE_EXTERNAL, 0)
sync_test_wallet(fast, wallet_service) sync_test_wallet(fast, wallet_service)
assert used_count[mixdepth] - start_index == wallet_service.get_next_unused_index(mixdepth, True) assert used_count[mixdepth] - start_index == \
assert used_count[mixdepth] == wallet_service.get_next_unused_index(mixdepth, False) wallet_service.get_next_unused_index(mixdepth,
BaseWallet.ADDRESS_TYPE_INTERNAL)
assert used_count[mixdepth] == wallet_service.get_next_unused_index(
mixdepth, BaseWallet.ADDRESS_TYPE_EXTERNAL)
@pytest.mark.parametrize('fast', (False, True)) @pytest.mark.parametrize('fast', (False, True))
def test_retain_unused_indices_wallet_sync(setup_wallets, fast): def test_retain_unused_indices_wallet_sync(setup_wallets, fast):
used_count = [0, 0, 0, 0, 0] used_count = [0, 0, 0, 0, 0]
wallet_service = create_wallet_for_sync(used_count, ['test_retain_unused_indices_wallet_sync']) wallet_service = create_wallet_for_sync(used_count,
['test_retain_unused_indices_wallet_sync'])
for x in range(9): for x in range(9):
wallet_service.get_new_script(0, 1) wallet_service.get_new_script(0, BaseWallet.ADDRESS_TYPE_INTERNAL)
sync_test_wallet(fast, wallet_service) sync_test_wallet(fast, wallet_service)
assert wallet_service.get_next_unused_index(0, 1) == 9 assert wallet_service.get_next_unused_index(0,
BaseWallet.ADDRESS_TYPE_INTERNAL) == 9
@pytest.mark.parametrize('fast', (False, True)) @pytest.mark.parametrize('fast', (False, True))

11
jmclient/test/test_core_nohistory_sync.py

@ -8,7 +8,7 @@ from commontest import create_wallet_for_sync
import pytest import pytest
from jmbase import get_log from jmbase import get_log
from jmclient import (load_test_config, SegwitLegacyWallet, from jmclient import (load_test_config, SegwitLegacyWallet,
SegwitWallet, jm_single) SegwitWallet, jm_single, BaseWallet)
from jmbitcoin import select_chain_params from jmbitcoin import select_chain_params
log = get_log() log = get_log()
@ -19,10 +19,11 @@ def test_fast_sync_unavailable(setup_sync):
with pytest.raises(RuntimeError) as e_info: with pytest.raises(RuntimeError) as e_info:
wallet_service.sync_wallet(fast=True) wallet_service.sync_wallet(fast=True)
@pytest.mark.parametrize('internal, wallet_cls', [(False, SegwitLegacyWallet), @pytest.mark.parametrize('internal, wallet_cls',
(True, SegwitLegacyWallet), [(BaseWallet.ADDRESS_TYPE_EXTERNAL, SegwitLegacyWallet),
(False, SegwitWallet), (BaseWallet.ADDRESS_TYPE_INTERNAL, SegwitLegacyWallet),
(True, SegwitWallet)]) (BaseWallet.ADDRESS_TYPE_EXTERNAL, SegwitWallet),
(BaseWallet.ADDRESS_TYPE_INTERNAL, SegwitWallet)])
def test_sync(setup_sync, internal, wallet_cls): def test_sync(setup_sync, internal, wallet_cls):
used_count = [1, 3, 6, 2, 23] used_count = [1, 3, 6, 2, 23]
wallet_service = create_wallet_for_sync(used_count, ['test_sync'], wallet_service = create_wallet_for_sync(used_count, ['test_sync'],

6
jmclient/test/test_snicker.py

@ -9,7 +9,7 @@ from commontest import make_wallets, dummy_accept_callback, dummy_info_callback
import jmbitcoin as btc import jmbitcoin as btc
from jmbase import get_log, bintohex from jmbase import get_log, bintohex
from jmclient import (load_test_config, estimate_tx_fee, SNICKERReceiver, from jmclient import (load_test_config, estimate_tx_fee, SNICKERReceiver,
direct_send, SegwitLegacyWallet) direct_send, SegwitLegacyWallet, BaseWallet)
TEST_PROPOSALS_FILE = "test_proposals.txt" TEST_PROPOSALS_FILE = "test_proposals.txt"
log = get_log() log = get_log()
@ -41,7 +41,7 @@ def test_snicker_e2e(setup_snicker, nw, wallet_structures,
wallet_r = wallets[0]['wallet'] wallet_r = wallets[0]['wallet']
wallet_p = wallets[1]['wallet'] wallet_p = wallets[1]['wallet']
# next, create a tx from the receiver wallet # next, create a tx from the receiver wallet
our_destn_script = wallet_r.get_new_script(1, 1) our_destn_script = wallet_r.get_new_script(1, BaseWallet.ADDRESS_TYPE_INTERNAL)
tx = direct_send(wallet_r, btc.coins_to_satoshi(0.3), 0, tx = direct_send(wallet_r, btc.coins_to_satoshi(0.3), 0,
wallet_r.script_to_addr(our_destn_script), wallet_r.script_to_addr(our_destn_script),
accept_callback=dummy_accept_callback, accept_callback=dummy_accept_callback,
@ -83,7 +83,7 @@ def test_snicker_e2e(setup_snicker, nw, wallet_structures,
our_input_utxo = btc.CMutableTxOut(prop_utxo['value'], our_input_utxo = btc.CMutableTxOut(prop_utxo['value'],
prop_utxo['script']) prop_utxo['script'])
fee_est = estimate_tx_fee(len(tx.vin), 2) fee_est = estimate_tx_fee(len(tx.vin), 2)
change_spk = wallet_p.get_new_script(0, 1) change_spk = wallet_p.get_new_script(0, BaseWallet.ADDRESS_TYPE_INTERNAL)
encrypted_proposals = [] encrypted_proposals = []

45
jmclient/test/test_wallet.py

@ -8,7 +8,7 @@ import pytest
import jmbitcoin as btc import jmbitcoin as btc
from commontest import ensure_bip65_activated from commontest import ensure_bip65_activated
from jmbase import get_log, hextobin from jmbase import get_log, hextobin
from jmclient import load_test_config, jm_single, \ from jmclient import load_test_config, jm_single, BaseWallet, \
SegwitLegacyWallet,BIP32Wallet, BIP49Wallet, LegacyWallet,\ SegwitLegacyWallet,BIP32Wallet, BIP49Wallet, LegacyWallet,\
VolatileStorage, get_network, cryptoengine, WalletError,\ VolatileStorage, get_network, cryptoengine, WalletError,\
SegwitWallet, WalletService, SegwitLegacyWalletFidelityBonds,\ SegwitWallet, WalletService, SegwitLegacyWalletFidelityBonds,\
@ -186,10 +186,10 @@ def test_bip32_test_vector_3(monkeypatch, setup_wallet):
@pytest.mark.parametrize('mixdepth,internal,index,address,wif', [ @pytest.mark.parametrize('mixdepth,internal,index,address,wif', [
[0, 0, 0, 'mpCX9EbdXpcrKMtjEe1fqFhvzctkfzMYTX', 'cVqtSSoVxFyPqTRGfeESi31uCYfgTF4tGWRtGeVs84fzybiX5TPk'], [0, BaseWallet.ADDRESS_TYPE_EXTERNAL, 0, 'mpCX9EbdXpcrKMtjEe1fqFhvzctkfzMYTX', 'cVqtSSoVxFyPqTRGfeESi31uCYfgTF4tGWRtGeVs84fzybiX5TPk'],
[0, 0, 5, 'mtj85a3pFppRhrxNcFig1k7ECshrZjJ9XC', 'cMsFXc4TRw9PTcCTv7x9mr88rDeGXBTLEV67mKaw2cxCkjkhL32G'], [0, BaseWallet.ADDRESS_TYPE_EXTERNAL, 5, 'mtj85a3pFppRhrxNcFig1k7ECshrZjJ9XC', 'cMsFXc4TRw9PTcCTv7x9mr88rDeGXBTLEV67mKaw2cxCkjkhL32G'],
[0, 1, 3, 'n1EaQuqvTRm719hsSJ7yRsj49JfoG1C86q', 'cUgSTqnAtvYoQRXCYy4wCFfaks2Zrz1d55m6mVhFyVhQbkDi7JGJ'], [0, BaseWallet.ADDRESS_TYPE_INTERNAL, 3, 'n1EaQuqvTRm719hsSJ7yRsj49JfoG1C86q', 'cUgSTqnAtvYoQRXCYy4wCFfaks2Zrz1d55m6mVhFyVhQbkDi7JGJ'],
[2, 1, 2, 'mfxkBk7uDhmF5PJGS9d1NonGiAxPwJqQP4', 'cPcZXSiXPuS5eiT4oDrDKi1mFumw5D1RcWzK2gkGdEHjEz99eyXn'] [2, BaseWallet.ADDRESS_TYPE_INTERNAL, 2, 'mfxkBk7uDhmF5PJGS9d1NonGiAxPwJqQP4', 'cPcZXSiXPuS5eiT4oDrDKi1mFumw5D1RcWzK2gkGdEHjEz99eyXn']
]) ])
def test_bip32_addresses_p2pkh(monkeypatch, setup_wallet, mixdepth, internal, index, address, wif): def test_bip32_addresses_p2pkh(monkeypatch, setup_wallet, mixdepth, internal, index, address, wif):
""" """
@ -391,7 +391,7 @@ def test_signing_simple(setup_wallet, wallet_cls, type_check):
[{"address": str(btc.CCoinAddress.from_scriptPubKey( [{"address": str(btc.CCoinAddress.from_scriptPubKey(
btc.CScript(b"\x00").to_p2sh_scriptPubKey())), btc.CScript(b"\x00").to_p2sh_scriptPubKey())),
"value": 10**8 - 9000}]) "value": 10**8 - 9000}])
script = wallet.get_script(0, 1, 0) script = wallet.get_script(0, BaseWallet.ADDRESS_TYPE_INTERNAL, 0)
success, msg = wallet.sign_tx(tx, {0: (script, 10**8)}) success, msg = wallet.sign_tx(tx, {0: (script, 10**8)})
assert success, msg assert success, msg
type_check(tx) type_check(tx)
@ -486,7 +486,8 @@ def test_add_new_utxos(setup_wallet):
jm_single().config.set('BLOCKCHAIN', 'network', 'testnet') jm_single().config.set('BLOCKCHAIN', 'network', 'testnet')
wallet = get_populated_wallet(num=1) wallet = get_populated_wallet(num=1)
scripts = [wallet.get_new_script(x, True) for x in range(3)] scripts = [wallet.get_new_script(x,
BaseWallet.ADDRESS_TYPE_INTERNAL) for x in range(3)]
tx_scripts = list(scripts) tx_scripts = list(scripts)
tx = btc.mktx( tx = btc.mktx(
[(b"\x00"*32, 2)], [(b"\x00"*32, 2)],
@ -514,7 +515,8 @@ def test_remove_old_utxos(setup_wallet):
for i in range(3): for i in range(3):
txin = jm_single().bc_interface.grab_coins( txin = jm_single().bc_interface.grab_coins(
wallet.get_internal_addr(1), 1) wallet.get_internal_addr(1), 1)
wallet.add_utxo(btc.x(txin), 0, wallet.get_script(1, 1, i), 10**8, 1) wallet.add_utxo(btc.x(txin), 0, wallet.get_script(1,
BaseWallet.ADDRESS_TYPE_INTERNAL, i), 10**8, 1)
inputs = wallet.select_utxos(0, 10**8) inputs = wallet.select_utxos(0, 10**8)
inputs.update(wallet.select_utxos(1, 2 * 10**8)) inputs.update(wallet.select_utxos(1, 2 * 10**8))
@ -549,7 +551,7 @@ def test_initialize_twice(setup_wallet):
def test_is_known(setup_wallet): def test_is_known(setup_wallet):
wallet = get_populated_wallet(num=0) wallet = get_populated_wallet(num=0)
script = wallet.get_new_script(1, True) script = wallet.get_new_script(1, BaseWallet.ADDRESS_TYPE_INTERNAL)
addr = wallet.get_external_addr(2) addr = wallet.get_external_addr(2)
assert wallet.is_known_script(script) assert wallet.is_known_script(script)
@ -576,29 +578,30 @@ def test_wallet_save(setup_wallet):
storage = VolatileStorage(data=data) storage = VolatileStorage(data=data)
wallet = SegwitLegacyWallet(storage) wallet = SegwitLegacyWallet(storage)
assert wallet.get_next_unused_index(0, True) == 3 assert wallet.get_next_unused_index(0, BaseWallet.ADDRESS_TYPE_INTERNAL) == 3
assert wallet.get_next_unused_index(0, False) == 0 assert wallet.get_next_unused_index(0, BaseWallet.ADDRESS_TYPE_EXTERNAL) == 0
assert wallet.get_next_unused_index(1, True) == 0 assert wallet.get_next_unused_index(1, BaseWallet.ADDRESS_TYPE_INTERNAL) == 0
assert wallet.get_next_unused_index(1, False) == 1 assert wallet.get_next_unused_index(1, BaseWallet.ADDRESS_TYPE_EXTERNAL) == 1
assert wallet.is_known_script(script) assert wallet.is_known_script(script)
def test_set_next_index(setup_wallet): def test_set_next_index(setup_wallet):
wallet = get_populated_wallet() wallet = get_populated_wallet()
assert wallet.get_next_unused_index(0, True) == 3 assert wallet.get_next_unused_index(0,
BaseWallet.ADDRESS_TYPE_INTERNAL) == 3
with pytest.raises(Exception): with pytest.raises(Exception):
# cannot advance index without force=True # cannot advance index without force=True
wallet.set_next_index(0, True, 5) wallet.set_next_index(0, BaseWallet.ADDRESS_TYPE_INTERNAL, 5)
wallet.set_next_index(0, True, 1) wallet.set_next_index(0, BaseWallet.ADDRESS_TYPE_INTERNAL, 1)
assert wallet.get_next_unused_index(0, True) == 1 assert wallet.get_next_unused_index(0, BaseWallet.ADDRESS_TYPE_INTERNAL) == 1
wallet.set_next_index(0, True, 20, force=True) wallet.set_next_index(0, BaseWallet.ADDRESS_TYPE_INTERNAL, 20, force=True)
assert wallet.get_next_unused_index(0, True) == 20 assert wallet.get_next_unused_index(0, BaseWallet.ADDRESS_TYPE_INTERNAL) == 20
script = wallet.get_new_script(0, True) script = wallet.get_new_script(0, BaseWallet.ADDRESS_TYPE_INTERNAL)
path = wallet.script_to_path(script) path = wallet.script_to_path(script)
index = wallet.get_details(path)[2] index = wallet.get_details(path)[2]
assert index == 20 assert index == 20
@ -693,7 +696,7 @@ def test_wallet_id(setup_wallet):
def test_addr_script_conversion(setup_wallet): def test_addr_script_conversion(setup_wallet):
wallet = get_populated_wallet(num=1) wallet = get_populated_wallet(num=1)
path = wallet.get_path(0, True, 0) path = wallet.get_path(0, BaseWallet.ADDRESS_TYPE_INTERNAL, 0)
script = wallet.get_script_from_path(path) script = wallet.get_script_from_path(path)
addr = wallet.script_to_addr(script) addr = wallet.script_to_addr(script)

8
scripts/convert_old_wallet.py

@ -7,7 +7,7 @@ from binascii import hexlify, unhexlify
from collections import defaultdict from collections import defaultdict
from pyaes import AESModeOfOperationCBC, Decrypter from pyaes import AESModeOfOperationCBC, Decrypter
from jmbase import JM_APP_NAME from jmbase import JM_APP_NAME
from jmclient import Storage, load_program_config, BTCEngine from jmclient import Storage, load_program_config, BTCEngine, BaseWallet
from jmclient.wallet_utils import get_password, get_wallet_cls,\ from jmclient.wallet_utils import get_password, get_wallet_cls,\
cli_get_wallet_passphrase_check, get_wallet_path cli_get_wallet_passphrase_check, get_wallet_path
@ -91,8 +91,10 @@ def new_wallet_from_data(data, file_name):
if 'index_cache' in data: if 'index_cache' in data:
for md, indices in enumerate(data['index_cache']): for md, indices in enumerate(data['index_cache']):
wallet.set_next_index(md, 0, indices[0], force=True) wallet.set_next_index(md, BaseWallet.ADDRESS_TYPE_EXTERNAL,
wallet.set_next_index(md, 1, indices[1], force=True) indices[0], force=True)
wallet.set_next_index(md, BaseWallet.ADDRESS_TYPE_INTERNAL,
indices[1], force=True)
if 'imported' in data: if 'imported' in data:
for md in data['imported']: for md in data['imported']:

9
test/common.py

@ -12,7 +12,7 @@ sys.path.insert(0, os.path.join(data_dir))
from jmbase import get_log from jmbase import get_log
from jmclient import open_test_wallet_maybe, BIP32Wallet, SegwitWallet, \ from jmclient import open_test_wallet_maybe, BIP32Wallet, SegwitWallet, \
estimate_tx_fee, jm_single, WalletService estimate_tx_fee, jm_single, WalletService, BaseWallet
import jmbitcoin as btc import jmbitcoin as btc
from jmbase import chunks from jmbase import chunks
@ -32,8 +32,8 @@ def make_sign_and_push(ins_full,
total = sum(x['value'] for x in ins_full.values()) total = sum(x['value'] for x in ins_full.values())
ins = ins_full.keys() ins = ins_full.keys()
#random output address and change addr #random output address and change addr
output_addr = wallet_service.get_new_addr(1, 1) if not output_addr else output_addr output_addr = wallet_service.get_new_addr(1, BaseWallet.ADDRESS_TYPE_INTERNAL) if not output_addr else output_addr
change_addr = wallet_service.get_new_addr(0, 1) if not change_addr else change_addr change_addr = wallet_service.get_new_addr(0, BaseWallet.ADDRESS_TYPE_INTERNAL) if not change_addr else change_addr
fee_est = estimate_tx_fee(len(ins), 2) if estimate_fee else 10000 fee_est = estimate_tx_fee(len(ins), 2) if estimate_fee else 10000
outs = [{'value': amount, outs = [{'value': amount,
'address': output_addr}, {'value': total - amount - fee_est, 'address': output_addr}, {'value': total - amount - fee_est,
@ -106,7 +106,8 @@ def make_wallets(n,
amt = mean_amt - sdev_amt / 2.0 + deviation amt = mean_amt - sdev_amt / 2.0 + deviation
if amt < 0: amt = 0.001 if amt < 0: amt = 0.001
amt = float(Decimal(amt).quantize(Decimal(10)**-8)) amt = float(Decimal(amt).quantize(Decimal(10)**-8))
jm_single().bc_interface.grab_coins(wallet_service.get_new_addr(j, 1), amt) jm_single().bc_interface.grab_coins(wallet_service.get_new_addr(
j, BaseWallet.ADDRESS_TYPE_INTERNAL), amt)
return wallets return wallets

8
test/test_segwit.py

@ -7,7 +7,7 @@ from pprint import pformat
import jmbitcoin as btc import jmbitcoin as btc
import pytest import pytest
from jmbase import get_log, hextobin from jmbase import get_log, hextobin
from jmclient import load_test_config, jm_single, LegacyWallet from jmclient import load_test_config, jm_single, LegacyWallet, BaseWallet
log = get_log() log = get_log()
@ -90,8 +90,10 @@ def test_spend_p2sh_p2wpkh_multi(setup_segwit, wallet_structure, in_amt, amount,
FEE = 50000 FEE = 50000
assert FEE < total_amt_in_sat - amount, "test broken, not enough funds" assert FEE < total_amt_in_sat - amount, "test broken, not enough funds"
cj_script = nsw_wallet_service.get_new_script(MIXDEPTH + 1, True) cj_script = nsw_wallet_service.get_new_script(MIXDEPTH + 1,
change_script = nsw_wallet_service.get_new_script(MIXDEPTH, True) BaseWallet.ADDRESS_TYPE_INTERNAL)
change_script = nsw_wallet_service.get_new_script(MIXDEPTH,
BaseWallet.ADDRESS_TYPE_INTERNAL)
change_amt = total_amt_in_sat - amount - FEE change_amt = total_amt_in_sat - amount - FEE
tx_outs = [ tx_outs = [

Loading…
Cancel
Save