From 648664ed9fbcf243a2e9d0bd935d25f406c588ff Mon Sep 17 00:00:00 2001 From: The MMGen Project Date: Mon, 19 Oct 2026 09:06:07 +0000 Subject: [PATCH] various fixes, renames and cleanups --- mmgen/cfg.py | 9 ++++--- mmgen/tw/txhistory.py | 2 +- mmgen/tw/view.py | 4 +-- mmgen/tx/new_swap.py | 15 ++++++----- test/cmdtest_d/httpd/thornode/rpc.py | 25 +++++++++---------- test/cmdtest_d/httpd/thornode/swap.py | 8 +++++- test/cmdtest_d/swap.py | 12 ++++++--- test/cmdtest_d/xmr_autosign.py | 10 ++++---- test/cmdtest_d/xmrwallet.py | 22 ++++++++-------- .../mmgen/swap/proto/thorchain/asset.py | 6 ++--- 10 files changed, 61 insertions(+), 52 deletions(-) diff --git a/mmgen/cfg.py b/mmgen/cfg.py index 6bbebbaa..91855fec 100644 --- a/mmgen/cfg.py +++ b/mmgen/cfg.py @@ -30,14 +30,15 @@ def die2(exit_val, s): sys.stderr.write(s+'\n') sys.exit(exit_val) -def fmt_opt_val(opt, val): +def fmt_opt_val(opt_in, val): + opt = opt_in.replace('_', '-') match val: case True: - return '--{}'.format(opt.replace('_', '-')) + return f'--{opt}' case False: - return '--no-{}'.format(opt.replace('_', '-')) + return f'--no-{opt}' case _: - return '--{}={}'.format(opt.replace('_', '-'), val) + return f'--{opt}={val}' class GlobalConstants(Lockable): """ diff --git a/mmgen/tw/txhistory.py b/mmgen/tw/txhistory.py index 348efccf..1745cf54 100644 --- a/mmgen/tw/txhistory.py +++ b/mmgen/tw/txhistory.py @@ -30,7 +30,7 @@ class TwTxHistory(TwView): colhdr_fmt_method = None item_separator = '\n\n' - has_wallet = False + has_twctl = False show_txid = False show_unconfirmed = False show_total_amt = False diff --git a/mmgen/tw/view.py b/mmgen/tw/view.py index eecfcad5..e05b88bd 100644 --- a/mmgen/tw/view.py +++ b/mmgen/tw/view.py @@ -81,7 +81,7 @@ class TwView(MMGenObject, metaclass=AsyncInit): is_account_based = False has_age = False has_used = False - has_wallet = True + has_twctl = True has_amt2 = False dates_set = False reverse = False @@ -200,7 +200,7 @@ class TwView(MMGenObject, metaclass=AsyncInit): self.proto = proto if have_rpc := 'rpc_init' in proto.mmcaps: self.rpc = await rpc_init(cfg, proto) - if self.has_wallet: + if self.has_twctl: from .ctl import TwCtl self.twctl = await TwCtl(cfg, proto, mode='w', no_rpc=not have_rpc) self.amt_iwidth_keys = {'amt': 'iwidth'} | ({'amt2': 'iwidth2'} if self.has_amt2 else {}) diff --git a/mmgen/tx/new_swap.py b/mmgen/tx/new_swap.py index 740386fc..f01bedd2 100644 --- a/mmgen/tx/new_swap.py +++ b/mmgen/tx/new_swap.py @@ -142,12 +142,6 @@ class NewSwap(BaseSwapMethods, New): await parse() - if self.refnum: - recv_output, parsed_ref_memo = await self.parse_network_memo( - data = self.swap_proto_rpc.validate_refnum(self.proto.coin, self.refnum), - recv_asset_spec = self.swap_recv_asset_spec, - recv_twmmid = args.recv_spec) - self.swap_cfg = self.swap_proto_mod.SwapCfg(self.cfg) if self.cfg.quote: @@ -170,7 +164,12 @@ class NewSwap(BaseSwapMethods, New): if args.send_amt and not (chg_output or self.proto.is_vm): chg_output = await self.get_chg_output(None, addrfiles) - if not self.refnum: + if self.refnum: + recv_output, parsed_ref_memo = await self.parse_network_memo( + data = self.swap_proto_rpc.validate_refnum(self.proto.coin, self.refnum), + recv_asset_spec = self.swap_recv_asset_spec, + recv_twmmid = args.recv_spec) + else: recv_output = await self.get_swap_output( self.recv_proto, args.recv_spec, @@ -210,7 +209,7 @@ class NewSwap(BaseSwapMethods, New): 'On the second pass, both amount and trade limit must remain unchanged!') from ..rpc import rpc_init if not args.send_amt: - die(1, 'With --memoless first pass, you must supply a send amount') + die(1, 'With --memoless (reference request transaction), you must supply a send amount') self.rpc = await rpc_init(self.cfg, self.proto) qd = self.swap_proto_mod.quote_client(self, args.send_amt) await self.display_quote_loop(qd, deduct_est_fee=False) diff --git a/test/cmdtest_d/httpd/thornode/rpc.py b/test/cmdtest_d/httpd/thornode/rpc.py index 52ee8790..305cf0fb 100644 --- a/test/cmdtest_d/httpd/thornode/rpc.py +++ b/test/cmdtest_d/httpd/thornode/rpc.py @@ -13,7 +13,6 @@ test.cmdtest_d.httpd.thornode.rpc: Thornode RPC HTTP server import re, json from wsgiref.util import request_uri -from mmgen.util import is_int from mmgen.cfg import Config from . import ThornodeServer @@ -125,31 +124,31 @@ class ThornodeRPCServer(ThornodeServer): return self.lastblock_info def get_refnum(m, length): - return self.memo_info[m[1].lower()[:8]] # 0c7454c0 + return self.memo_info[m[1].lower()[:8]] def validate_refnum(m, length): - mi = self.memo_info['0c7454c0'] - assert m[1] == mi['asset'] - assert m[2] == mi['reference'] - return mi + for v in self.memo_info.values(): + if v['asset'] == m[1] and v['reference'] == m[2]: + return v def validate_amt(m, length): - mi = self.memo_info['0c7454c0'] - assert m[1] == mi['asset'] - assert is_int(m[2]) - from mmgen.swap.util import get_swap_asset, init_swap_proto # pylint: disable=all from mmgen.swap.proto.thorchain.memoless import THORChainMemolessAmount # pylint: disable=all cfg = Config() swap_asset = get_swap_asset(cfg, m[1], sanitize_input=True) amt = init_swap_proto(cfg, swap_asset).coin_amt(int(m[2]), from_unit='atomic') + ma = THORChainMemolessAmount(amt) - a = THORChainMemolessAmount(amt) - assert a.refnum == int(mi['reference']), f'{a.refnum} != {int(mi["reference"])}' + for v in self.memo_info.values(): + if v['asset'] == m[1] and int(v['reference']) == ma.refnum: + mi = v + break + else: + raise ValueError(f'No reference matching asset {m[1]} and refnum {ma.refnum}') return { - 'reference': a.refnum, + 'reference': ma.refnum, 'available': True, 'can_register': True, 'expires_at': 9999999999, diff --git a/test/cmdtest_d/httpd/thornode/swap.py b/test/cmdtest_d/httpd/thornode/swap.py index 1489160c..634ea68d 100644 --- a/test/cmdtest_d/httpd/thornode/swap.py +++ b/test/cmdtest_d/httpd/thornode/swap.py @@ -21,7 +21,13 @@ from ...include.common import eth_inbound_addr, thorchain_router_addr_file from . import ThornodeServer # https://thornode.ninerealms.com/thorchain/quote/swap?from_asset=BCH.BCH&to_asset=LTC.LTC&amount=1000000 -prices = {'BTC': 97000, 'LTC': 115, 'BCH': 330, 'ETH': 2304, 'MM1': 0.998, 'RUNE': 1.4} +prices = { + 'BTC': 97000, + 'LTC': 115, + 'BCH': 330, + 'ETH': 2304, + 'MM1': 0.998, + 'RUNE': 1.4} gas_rate_units = {'ETH': 'gwei', 'BTC': 'satsperbyte'} recommended_gas_rate = {'ETH': '1', 'BTC': '6'} diff --git a/test/cmdtest_d/swap.py b/test/cmdtest_d/swap.py index b8a9ab29..92e09d5f 100644 --- a/test/cmdtest_d/swap.py +++ b/test/cmdtest_d/swap.py @@ -820,11 +820,11 @@ class CmdTestSwap( def _memoless_swaptxcreate( self, args, + opts, *, - add_opts = ['--memoless'], refreq = False, refnum = False): - t = self._swaptxcreate(args, add_opts=add_opts) + t = self._swaptxcreate(args, add_opts=opts) if refnum: return self._swaptxcreate_ui_common(t, inputs='2') if args[-1] == 'BCH': # no dest addr @@ -846,7 +846,7 @@ class CmdTestSwap( def memoless_swaptxcreate(self): return self._memoless_swaptxcreate( ['LTC', '2.345', f'{self.subsid}:B:1', 'BCH'], # no dest addr - add_opts = ['--no-refreq']) + opts = ['--no-refreq']) def rune_txcreate_refreq(self): self.get_file_with_ext('rawtx', delete_all=True) @@ -868,6 +868,7 @@ class CmdTestSwap( self.get_file_with_ext('rawtx', delete_all=True) return self._memoless_swaptxcreate( ['LTC', '2.345', f'{self.subsid}:B:1', 'BCH', f'{self.sid}:C:2'], + opts = ['--memoless'], refreq = True) refreq_swaptxsign = rune_txsign_refreq @@ -880,7 +881,10 @@ class CmdTestSwap( def _refnum_swaptxcreate(self, args, *, chg_addr=None, dest_addr=None): data = json.loads(self.read_from_tmpfile('memo_info.json')) - return self._memoless_swaptxcreate(args, add_opts=[f'--refnum={data["reference"]}'], refnum=True) + return self._memoless_swaptxcreate( + args, + opts = [f'--refnum={data["reference"]}'], + refnum = True) def refnum_swaptxcreate1(self): return self._refnum_swaptxcreate(['LTC', '2.345', f'{self.subsid}:B:1', 'BCH', f'{self.sid}:C:2']) diff --git a/test/cmdtest_d/xmr_autosign.py b/test/cmdtest_d/xmr_autosign.py index d926b5df..06a204f2 100644 --- a/test/cmdtest_d/xmr_autosign.py +++ b/test/cmdtest_d/xmr_autosign.py @@ -117,8 +117,8 @@ class CmdTestXMRAutosign(CmdTestXMRWallet, CmdTestAutosignThreaded): self.burn_addr = make_burn_addr(cfg) - self.xmrwallets_opt = f'--xmrwallets={self.users[self.user].kal_range}' self.autosign_opts = ['--autosign'] # mmgen-xmrwallet opts + self.autosign_setup_opts = [f'--xmrwallets={self.users[self.user].kal_range}'] def create_tmp_wallets(self): self.spawn(msg_only=True) @@ -216,10 +216,10 @@ class CmdTestXMRAutosign(CmdTestXMRWallet, CmdTestAutosignThreaded): return self._delete_files('.dump') def gen_kafile_miner(self): - return self.gen_kafiles(['miner']) + return self._gen_kafiles(['miner']) def gen_vkafile_user(self): - return self.gen_kafiles([self.user], add_opts=['--viewkeys']) + return self._gen_kafiles([self.user], add_opts=['--viewkeys']) def create_wallet_miner(self): return self.create_wallets_miner() @@ -246,7 +246,7 @@ class CmdTestXMRAutosign(CmdTestXMRWallet, CmdTestAutosignThreaded): mn_type = 'mmgen', mn_file = self.users[self.user].mmwords, use_dfl_wallet = None, - add_opts = [self.xmrwallets_opt], + add_opts = self.autosign_setup_opts, expect_args = ['Continue with Monero setup? (Y/n): ', 'n']) def autosign_xmr_setup_redo(self): @@ -263,7 +263,7 @@ class CmdTestXMRAutosign(CmdTestXMRWallet, CmdTestAutosignThreaded): self.insert_device() t = self.spawn( 'mmgen-autosign', - self.opts + [self.xmrwallets_opt] + ['xmr_setup'], + self.opts + self.autosign_setup_opts + ['xmr_setup'], no_passthru_opts = True) if write_viewkeys: t.written_to_file('View keys') diff --git a/test/cmdtest_d/xmrwallet.py b/test/cmdtest_d/xmrwallet.py index 7abb33a9..8e919e03 100644 --- a/test/cmdtest_d/xmrwallet.py +++ b/test/cmdtest_d/xmrwallet.py @@ -128,12 +128,12 @@ class CmdTestXMRWallet(CmdTestBase): for v in self.users.values(): run(['mkdir', '-p', v.udir]) - self.tx_relay_daemon_parm = 'localhost:{}'.format(self.users[self.tx_relay_user].md.rpc_port) - self.tx_relay_daemon_proxy_parm = ( - # must be IP, not 'localhost': - self.tx_relay_daemon_parm + f':127.0.0.1:{TestProxy.port}') - - TestProxy(self, cfg) + if self.tx_relay_user: + self.tx_relay_daemon_parm = 'localhost:{}'.format(self.users[self.tx_relay_user].md.rpc_port) + self.tx_relay_daemon_proxy_parm = ( + # must be IP, not 'localhost': + self.tx_relay_daemon_parm + f':127.0.0.1:{TestProxy.port}') + TestProxy(self, cfg) if not cfg.no_daemon_stop: atexit.register(stop_daemons, self) @@ -218,8 +218,8 @@ class CmdTestXMRWallet(CmdTestBase): test_connection = False) kafile_suf, fn_stem = ( - ('vkeys', 'MoneroWatchOnlyWallet') if autosign else - ('akeys', 'MoneroWallet')) + ('.vkeys', 'MoneroWatchOnlyWallet') if autosign else + ('.akeys', 'MoneroWallet')) self.users[user] = ud( cfg = usr_cfg, @@ -229,7 +229,7 @@ class CmdTestXMRWallet(CmdTestBase): udir = udir, twdir = wd.wallet_dir, kal_range = kal_range, - kafile = str(udir / f'{sid}-XMR-M[{kal_range}].{kafile_suf}'), + kafile = str(udir / f'{sid}-XMR-M[{kal_range}]{kafile_suf}'), walletfile_fs = str(wd.wallet_dir / f'{sid}-{{}}-{fn_stem}'), addrfile_fs = str(wd.wallet_dir / f'{sid}-{{}}-{fn_stem}.address.txt'), md = md, @@ -255,9 +255,9 @@ class CmdTestXMRWallet(CmdTestBase): return self.spawn('mmgen-tool', ['--coin=xmr', f'--rpc-port={rpc_port}', 'daemon_version']) def gen_kafiles_miner_alice(self): - return self.gen_kafiles(['miner', 'alice']) + return self._gen_kafiles(['miner', 'alice']) - def gen_kafiles(self, users, add_opts=[]): + def _gen_kafiles(self, users, add_opts=[]): for user, data in self.users.items(): if not user in users: continue diff --git a/test/overlay/fakemods/mmgen/swap/proto/thorchain/asset.py b/test/overlay/fakemods/mmgen/swap/proto/thorchain/asset.py index f505f748..ef3e0db3 100644 --- a/test/overlay/fakemods/mmgen/swap/proto/thorchain/asset.py +++ b/test/overlay/fakemods/mmgen/swap/proto/thorchain/asset.py @@ -3,9 +3,9 @@ from .asset_orig import * class overlay_fake_THORChainSwapAsset: assets_data = { - 'ETH.MM1': THORChainSwapAsset._ad('MM1 Token (ETH)', None, 'ETH.MM1', None, 18, True), - 'ETH.JUNK': THORChainSwapAsset._ad('Junk Token (ETH)', None, 'ETH.JUNK', None, 6, True), - 'ETH.NONE': THORChainSwapAsset._ad('Unavailable Token (ETH)', None, 'ETH.NONE', None, 18, True)} + 'ETH.MM1': THORChainSwapAsset._ad('MM1 Token (ETH)', None, 'ETH.MM1', None, 18, True), + 'ETH.JUNK': THORChainSwapAsset._ad('Junk Token (ETH)', None, 'ETH.JUNK', None, 6, True), + 'ETH.NONE': THORChainSwapAsset._ad('Banned Token (ETH)', None, 'ETH.NONE', None, 18, True)} evm_contracts = { 'ETH.MM1': 'deadbeefdeadbeefdeadbeefdeadbeefdeadbeef'}