Browse Source

tx.new_swap: add network-estimated fee display; related cleanups

The MMGen Project 1 week ago
parent
commit
ed77c9661e

+ 8 - 5
mmgen/proto/btc/tx/new.py

@@ -54,6 +54,9 @@ class New(Base, TxNew):
 				t = fe_type))
 			self._fee_estimate_fail_warning_shown = True
 
+	def network_fee_to_unit_disp(self, net_fee):
+		return '{} sat/byte'.format(net_fee.fee.to_unit('satoshi') // 1024)
+
 	async def get_rel_fee_from_network(self):
 		try:
 			ret = await self.rpc.call(
@@ -71,22 +74,22 @@ class New(Base, TxNew):
 		if fee_per_kb is None:
 			self.warn_fee_estimate_fail(fe_type)
 
-		return fee_per_kb, fe_type
+		return self._net_fee(fee_per_kb, fe_type)
 
 	# given tx size, rel fee and units, return absolute fee
 	def fee_rel2abs(self, tx_size, amt_in_units, unit):
 		return self.proto.coin_amt(int(amt_in_units * tx_size), from_unit=unit)
 
 	# given network fee estimate in BTC/kB, return absolute fee using estimated tx size
-	def fee_est2abs(self, fee_per_kb, *, fe_type=None):
+	def fee_est2abs(self, net_fee):
 		tx_size = self.estimate_size()
-		ret = self.proto.coin_amt('1') * (fee_per_kb * self.cfg.fee_adjust * tx_size / 1024)
+		ret = self.proto.coin_amt('1') * (net_fee.fee * self.cfg.fee_adjust * tx_size / 1024)
 		if self.cfg.verbose:
 			msg(fmt(f"""
-				{fe_type.upper()} fee for {self.cfg.fee_estimate_confs} confirmations: {fee_per_kb} {self.coin}/kB
+				{net_fee.type.upper()} fee for {self.cfg.fee_estimate_confs} confirmations: {net_fee.fee} {self.coin}/kB
 				TX size (estimated): {tx_size} bytes
 				Fee adjustment factor: {self.cfg.fee_adjust:.2f}
-				Absolute fee (fee_per_kb * adj_factor * tx_size / 1024): {ret} {self.coin}
+				Absolute fee (net_fee.fee * adj_factor * tx_size / 1024): {ret} {self.coin}
 			""").strip())
 		return ret
 

+ 10 - 4
mmgen/proto/eth/tx/new.py

@@ -115,9 +115,15 @@ class New(Base, TxBase.New):
 	def network_estimated_fee_label(self):
 		return 'Network-estimated'
 
+	def network_fee_to_unit_disp(self, net_fee):
+		return '{} Gwei'.format(self.pretty_fmt_fee(
+			self.proto.coin_amt(net_fee.fee, from_unit='wei').to_unit('Gwei')))
+
 	# get rel_fee (gas price) from network, return in native wei
 	async def get_rel_fee_from_network(self):
-		return Int(await self.rpc.call('eth_gasPrice'), base=16), 'eth_gasPrice'
+		return self._net_fee(
+			Int(await self.rpc.call('eth_gasPrice'), base=16),
+			'eth_gasPrice')
 
 	def check_chg_addr_is_wallet_addr(self):
 		pass
@@ -131,10 +137,10 @@ class New(Base, TxBase.New):
 		return self.proto.coin_amt(int(amt_in_units * self.gas.toWei()), from_unit=unit)
 
 	# given fee estimate (gas price) in wei, return absolute fee, adjusting by self.cfg.fee_adjust
-	def fee_est2abs(self, rel_fee, *, fe_type=None):
-		ret = self.fee_gasPrice2abs(rel_fee) * self.cfg.fee_adjust
+	def fee_est2abs(self, net_fee):
+		ret = self.fee_gasPrice2abs(net_fee.fee) * self.cfg.fee_adjust
 		if self.cfg.verbose:
-			msg(f'Estimated fee: {ret} ETH')
+			msg(f'Estimated fee: {net_fee.fee} ETH')
 		return ret
 
 	def convert_and_check_fee(self, fee, desc):

+ 2 - 1
mmgen/swap/proto/thorchain/thornode.py

@@ -70,7 +70,7 @@ class Thornode:
 			from ....util import pp_fmt, die
 			die(2, pp_fmt(self.data))
 
-	def format_quote(self, trade_limit, usr_trade_limit, *, deduct_est_fee=False):
+	async def format_quote(self, trade_limit, usr_trade_limit, *, deduct_est_fee=False):
 		from ....util import make_timestr, ymsg
 		from ....util2 import format_elapsed_hr
 		from ....color import blue, green, cyan, pink, orange, redbg, yelbg, grnbg
@@ -137,6 +137,7 @@ class Thornode:
   Reverse rate:                  {(in_amt / out_amt).hl()} {in_coin}/{out_coin}
   Recommended minimum in amount: {min_in_amt.hl()} {in_coin}
   Recommended fee:               {pink(d['recommended_gas_rate'])} {pink(gas_unit_disp)}
+  Network-estimated fee:         {await self.tx.network_fee_disp()} (from node)
   Fees:
     Total:    {fees_t.hl()} {out_coin} ({pink(fees_pct_disp)})
     Slippage: {pink(slip_pct_disp)}

+ 1 - 1
mmgen/tx/bump.py

@@ -86,7 +86,7 @@ class Bump(Completed, NewSwap):
 		if self.is_swap:
 			self.recv_proto = self.check_swap_memo().proto
 			self.process_swap_options()
-			fee_hint = self.update_vault_output(self.send_amt)
+			fee_hint = await self.update_vault_output(self.send_amt)
 		else:
 			fee_hint = None
 

+ 11 - 4
mmgen/tx/new.py

@@ -87,6 +87,7 @@ class New(Base):
 	"""
 	chg_autoselected = False
 	_funds_available = namedtuple('funds_available', ['is_positive', 'amt'])
+	_net_fee = namedtuple('network_fee_estimate', ['fee', 'type'])
 
 	def warn_insufficient_funds(self, amt, coin):
 		msg(self.msg_insufficient_funds.format(amt.hl(), coin))
@@ -402,14 +403,20 @@ class New(Base):
 		self.copy_inputs_from_tw(sel_unspent)  # makes self.inputs
 		return True
 
+	async def network_fee_disp(self):
+		res = await self.get_rel_fee_from_network()
+		return pink(
+			'N/A' if res.fee is None else
+			self.network_fee_to_unit_disp(res))
+
 	async def get_fee(self, fee, outputs_sum, start_fee_desc):
 
 		if fee:
 			self.usr_fee = self.get_usr_fee_interactive(fee, desc=start_fee_desc)
 		else:
-			fee_per_kb, fe_type = await self.get_rel_fee_from_network()
+			res = await self.get_rel_fee_from_network()
 			self.usr_fee = self.get_usr_fee_interactive(
-				None if fee_per_kb is None else self.fee_est2abs(fee_per_kb, fe_type=fe_type),
+				None if res.fee is None else self.fee_est2abs(res),
 				desc = self.network_estimated_fee_label)
 
 		funds = await self.get_funds_available(self.usr_fee, outputs_sum)
@@ -486,7 +493,7 @@ class New(Base):
 				continue
 			fee_hint = None
 			if self.is_swap:
-				fee_hint = self.update_vault_output(
+				fee_hint = await self.update_vault_output(
 					self.vault_output.amt or self.sum_inputs(),
 					deduct_est_fee = self.vault_output == self.chg_output)
 			desc = 'User-selected' if self.cfg.fee else 'Recommended' if fee_hint else None
@@ -506,7 +513,7 @@ class New(Base):
 			self.add_comment()  # edits an existing comment
 
 		if self.is_swap:
-			self.update_vault_output(self.vault_output.amt)
+			await self.update_vault_output(self.vault_output.amt)
 
 		await self.create_serialized(locktime=locktime) # creates self.txid too
 

+ 2 - 2
mmgen/tx/new_swap.py

@@ -162,7 +162,7 @@ class NewSwap(New):
 		o['addr'] = addr
 		self.outputs[vault_idx] = self.Output(self.proto, **o)
 
-	def update_vault_output(self, amt, *, deduct_est_fee=False):
+	async def update_vault_output(self, amt, *, deduct_est_fee=False):
 		sp = get_swap_proto_mod(self.swap_proto)
 		c = sp.rpc_client(self, amt)
 
@@ -182,7 +182,7 @@ class NewSwap(New):
 			c.get_quote()
 			trade_limit = get_trade_limit()
 			self.cfg._util.qmsg('OK')
-			msg(c.format_quote(trade_limit, self.usr_trade_limit, deduct_est_fee=deduct_est_fee))
+			msg(await c.format_quote(trade_limit, self.usr_trade_limit, deduct_est_fee=deduct_est_fee))
 			ch = get_char('Press ‘r’ to refresh quote, any other key to continue: ')
 			msg('')
 			if ch not in 'Rr':