minor cleanups, variable renames, whitespace

This commit is contained in:
The MMGen Project 2026-10-05 14:30:05 +00:00
commit b2ff67b36c
Signed by: mmgen
GPG key ID: 3F8B1861E32B7DA2
6 changed files with 58 additions and 32 deletions

View file

@ -51,7 +51,7 @@ class help_notes:
return 'ADDR,AMT [addr file ...]'
def swaptxcreate_args(self):
return 'COIN1 [AMT CHG_ADDR] COIN2 [ADDR]'
return 'COIN1 [AMT CHG_ADDR] COIN2 [DEST_ADDR]'
def acct_info_desc(self):
return 'unspent outputs' if self.proto.base_proto == 'Bitcoin' else 'account info'

View file

@ -53,10 +53,10 @@ user will be presented with a list of the lowest-indexed addresses of
preferred type for each Seed ID and prompted to choose from among them.
Change and destination addresses may also be specified manually with the
CHG_ADDR and ADDR arguments. These may be given as full MMGen IDs or in the
form ADDRTYPE_CODE or SEED_ID:ADDRTYPE_CODE (see EXAMPLES below and the
‘mmgen-txcreate’ help screen for details). For Ethereum, the CHG_ADDR
argument is not supported.
CHG_ADDR and DEST_ADDR arguments. These are given either as full MMGen IDs
or in the form [SEED_ID:]ADDRTYPE_CODE, with the following exception: for
Ethereum the CHG_ADDR argument is not supported. See EXAMPLES below and the
‘mmgen-txcreate’ help screen for details.
While discouraged, sending change or swapping to non-wallet addresses is also
supported, in which case the signing script (‘mmgen-txsign’ or ‘mmgen-

View file

@ -40,7 +40,6 @@ class MoneroTwAddresses(MoneroTwView, TwAddresses):
include_empty = True
has_used = True
prompt_fs_repl = {'XMR': (
(1, 'Filters: show [E]mpty addrs, [u]sed addrs, all [L]abels'),
(3, 'Actions: [q]uit menu, add [l]abel, [N]ew acct, [n]ew addr, [R]efresh bals:'))}

View file

@ -332,7 +332,15 @@ class TwAddresses(TwView):
return e.is_used
return None # addr not in tracking wallet
def get_change_address(self, al_id, *, bot=None, top=None, exclude=None, desc=None):
def get_change_address(
self,
key_in,
*,
bot = None,
top = None,
exclude = None,
desc = None):
"""
Get lowest-indexed unused address in tracking wallet for requested AddrListID.
Return values on failure:
@ -342,20 +350,22 @@ class TwAddresses(TwView):
def get_start(bot, top):
"""
bisecting algorithm to find first entry with requested al_id
bisecting algorithm to find first entry matching requested match key
Since 'btc' > 'F' and pre_target sorts below the first twmmid of the al_id
Since 'btc' > 'F' and target sorts below the first twmmid of the match key
stringwise, we can just search on raw twmmids.
"""
pre_target = al_id + ':0'
# bisect target key sorts just below the desired target and never matches the bisect key
pre_target_key = key + ':0'
n = top >> 1
while True:
if bot == top:
return bot if data[bot].al_id == al_id else None
return bot if self.data[bot].al_id == key else None
if data[n].twmmid < pre_target:
if self.data[n].twmmid < pre_target_key:
bot = n + 1
else:
top = n
@ -365,18 +375,20 @@ class TwAddresses(TwView):
assert self.sort_key == 'twmmid'
assert self.reverse is False
data = self.data
key = key_in
start = get_start(
bot = 0 if bot is None else bot,
top = len(data) - 1 if top is None else top)
top = len(self.data) - 1 if top is None else top)
if start is not None:
for d in data[start:]:
if d.al_id == al_id:
for d in self.data[start:]:
if d.al_id == key:
if (
not d.is_used
and not d.twmmid in exclude
and (self.cfg.autochg_ignore_labels or not d.comment)
and (
self.cfg.autochg_ignore_labels or
not d.comment)
):
if d.comment:
msg('{} {} {} {}{}'.format(
@ -384,8 +396,7 @@ class TwAddresses(TwView):
d.twmmid.hl(),
yellow('has a label,'),
d.comment.hl2(encl='‘’'),
yellow(f',\n but allowing it for {desc} anyway by user request')
))
yellow(f',\n but allowing it for {desc} anyway by user request')))
return d
else:
break

View file

@ -89,6 +89,7 @@ class New(Base):
chg_autoselected = False
_funds_available = namedtuple('funds_available', ['is_positive', 'amt'])
_net_fee = namedtuple('network_fee_estimate', ['fee', 'type'])
_cl_output = namedtuple('txcreate_cmdline_output', 'arg mmid addr amt data is_vault')
def warn_insufficient_funds(self, amt, coin):
msg(self.msg_insufficient_funds.format(amt.hl(), coin))
@ -183,10 +184,8 @@ class New(Base):
def parse_cmdline_arg(self, proto, arg_in, ad_f, ad_w):
_pa = namedtuple('txcreate_cmdline_output', ['arg', 'mmid', 'addr', 'amt', 'data', 'is_vault'])
if data := self.process_data_output_arg(arg_in):
return _pa(arg_in, None, None, None, data, False)
return self._cl_output(arg_in, None, None, None, data, False)
arg, amt = arg_in.split(',', 1) if ',' in arg_in else (arg_in, None)
@ -205,13 +204,21 @@ class New(Base):
else:
die(2, f'{arg_in}: invalid command-line argument')
return _pa(arg, mmid or None, coin_addr, amt, None, is_vault)
return self._cl_output(arg, mmid or None, coin_addr, amt, None, is_vault)
async def get_autochg_addr(
self,
proto,
arg,
*,
exclude,
desc,
match_all_addrtypes = False):
async def get_autochg_addr(self, proto, arg, *, exclude, desc, all_addrtypes=False):
from ..tw.addresses import TwAddresses
al = await TwAddresses(self.cfg, proto, get_data=True)
if all_addrtypes:
if match_all_addrtypes:
res = al.get_change_address_by_addrtype(None, exclude=exclude, desc=desc)
req_desc = 'of any allowed address type'
elif obj := get_obj(MMGenAddrType, proto=proto, id_str=arg, silent=True):
@ -276,7 +283,9 @@ class New(Base):
if self.chg_output is not None:
if self.chg_autoselected and not self.is_swap: # swap TX, so user has already confirmed
self.confirm_autoselected_addr(self.chg_output.mmid, 'change address')
self.confirm_autoselected_addr(
self.chg_output.mmid,
'change address')
elif len(self.nondata_outputs) > 1:
await self.warn_addr_used(self.proto, self.chg_output, 'change address')

View file

@ -49,16 +49,21 @@ class NewSwap(New):
self.get_addrdata_from_files(proto, addrfiles),
await TwAddrData(self.cfg, proto))
if pa.addr:
await self.warn_addr_used(proto, pa, desc)
await self.warn_addr_used(proto, pa, f'{desc} address')
return ret(proto.coin, proto.network, pa.addr, pa.mmid)
full_desc = f'{desc} on the {proto.coin} {proto.network} network'
res = await self.get_autochg_addr(proto, arg, exclude=[], desc=full_desc, all_addrtypes=not arg)
full_desc = f'{desc} address on the {proto.coin} {proto.network} network'
res = await self.get_autochg_addr(
proto,
arg,
exclude = [],
desc = full_desc,
match_all_addrtypes = not arg)
self.confirm_autoselected_addr(res.twmmid, full_desc)
return ret(proto.coin, proto.network, res.addr, res.twmmid)
async def get_chg_output(self, arg, addrfiles):
chg_output = await self.get_swap_output(self.proto, arg, addrfiles, 'change address')
chg_output = await self.get_swap_output(self.proto, arg, addrfiles, 'change')
self.check_addr_is_wallet_addr(
chg_output,
message = 'Change address is not an MMGen wallet address!')
@ -97,7 +102,9 @@ class NewSwap(New):
arg = get_arg()
# arg 3: chg_spec (change address spec)
if args.send_amt and not (self.proto.is_vm or arg in sa.recv): # is change arg
if args.send_amt and not (
self.proto.is_vm or
arg in sa.recv): # is change arg
nonlocal chg_output
chg_output = await self.get_chg_output(arg, addrfiles)
arg = get_arg()
@ -136,7 +143,7 @@ class NewSwap(New):
self.recv_proto,
args.recv_spec,
addrfiles,
'destination address')
'destination')
self.check_addr_is_wallet_addr(
recv_output,