Browse Source

tx.New: exclude cmdline tx outputs from autochg result

The MMGen Project 1 year ago
parent
commit
afd2a00988
4 changed files with 24 additions and 11 deletions
  1. 1 1
      mmgen/data/version
  2. 4 3
      mmgen/tw/addresses.py
  3. 9 7
      mmgen/tx/new.py
  4. 10 0
      test/cmdtest_py_d/ct_regtest.py

+ 1 - 1
mmgen/data/version

@@ -1 +1 @@
-14.1.dev23
+14.1.dev24

+ 4 - 3
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):

+ 9 - 7
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)
 

+ 10 - 0
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',