diff --git a/src/jmclient/wallet.py b/src/jmclient/wallet.py index 4f29d081b..5ac786fee 100644 --- a/src/jmclient/wallet.py +++ b/src/jmclient/wallet.py @@ -910,9 +910,12 @@ def get_balance_at_mixdepth(self, mixdepth, return self._utxos.get_balance_at_mixdepth(mixdepth, include_disabled=include_disabled, maxheight=maxheight) - def get_utxos_by_mixdepth(self, include_disabled=False, includeheight=False): + def get_utxos_by_mixdepth(self, include_disabled: bool = False, + includeheight: bool = False, + limit_mixdepth: Optional[int] = None + ) -> collections.defaultdict: """ - Get all UTXOs for active mixdepths. + Get all UTXOs for active mixdepths or specified mixdepth. returns: {mixdepth: {(txid, index): @@ -920,9 +923,15 @@ def get_utxos_by_mixdepth(self, include_disabled=False, includeheight=False): (if `includeheight` is True, adds key 'height': int) """ script_utxos = collections.defaultdict(dict) - for md in range(self.mixdepth + 1): - script_utxos[md] = self.get_utxos_at_mixdepth(md, - include_disabled=include_disabled, includeheight=includeheight) + if limit_mixdepth: + script_utxos[limit_mixdepth] = self.get_utxos_at_mixdepth( + mixdepth=limit_mixdepth, include_disabled=include_disabled, + includeheight=includeheight) + else: + for md in range(self.mixdepth + 1): + script_utxos[md] = self.get_utxos_at_mixdepth(md, + include_disabled=include_disabled, + includeheight=includeheight) return script_utxos def get_utxos_at_mixdepth(self, mixdepth: int, diff --git a/src/jmclient/wallet_service.py b/src/jmclient/wallet_service.py index 3b2902d0b..b68ae632c 100644 --- a/src/jmclient/wallet_service.py +++ b/src/jmclient/wallet_service.py @@ -900,12 +900,15 @@ def _add_unspent_txo(self, utxo: dict, height: Optional[int]) -> None: def save_wallet(self): self.wallet.save() - def get_utxos_by_mixdepth(self, include_disabled=False, - verbose=False, includeconfs=False): + def get_utxos_by_mixdepth(self, include_disabled: bool = False, + verbose: bool = False, + includeconfs: bool = False, + limit_mixdepth: Optional[int] = None + ) -> collections.defaultdict: """ Returns utxos by mixdepth in a dict, optionally including information about how many confirmations each utxo has. """ - def height_to_confs(x): + def height_to_confs(x: int) -> int: # convert height entries to confirmations: ubym_conv = collections.defaultdict(dict) for m, i in x.items(): @@ -919,7 +922,8 @@ def height_to_confs(x): ubym_conv[m][u]["confs"] = confs return ubym_conv ubym = self.wallet.get_utxos_by_mixdepth( - include_disabled=include_disabled, includeheight=includeconfs) + include_disabled=include_disabled, includeheight=includeconfs, + limit_mixdepth=limit_mixdepth) if not includeconfs: return ubym else: diff --git a/src/jmclient/wallet_utils.py b/src/jmclient/wallet_utils.py index 2bbf6c70e..b49bf1d71 100644 --- a/src/jmclient/wallet_utils.py +++ b/src/jmclient/wallet_utils.py @@ -426,11 +426,12 @@ def get_imported_privkey_branch(wallet_service, m, showprivkey): return WalletViewBranch("m/0", m, -1, branchentries=entries) return None -def wallet_showutxos(wallet_service, showprivkey): +def wallet_showutxos(wallet_service: WalletService, showprivkey: bool, + limit_mixdepth: Optional[int] = None) -> str: unsp = {} max_tries = jm_single().config.getint("POLICY", "taker_utxo_retries") utxos = wallet_service.get_utxos_by_mixdepth(include_disabled=True, - includeconfs=True) + includeconfs=True, limit_mixdepth=limit_mixdepth) for md in utxos: (enabled, disabled) = get_utxos_enabled_disabled(wallet_service, md) for u, av in utxos[md].items(): @@ -1270,7 +1271,8 @@ def output_utxos(utxos, status, start=0): disable = False if chosen_idx <= disabled_max else True return ulist[chosen_idx], disable -def get_utxos_enabled_disabled(wallet_service, md): +def get_utxos_enabled_disabled(wallet_service: WalletService, + md: int) -> Tuple[dict, dict]: """ Returns dicts for enabled and disabled separately """ utxos_enabled = wallet_service.get_utxos_at_mixdepth(md) @@ -1674,7 +1676,9 @@ def wallet_tool_main(wallet_root_path): retval = wallet_change_passphrase(wallet_service) return "Changed encryption passphrase OK" if retval else "Failed" elif method == "showutxos": - return wallet_showutxos(wallet_service, options.showprivkey) + return wallet_showutxos(wallet_service, + showprivkey=options.showprivkey, + limit_mixdepth=options.mixdepth) elif method == "showseed": return wallet_showseed(wallet_service) elif method == "dumpprivkey": diff --git a/test/jmclient/test_taker.py b/test/jmclient/test_taker.py index 7067382df..407cef0da 100644 --- a/test/jmclient/test_taker.py +++ b/test/jmclient/test_taker.py @@ -9,6 +9,7 @@ import json import struct from base64 import b64encode +from typing import Optional from jmbase import utxostr_to_utxo, hextobin from jmclient import load_test_config, jm_single, set_commitment_file,\ get_commitment_file, LegacyWallet, Taker, VolatileStorage,\ @@ -71,16 +72,20 @@ def add_extra_utxo(self, txid, index, value, md, def remove_extra_utxo(self, txid, index, md): del self.ex_utxos[(txid, index)] - def get_utxos_by_mixdepth(self, include_disabled=False, verbose=True, - includeheight=False): + def get_utxos_by_mixdepth(self, include_disabled: bool = False, + verbose: bool = True, + includeheight: bool = False, + limit_mixdepth: Optional[int] = None): # utxostr conversion routines because taker_test_data uses hex: retval = {} for mixdepth, v in t_utxos_by_mixdepth.items(): - retval[mixdepth] = {} - for i, (utxo, val) in enumerate(v.items()): - retval[mixdepth][utxostr_to_utxo(utxo)[1]] = val - val["script"] = self._ENGINE.address_to_script(val['address']) - val["path"] = (b'dummy', mixdepth, i) + if not limit_mixdepth or limit_mixdepth == mixdepth: + retval[mixdepth] = {} + for i, (utxo, val) in enumerate(v.items()): + retval[mixdepth][utxostr_to_utxo(utxo)[1]] = val + val["script"] = self._ENGINE.address_to_script( + val['address']) + val["path"] = (b'dummy', mixdepth, i) for md, u in self.ex_utxos.items(): retval[md].update(u) return retval