From 226995cfc7f3b6ba4c5c5d4eb8aa07a1124aed0d Mon Sep 17 00:00:00 2001 From: The MMGen Project Date: Mon, 12 Oct 2026 10:04:48 +0000 Subject: [PATCH] tx.new_swap, tx.base, ThornodeRPCServer: minor fixes and cleanups --- mmgen/tx/base.py | 27 ++++++++++++++--------- mmgen/tx/info.py | 2 +- mmgen/tx/new_swap.py | 33 ++++++++++++++++------------ test/cmdtest_d/httpd/thornode/rpc.py | 18 +++++++-------- 4 files changed, 45 insertions(+), 35 deletions(-) diff --git a/mmgen/tx/base.py b/mmgen/tx/base.py index f3b4d375..e06b9349 100644 --- a/mmgen/tx/base.py +++ b/mmgen/tx/base.py @@ -117,7 +117,7 @@ class Base(MMGenObject): class OutputList(MMGenTxIOList): desc = 'transaction outputs' - def __init__(self, *, cfg, proto, twctl=None, **kwargs): + def __init__(self, *, cfg, proto, twctl=None, target=None, automount=None): self.cfg = cfg self.inputs = self.InputList(self) self.outputs = self.OutputList(self) @@ -126,6 +126,14 @@ class Base(MMGenObject): self.twctl = twctl self.is_token = 'Token' in self.name + @property + def data_desc(self): + def gen(): + if self.is_swap: + yield 'swap' + yield 'transaction data' + return ' '.join(gen()) + @property def coin(self): return self.proto.coin @@ -246,20 +254,19 @@ class Base(MMGenObject): else: # backwards-compatibility workaround from ..swap.asset import SwapAsset x = '[unknown]' - return SwapAsset._ad(x, x, x, x, x) + return SwapAsset._ad(x, x, x, x, x, x) def check_swap_network(self): rpc = self.swap_proto_rpc data = rpc.inbound_addrs() for asset in (self.send_asset, self.recv_asset): - if asset.name == 'RUNE': - continue - for key, state in ( - ('global_trading_paused', 'paused'), - ('chain_trading_paused', f'paused for asset {asset.name}'), - ('halted', f'halted for asset {asset.name}')): - if rpc.data_for_coin(data, asset.coin)[key]: - die(2, f'Trading is {state} on the {self.swap_proto_mod.name} network') + if asset.name != 'RUNE': + for key, state in ( + ('global_trading_paused', 'paused'), + ('chain_trading_paused', f'paused for asset {asset.name}'), + ('halted', f'halted for asset {asset.name}')): + if rpc.data_for_coin(data, asset.coin)[key]: + die(2, f'Trading is {state} on the {self.swap_proto_mod.name} network') # token methods: @property diff --git a/mmgen/tx/info.py b/mmgen/tx/info.py index 6da3b549..017ca0a1 100644 --- a/mmgen/tx/info.py +++ b/mmgen/tx/info.py @@ -49,7 +49,7 @@ class TxInfo: def gen_view(): yield (self.txinfo_hdr_fs_short if terse else self.txinfo_hdr_fs).format( - hdr = cyan(('SWAP ' if tx.is_swap else '') + 'TRANSACTION DATA'), + hdr = cyan(tx.data_desc.upper()), i = tx.txid.hl(), a = tx.send_amt.hl(), c = tx.dcoin, diff --git a/mmgen/tx/new_swap.py b/mmgen/tx/new_swap.py index d6a6ceba..c5f50568 100644 --- a/mmgen/tx/new_swap.py +++ b/mmgen/tx/new_swap.py @@ -29,18 +29,18 @@ def get_send_proto(cfg): class NewSwap(New): desc = 'swap transaction' swap_quote_refresh_timeout = 30 + _output = namedtuple('swap_output', ['coin', 'network', 'addr', 'mmid']) def __init__(self, *, cfg, **kwargs): - self.is_swap = True self.swap_proto = cfg.swap_proto - New.__init__(self, cfg=cfg, **kwargs) + self.is_swap = True + super().__init__(cfg=cfg, **kwargs) def check_addr_is_wallet_addr(self, output, *, message): if not output.mmid: self._non_wallet_addr_confirm(message) async def get_swap_output(self, proto, arg, addrfiles, desc): - ret = namedtuple('swap_output', ['coin', 'network', 'addr', 'mmid']) if arg: from ..addrdata import TwAddrData pa = self.parse_cmdline_arg( @@ -50,12 +50,12 @@ class NewSwap(New): await TwAddrData(self.cfg, proto)) if pa.addr: await self.warn_addr_used(proto, pa, f'{desc} address') - return ret(proto.coin, proto.network, pa.addr, pa.mmid) + return self._output(proto.coin, proto.network, pa.addr, pa.mmid) full_desc = f'{desc} address on the {proto.coin} {proto.network} network' res = await self.get_autochg_addr(proto, arg, exclude=[], desc=full_desc) self.confirm_autoselected_addr(res.twmmid, res.comment, full_desc) - return ret(proto.coin, proto.network, res.addr, res.twmmid) + return self._output(proto.coin, proto.network, res.addr, res.twmmid) async def get_chg_output(self, arg, addrfiles): chg_output = await self.get_swap_output(self.proto, arg, addrfiles, 'change') @@ -106,7 +106,8 @@ class NewSwap(New): arg = get_arg() # arg 4: recv_coin - self.swap_recv_asset_spec = arg # this goes into the transaction file + # this goes into the transaction file: + self.swap_recv_asset_spec = sp.SwapAsset(arg, 'recv').name # used by ‘recv_asset’ property self.recv_proto = init_swap_proto(self.cfg, self.recv_asset) # arg 5: recv_spec (receive address spec) @@ -179,12 +180,22 @@ class NewSwap(New): return tuple(ret + [f'data:{memo}']) + async def display_quote_loop(self, qd, *, deduct_est_fee=False): + from ..term import get_char + while True: + await self.display_quote(qd, 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': + break + async def display_quote(self, qd, *, deduct_est_fee=False, skip_est_fee=False): self.cfg._util.qmsg(f'Retrieving data from {qd.rpc.swap_api.host}...') qd.get_quote(self.swap_cfg) self.cfg._util.qmsg('OK') self.swap_quote_refresh_time = time.time() - await self.set_gas(to_addr=qd.router if self.is_token else None) + if not skip_est_fee: + await self.set_gas(to_addr=qd.router if self.is_token else None) msg(await qd.format_quote(deduct_est_fee=deduct_est_fee, skip_est_fee=skip_est_fee)) def update_vault_addr(self, qd, *, addr='inbound_address'): @@ -203,14 +214,8 @@ class NewSwap(New): trade_limit = trade_limit) async def update_vault_output(self, amt, *, deduct_est_fee=False): - from ..term import get_char qd = self.swap_proto_mod.quote_client(self, amt) - while True: - await self.display_quote(qd, 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': - break + await self.display_quote_loop(qd, deduct_est_fee=deduct_est_fee) self.swap_quote_expiry = qd.data['expiry'] self.update_vault_addr(qd) self.update_data_output(qd.trade_limit) diff --git a/test/cmdtest_d/httpd/thornode/rpc.py b/test/cmdtest_d/httpd/thornode/rpc.py index e05fa157..7669eae5 100644 --- a/test/cmdtest_d/httpd/thornode/rpc.py +++ b/test/cmdtest_d/httpd/thornode/rpc.py @@ -44,10 +44,11 @@ class ThornodeRPCServer(ThornodeServer): 'thorchain': 28043387}] memo_info = { - 'reference': '13579', - 'asset': 'LTC.LTC', - 'memo': '=:c:qq6myf0qd6q5tln96ntl37hq0u7940w2xvs9jsuqv0:0/3/0', - 'height': '12345678'} + '0c7454c0': { # 0c7454c06d3fc0e520d34283e6f491ce7afe5abb3f569bbdfea1732e04b716ec + 'reference': '13579', + 'asset': 'LTC.LTC', + 'memo': '=:c:qq6myf0qd6q5tln96ntl37hq0u7940w2xvs9jsuqv0:0/3/0', + 'height': '12345678'}} inbounds_info = get_inbounds_info() @@ -102,13 +103,10 @@ class ThornodeRPCServer(ThornodeServer): 'codespace': ''} def broadcast_tx_sync(m, length): + from mmgen.proto.rune.tx.protobuf import RuneTx txhex = environ['wsgi.input'].read(length).decode().removeprefix('tx=0x').upper() - res = {'code': 0, 'codespace': '', 'data': '', 'log': ''} - if txhex.startswith('0A540A52'): - res.update({'hash': '14463C716CF08A814868DB779156BCD85A1DF8EE49E924900A74482E9DEE132D'}) - elif txhex.startswith('0AC1010A'): - res.update({'hash': 'BD30B8FD9FC278A26E7A81ABB36C4709260DE64087EB578900BD23CEBF11D1A2'}) - return res + tx = RuneTx.loads(bytes.fromhex(txhex)) + return {'code': 0, 'codespace': '', 'data': '', 'log': '', 'hash': tx.txid} def ping(m, length): return self.ping_info