Browse Source

minor fixes and cleanups

The MMGen Project 1 week ago
parent
commit
f6aa4bad33

+ 1 - 1
mmgen/proto/btc/tx/completed.py

@@ -24,7 +24,7 @@ class Completed(Base, TxBase.Completed):
 		if o := self.data_output:
 			try:
 				return o.data.decode()
-			except:
+			except UnicodeDecodeError:
 				pass
 
 	# check signature and witness data

+ 8 - 5
mmgen/proto/eth/tx/status.py

@@ -13,7 +13,7 @@ proto.eth.tx.status: Ethereum transaction status class
 """
 
 from ....tx import status as TxBase
-from ....util import msg, die, suf, capfirst
+from ....util import msg, die, suf, capfirst, pp_fmt
 
 class Status(TxBase.Status):
 
@@ -42,11 +42,11 @@ class Status(TxBase.Status):
 			d = await tx.rpc.call('eth_getTransactionReceipt', '0x'+tx.coin_txid)
 			if d and 'blockNumber' in d and d['blockNumber'] is not None:
 				from collections import namedtuple
-				receipt_info = namedtuple('receipt_info', ['confs', 'exec_status'])
+				receipt_info = namedtuple('receipt_info', ['confs', 'exec_status', 'rx'])
 				return receipt_info(
-					confs       = 1 + int(await tx.rpc.call('eth_blockNumber'), 16) - int(d['blockNumber'], 16),
-					exec_status = int(d['status'], 16)
-				)
+					confs = 1 + int(await tx.rpc.call('eth_blockNumber'), 16) - int(d['blockNumber'], 16),
+					exec_status = int(d['status'], 16),
+					rx = d)
 
 		if await is_in_mempool():
 			msg(
@@ -56,6 +56,9 @@ class Status(TxBase.Status):
 
 		if usr_req:
 			ret = await is_in_wallet()
+			if tx.cfg.verbose:
+				from ....color import cyan
+				msg('{}\n{}'.format(cyan('TRANSACTION RECEIPT'), pp_fmt(ret.rx)))
 			if ret:
 				if tx.txobj['data']:
 					cd = capfirst(tx.contract_desc)

+ 3 - 3
mmgen/swap/proto/thorchain/thornode.py

@@ -56,7 +56,7 @@ class Thornode:
 
 	def __init__(self, tx, amt):
 		self.tx = tx
-		self.in_amt = UniAmt(str(amt))
+		self.in_amt = UniAmt(f'{amt:.8f}')
 		self.rpc = ThornodeRPCClient(tx)
 
 	def get_quote(self):
@@ -80,7 +80,7 @@ class Thornode:
 		tx = self.tx
 		in_coin = tx.proto.coin
 		out_coin = tx.recv_proto.coin
-		in_amt = UniAmt(str(self.in_amt))
+		in_amt = self.in_amt
 		out_amt = UniAmt(int(d['expected_amount_out']), from_unit='satoshi')
 		gas_unit = d['gas_rate_units']
 
@@ -110,7 +110,7 @@ class Thornode:
 		_amount_in_label = 'Amount in:'
 		if deduct_est_fee:
 			if gas_unit in gas_unit_data:
-				in_amt -= UniAmt(str(get_estimated_fee()))
+				in_amt -= UniAmt(f'{get_estimated_fee():.8f}')
 				out_amt *= (in_amt / self.in_amt)
 				_amount_in_label = 'Amount in (estimated):'
 			else:

+ 5 - 5
mmgen/tw/view.py

@@ -398,7 +398,7 @@ class TwView(MMGenObject, metaclass=AsyncInit):
 
 		def make_display():
 
-			def gen_hdr():
+			def gen_hdr(spc):
 
 				Blue, Green = (blue, green) if color else (nocolor, nocolor)
 				Yes, No, All = (green('yes'), red('no'), yellow('all')) if color else ('yes', 'no', 'all')
@@ -410,12 +410,12 @@ class TwView(MMGenObject, metaclass=AsyncInit):
 				yield '{} (sort order: {}){}'.format(
 					self.hdr_lbl.upper(),
 					Blue(sort_info),
-					' ' * (self.cols - len(f'{self.hdr_lbl} (sort order: {sort_info})')))
+					spc * (self.cols - len(f'{self.hdr_lbl} (sort order: {sort_info})')))
 
 				if self.filters:
 					yield 'Filters: {}{}'.format(
 						' '.join(map(fmt_filter, self.filters)),
-						' ' * len(self.filters))
+						spc * len(self.filters))
 
 				yield 'Network: {}'.format(Green(
 					self.proto.coin + ' ' + self.proto.chain_name.upper()))
@@ -429,7 +429,7 @@ class TwView(MMGenObject, metaclass=AsyncInit):
 
 				yield from getattr(self, dt.subhdr_fmt_method)(cw, color)
 
-				yield ' ' * self.term_width
+				yield spc * self.term_width
 
 				if data and dt.colhdr_fmt_method:
 					col_hdr = getattr(self, dt.colhdr_fmt_method)(cw, hdr_fs, color)
@@ -456,7 +456,7 @@ class TwView(MMGenObject, metaclass=AsyncInit):
 				cw = hdr_fs = fs = None
 
 			return (
-				tuple(gen_hdr()),
+				tuple(gen_hdr(spc='' if line_processing == 'print' else ' ')),
 				tuple(
 					get_body(getattr(self, dt.fmt_method)) if data else
 					[(nocolor, yellow)[color](self.nodata_msg.ljust(self.term_width))])

+ 3 - 2
mmgen/tx/info.py

@@ -74,8 +74,9 @@ class TxInfo:
 
 			if tx.is_swap:
 				from ..swap.proto.thorchain.memo import Memo, proto_name
-				if Memo.is_partial_memo(tx.data_output.data):
-					p = Memo.parse(tx.data_output.data)
+				text = tx.data_output.data.decode()
+				if Memo.is_partial_memo(text):
+					p = Memo.parse(text)
 					yield '  {} {}\n'.format(magenta('DEX Protocol:'), blue(proto_name))
 					yield '    Swap: {}\n'.format(orange(f'{tx.proto.coin} => {p.asset}'))
 					yield '    Dest: {}{}\n'.format(

+ 3 - 2
mmgen/tx/new_swap.py

@@ -55,12 +55,12 @@ class NewSwap(New):
 				proto,
 				arg,
 				self.get_addrdata_from_files(proto, addrfiles),
-				await TwAddrData(self.cfg, proto, twctl=None)) # TODO: twctl required for Ethereum
+				await TwAddrData(self.cfg, proto))
 			if pa.addr:
 				await self.warn_addr_used(proto, pa, desc)
 				return ret(proto.coin, proto.network, pa.addr, pa.mmid)
 
-		full_desc = '{} on the {} {} network'.format(desc, proto.coin, proto.network)
+		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)
 		self.confirm_autoselected_addr(res.twmmid, full_desc)
 		return ret(proto.coin, proto.network, res.addr, res.twmmid)
@@ -92,6 +92,7 @@ class NewSwap(New):
 
 			# arg 2: amt
 			if is_coin_amt(self.proto, arg):
+				UniAmt(arg) # throw exception on decimal overflow
 				args.send_amt = self.proto.coin_amt(arg)
 				arg = get_arg()
 

+ 3 - 2
pyproject.toml

@@ -97,7 +97,8 @@ mixin-class-rgx = """.*[Mm]ixin|\
 	^(Hilite|InitErrors|DummyWIF|\
 	cfg_file|cfg_file_sample|\
 	MoneroMMGenFile|keygen_base|xmr_signable|\
-	CmdTestShared)$"""
+	CmdTestShared|CmdTestSwapMethods|HTTPD|\
+	RPC|TxProxyClient|Contract)$"""
 
 ignored-classes = [ # ignored for no-member, otherwise checked
 	"optparse.Values",
@@ -133,5 +134,5 @@ ignored-classes = [ # ignored for no-member, otherwise checked
 	"Opts",
 	"Help",
 	"FFI_override",
-	"RPC",
+	"CmdGroupMgr",
 ]

+ 1 - 1
test/cmdtest_d/ct_regtest.py

@@ -64,7 +64,7 @@ pat_date_time = r'\b\d\d\d\d-\d\d-\d\d\s+\d\d:\d\d\b'
 
 dfl_wcls = get_wallet_cls('mmgen')
 
-tx_fee = rtFundAmt = rtFee = rtBals = rtBals_gb = rtBobOp3 = rtAmts = None # ruff
+tx_fee = rtFundAmt = rtFee = rtBals = rtBals_gb = rtBobOp3 = rtAmts = {} # ruff, pylint
 
 rt_data = {
 	'tx_fee': {'btc':'0.0001', 'bch':'0.001', 'ltc':'0.01'},

+ 5 - 1
test/cmdtest_d/httpd/thornode.py

@@ -24,7 +24,9 @@ cfg = Config()
 # https://thornode.ninerealms.com/thorchain/quote/swap?from_asset=BCH.BCH&to_asset=LTC.LTC&amount=1000000
 sample_request = 'GET /thorchain/quote/swap?from_asset=BCH.BCH&to_asset=LTC.LTC&amount=1000000000'
 request_pat = r'/thorchain/quote/swap\?from_asset=(\S+)\.(\S+)&to_asset=(\S+)\.(\S+)&amount=(\d+)'
-prices = { 'BTC': 97000, 'LTC': 115, 'BCH': 330 }
+prices = {'BTC': 97000, 'LTC': 115, 'BCH': 330}
+gas_rate_units = {'BTC': 'satsperbyte'}
+recommended_gas_rate = {'BTC': '6'}
 
 data_template = {
 	'inbound_address': None,
@@ -84,5 +86,7 @@ class ThornodeServer(HTTPD):
 			'expected_amount_out': str(out_amt.to_unit('satoshi')),
 			'expiry': int(time.time()) + (10 * 60),
 			'inbound_address': addr,
+			'gas_rate_units': gas_rate_units[send_proto.base_proto_coin],
+			'recommended_gas_rate': recommended_gas_rate[send_proto.base_proto_coin],
 		}
 		return json.dumps(data).encode()

+ 4 - 2
test/cmdtest_d/runner.py

@@ -148,7 +148,8 @@ class CmdTestRunner:
 		passthru_opts = (
 			self.passthru_opts if not no_passthru_opts else
 			[] if no_passthru_opts is True else
-			[o for o in self.passthru_opts if o[2:].split('=')[0] not in no_passthru_opts])
+			[o for o in self.passthru_opts
+				if o[2:].split('=')[0].replace('-','_') not in no_passthru_opts])
 
 		args = (
 			self.pre_args +
@@ -289,7 +290,8 @@ class CmdTestRunner:
 		self.passthru_opts = ['--{}{}'.format(
 				k.replace('_', '-'),
 				'' if self.cfg._uopts[k] is True else '=' + self.cfg._uopts[k]
-			) for k in self.cfg._uopts if k in self.tg.base_passthru_opts + self.tg.passthru_opts]
+			) for k in self.cfg._uopts
+				if self.cfg._uopts[k] and k in self.tg.base_passthru_opts + self.tg.passthru_opts]
 
 		if self.cfg.resuming:
 			rc = self.cfg.resume or self.cfg.resume_after