Browse Source

Merge JoinMarket-Org/joinmarket-clientserver#1633: Implement mixdepth filtering for `showutxos`

053d8a18f2 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
master
Kristaps Kaupe 2 years ago
parent
commit
5bfa08c6f5
No known key found for this signature in database
GPG Key ID: 33E472FE870C7E5D
  1. 19
      src/jmclient/wallet.py
  2. 12
      src/jmclient/wallet_service.py
  3. 12
      src/jmclient/wallet_utils.py
  4. 19
      test/jmclient/test_taker.py

19
src/jmclient/wallet.py

@ -910,9 +910,12 @@ class BaseWallet(object):
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 @@ class BaseWallet(object):
(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,

12
src/jmclient/wallet_service.py

@ -900,12 +900,15 @@ class WalletService(Service):
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 @@ class WalletService(Service):
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:

12
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 display_utxos_for_disable_choice_default(wallet_service, utxos_enabled,
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":

19
test/jmclient/test_taker.py

@ -9,6 +9,7 @@ import pytest
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 @@ class DummyWallet(LegacyWallet):
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

Loading…
Cancel
Save