From afd2a00988e2f8404bde24f3419623d0fa1f6cc7 Mon Sep 17 00:00:00 2001 From: The MMGen Project Date: Wed, 13 Mar 2024 12:16:10 +0000 Subject: [PATCH] tx.New: exclude cmdline tx outputs from autochg result --- mmgen/data/version | 2 +- mmgen/tw/addresses.py | 7 ++++--- mmgen/tx/new.py | 16 +++++++++------- test/cmdtest_py_d/ct_regtest.py | 10 ++++++++++ 4 files changed, 24 insertions(+), 11 deletions(-) diff --git a/mmgen/data/version b/mmgen/data/version index 56012dfa..1ac202df 100644 --- a/mmgen/data/version +++ b/mmgen/data/version @@ -1 +1 @@ -14.1.dev23 +14.1.dev24 diff --git a/mmgen/tw/addresses.py b/mmgen/tw/addresses.py index d7ea97e6..7d9a9cd2 100755 --- a/mmgen/tw/addresses.py +++ b/mmgen/tw/addresses.py @@ -282,7 +282,7 @@ class TwAddresses(TwView): else: # addr not in tracking wallet return None - def get_change_address(self,al_id,bot=None,top=None): + def get_change_address(self, al_id, bot=None, top=None, exclude=None): """ Get lowest-indexed unused address in tracking wallet for requested AddrListID. Return values on failure: @@ -325,6 +325,7 @@ class TwAddresses(TwView): if d.al_id == al_id: if ( not d.recvd + and not d.twmmid in exclude and (self.cfg.autochg_ignore_labels or not d.comment) ): if d.comment: @@ -340,7 +341,7 @@ class TwAddresses(TwView): break return False - def get_change_address_by_addrtype(self,mmtype): + def get_change_address_by_addrtype(self, mmtype, exclude=None): """ Find the lowest-indexed change addresses in tracking wallet of given address type, present them in a menu and return a single change address chosen by the user. @@ -372,7 +373,7 @@ class TwAddresses(TwView): assert isinstance(mmtype,MMGenAddrType) - res = [self.get_change_address(f'{sid}:{mmtype}', r.bot, r.top) + res = [self.get_change_address(f'{sid}:{mmtype}', r.bot, r.top, exclude) for sid,r in self.sid_ranges.items()] if any(res): diff --git a/mmgen/tx/new.py b/mmgen/tx/new.py index 4f3834f0..e1602b26 100755 --- a/mmgen/tx/new.py +++ b/mmgen/tx/new.py @@ -22,6 +22,7 @@ from ..util import msg,fmt,die,suf,remove_dups,get_extension from ..addr import ( is_mmgen_id, MMGenAddrType, + MMGenID, CoinAddr, is_mmgen_addrtype, is_coin_addr, @@ -179,11 +180,11 @@ class New(Base): def parse_cmd_arg(self, arg_in, ad_f, ad_w): - _pa = namedtuple('parsed_txcreate_cmdline_arg', ['arg', 'coin_addr', 'amt']) + _pa = namedtuple('parsed_txcreate_cmdline_arg', ['arg', 'mmid', 'coin_addr', 'amt']) arg, amt = arg_in.split(',', 1) if ',' in arg_in else (arg_in, None) - if is_mmgen_id(self.proto, arg): + if mmid := get_obj(MMGenID, proto=self.proto, id_str=arg, silent=True): coin_addr = mmaddr2coinaddr(self.cfg, arg, ad_w, ad_f, self.proto) elif is_coin_addr(self.proto, arg): coin_addr = CoinAddr(self.proto, arg) @@ -195,19 +196,20 @@ class New(Base): else: die(2, f'{arg_in}: invalid command-line argument') - return _pa(arg, coin_addr, amt) + return _pa(arg, mmid, coin_addr, amt) async def process_cmd_args(self,cmd_args,ad_f,ad_w): - async def get_autochg_addr(arg): + async def get_autochg_addr(arg, parsed_args): from ..tw.addresses import TwAddresses al = await TwAddresses(self.cfg, self.proto, get_data=True) + exclude = [a.mmid for a in parsed_args if a.mmid] if is_mmgen_addrtype(self.proto, arg): - res = al.get_change_address_by_addrtype(MMGenAddrType(self.proto, arg)) + res = al.get_change_address_by_addrtype(MMGenAddrType(self.proto, arg), exclude=exclude) desc = 'of address type' else: - res = al.get_change_address(arg) + res = al.get_change_address(arg, exclude=exclude) desc = 'from address list' if res: @@ -228,7 +230,7 @@ class New(Base): for a in parsed_args: self.add_output( - coinaddr = a.coin_addr or (await get_autochg_addr(a.arg)).addr, + coinaddr = a.coin_addr or (await get_autochg_addr(a.arg, parsed_args)).addr, amt = self.proto.coin_amt(a.amt or '0'), is_chg = not a.amt) diff --git a/test/cmdtest_py_d/ct_regtest.py b/test/cmdtest_py_d/ct_regtest.py index 8d27dc88..97f71456 100755 --- a/test/cmdtest_py_d/ct_regtest.py +++ b/test/cmdtest_py_d/ct_regtest.py @@ -430,6 +430,7 @@ class CmdTestRegtest(CmdTestBase,CmdTestShared): ('bob_auto_chg_addrtype5', 'creating an auto-chg-address TX by addrtype, skipping unused address ' 'with label (C)'), ('bob_auto_chg6', 'creating an auto-chg-address TX, using unused address with label (C)'), + ('bob_auto_chg7', 'creating an automatic change address transaction (exclude cmdline output)'), ('bob_auto_chg_addrtype6', 'creating an auto-chg-address TX by addrtype, using unused address with ' 'label (C)'), ('bob_remove_comment_uua1', 'removing a comment for unused address in tracking wallet (C)'), @@ -451,6 +452,7 @@ class CmdTestRegtest(CmdTestBase,CmdTestShared): ('carol_auto_chg_addrtype1', 'creating an automatic change address transaction by addrtype (C)'), ('carol_auto_chg_addrtype2', 'creating an automatic change address transaction by addrtype (B)'), ('carol_auto_chg_addrtype3', 'creating an automatic change address transaction by addrtype (S)'), + ('carol_auto_chg_addrtype4', 'creating an automatic change address transaction by addrtype (C) (exclude cmdline output)'), ('carol_auto_chg_bad1', 'error handling for auto change address transaction (no unused addresses)'), ('carol_auto_chg_bad2', 'error handling for auto change address transaction by addrtype ' '(no unused addresses)'), @@ -1947,6 +1949,10 @@ class CmdTestRegtest(CmdTestBase,CmdTestShared): def bob_auto_chg6(self): return self._usr_auto_chg( 'bob', 'C', '3', ignore_labels=True ) + def bob_auto_chg7(self): + sid = self._user_sid('bob') + return self._usr_auto_chg( 'bob', 'S', '3', add_args=[f'{sid}:S:1,0.00345'] ) + def bob_auto_chg_addrtype6(self): return self._usr_auto_chg( 'bob', 'C', '3', True, ignore_labels=True ) @@ -2043,6 +2049,10 @@ class CmdTestRegtest(CmdTestBase,CmdTestShared): def carol_auto_chg_addrtype3(self): return self._usr_auto_chg( 'carol', 'S', '1', True ) + def carol_auto_chg_addrtype4(self): + sid = self._user_sid('bob') + return self._usr_auto_chg('carol', 'S', '3', True, add_args=[f'{sid}:S:1,0.00345']) + def carol_auto_chg_bad1(self): return self._usr_auto_chg_bad( 'carol',