Browse Source

proto.eth.tw.ctl: find unused addresses correctly

The MMGen Project 7 months ago
parent
commit
a351b16e11
3 changed files with 19 additions and 5 deletions
  1. 4 1
      mmgen/proto/eth/tw/addresses.py
  2. 12 1
      mmgen/proto/eth/tw/ctl.py
  3. 3 3
      test/cmdtest_d/ethdev.py

+ 4 - 1
mmgen/proto/eth/tw/addresses.py

@@ -13,6 +13,7 @@ proto.eth.tw.addresses: Ethereum base protocol tracking wallet address list clas
 """
 
 from ....tw.addresses import TwAddresses
+
 from .view import EthereumTwView
 from .rpc import EthereumTwRPC
 
@@ -69,13 +70,15 @@ class EthereumTwAddresses(TwAddresses, EthereumTwView, EthereumTwRPC):
 		self.minconf = None
 		addrs = {}
 
+		used_addrs = self.twctl.used_addrs
+
 		for e in await self.twctl.get_label_addr_pairs():
 			bal = await self.twctl.get_balance(e.coinaddr)
 			addrs[e.label.mmid] = {
 				'addr':  e.coinaddr,
 				'amt':   bal,
 				'recvd': bal,         # current bal only, CF btc.tw.addresses.get_rpc_data()
-				'is_used': bool(bal), # ditto
+				'is_used': bool(bal) or e.coinaddr in used_addrs,
 				'confs': 0,
 				'lbl':   e.label}
 			self.total += bal

+ 12 - 1
mmgen/proto/eth/tw/ctl.py

@@ -20,7 +20,7 @@
 proto.eth.tw.ctl: Ethereum tracking wallet control class
 """
 
-from ....util import msg, ymsg, die
+from ....util import msg, ymsg, die, cached_property
 from ....tw.ctl import TwCtl, write_mode, label_addr_pair
 from ....tw.shared import TwLabel
 from ....addr import is_coin_addr, is_mmgen_id, CoinAddr
@@ -167,6 +167,17 @@ class EthereumTwCtl(TwCtl):
 				CoinAddr(self.proto, d['addr'])
 			) for mmid, d in self.mmid_ordered_dict.items()]
 
+	# Since it’s nearly impossible to empty an Ethereum account, consider set of used addresses
+	# to be all accounts with balances.
+	# Token addresses might have a balance but no corresponding ETH balance, so check them too.
+	@cached_property
+	def used_addrs(self):
+		from decimal import Decimal
+		return (
+			{k for k, v in self.data['accounts'].items() if Decimal(v['balance'])} |
+			{k for t in self.data['tokens'].values() for k, v in t.items()
+				if Decimal(v.get('balance', 0))})
+
 class EthereumTokenTwCtl(EthereumTwCtl):
 
 	desc = 'Ethereum token tracking wallet'

+ 3 - 3
test/cmdtest_d/ethdev.py

@@ -319,7 +319,7 @@ class CmdTestEthdevMethods:
 			caller            = cmd,
 			file_desc         = 'Unsigned automount transaction')
 
-	async def _token_transfer_ops(self, *, op, mm_idxs, amt=1000, sid=dfl_sid):
+	async def _token_transfer_ops(self, *, op, mm_idxs, amt=1000, sid=dfl_sid, token_addr=None):
 		self.spawn(msg_only=True)
 		from mmgen.tool.wallet import tool_cmd
 		usr_mmaddrs = [f'{sid}:E:{i}' for i in mm_idxs]
@@ -330,7 +330,7 @@ class CmdTestEthdevMethods:
 				tk = await ResolvedToken(
 					self.cfg,
 					self.proto,
-					self.read_from_tmpfile(f'token_addr{i+1}').strip(),
+					self.read_from_tmpfile(token_addr or f'token_addr{i+1}').strip(),
 					rpc = rpc)
 				imsg_r('\n' + await tk.info())
 				imsg('dev token balance (pre-send): {}'.format(await tk.get_balance(dfl_devaddr)))
@@ -356,7 +356,7 @@ class CmdTestEthdevMethods:
 				tk = await ResolvedToken(
 					self.cfg,
 					self.proto,
-					self.read_from_tmpfile(f'token_addr{i+1}').strip(),
+					self.read_from_tmpfile(token_addr or f'token_addr{i+1}').strip(),
 					rpc = rpc)
 				imsg('Token: {}'.format(await tk.get_symbol()))
 				imsg(f'dev token balance: {await tk.get_balance(dfl_devaddr)}')