Skip to content

Commit

Permalink
Merge #1633: Implement mixdepth filtering for showutxos
Browse files Browse the repository at this point in the history
053d8a1 Implement mixdepth filtering for showutxos (Kristaps Kaupe)

Pull request description:

  Resolves #1539. As usual, also added type hints here and there.

Top commit has no ACKs.

Tree-SHA512: a61ce96cb1c79e046c0d44289411029cae050f30349aafa886c4882d77addcd8ec84d5f8990328fb7257436779c6cca9b87e89376aedbeb3e9d61d0e6d31a4c7
  • Loading branch information
kristapsk committed Feb 23, 2024
2 parents eaae8d8 + 053d8a1 commit 5bfa08c
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 20 deletions.
19 changes: 14 additions & 5 deletions src/jmclient/wallet.py
Original file line number Diff line number Diff line change
Expand Up @@ -910,19 +910,28 @@ 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):
{'script': bytes, 'path': tuple, 'value': int}}}
(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,
Expand Down
12 changes: 8 additions & 4 deletions src/jmclient/wallet_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -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():
Expand All @@ -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:
Expand Down
12 changes: 8 additions & 4 deletions src/jmclient/wallet_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -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():
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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":
Expand Down
19 changes: 12 additions & 7 deletions test/jmclient/test_taker.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,\
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit 5bfa08c

Please sign in to comment.