mmgen-swaptxcreate: check network before creating and sending TX

This commit is contained in:
The MMGen Project 2026-10-07 16:40:39 +00:00
commit 99b9081640
Signed by: mmgen
GPG key ID: 3F8B1861E32B7DA2
6 changed files with 69 additions and 4 deletions

View file

@ -175,8 +175,10 @@ async def process_tx(tx):
await tx.post_send(asi)
return 0
if tx.is_swap and not tx.check_swap_expiry():
die(1, 'Swap quote has expired. Please re-create the transaction')
if tx.is_swap:
await tx.check_swap_network()
if not tx.check_swap_expiry():
die(1, 'Swap quote has expired. Please re-create the transaction')
if not cfg.yes:
tx.info.view_with_prompt('View transaction details?')

View file

@ -13,6 +13,7 @@ swap.proto.thorchain: THORChain swap protocol implementation for the MMGen Walle
__all__ = ['SwapCfg', 'SwapAsset', 'Memo']
name = 'THORChain'
coin = 'RUNE'
exp_prec = 4
from ....util2 import ExpInt

View file

@ -243,6 +243,20 @@ class Base(MMGenObject):
x = '[unknown]'
return SwapAsset._ad(x, x, x, x, x)
async def check_swap_network(self):
from ..protocol import init_proto
from ..rpc import rpc_init
proto = init_proto(self.cfg, self.swap_proto_mod.coin, network=self.cfg.network)
rpc = await rpc_init(self.cfg, proto)
data = rpc.inbound_addrs()
for asset in (self.send_asset, self.recv_asset):
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
def token_op(self):

View file

@ -121,6 +121,8 @@ class NewSwap(New):
await parse()
await self.check_swap_network()
for asset in (self.send_asset, self.recv_asset):
if asset.name not in sa.tested:
from ..util import msg, ymsg

View file

@ -51,6 +51,12 @@ class ThornodeRPCServer(ThornodeServer):
inbounds_info = get_inbounds_info()
chain_var_actions = {
'ltc_global_paused': ('inbounds_info', 'LTC', 'global_trading_paused'),
'ltc_paused': ('inbounds_info', 'LTC', 'chain_trading_paused'),
'ltc_halted': ('inbounds_info', 'LTC', 'halted'),
'bch_halted': ('inbounds_info', 'BCH', 'halted')}
def make_response_body(self, method, environ):
class responses:

View file

@ -124,8 +124,8 @@ class CmdTestSwapMethods:
exit_val = exit_val,
no_passthru_opts = ['coin'])
def _swaptxcreate_bad(self, args, *, exit_val=1, expect1=None, expect2=None):
t = self._swaptxcreate(args, exit_val=exit_val)
def _swaptxcreate_bad(self, args, *, add_opts=[], exit_val=1, expect1=None, expect2=None):
t = self._swaptxcreate(args, add_opts=add_opts, exit_val=exit_val)
if expect1:
t.expect(expect1)
if expect2:
@ -297,6 +297,7 @@ class CmdTestSwap(
('subgroup.init_swap', []),
('subgroup.create', ['init_swap']),
('subgroup.create_bad', ['init_swap']),
('subgroup.create_neterror', ['init_swap']),
('subgroup.signsend', ['init_swap']),
('subgroup.signsend_bad', ['init_swap']),
('subgroup.autosign', ['signsend']),
@ -345,6 +346,12 @@ class CmdTestSwap(
('swaptxcreate_bad8', 'creating a swap transaction (bad, non-MMGen change address)'),
('swaptxcreate_bad9', 'creating a swap transaction (bad, invalid addrtype)'),
),
'create_neterror': (
'Swap TX create operations: network error handling',
('swaptxcreate_neterror1', 'creating a swap transaction (network error, trading paused)'),
('swaptxcreate_neterror2', 'creating a swap transaction (network error, trading for coin paused)'),
('swaptxcreate_neterror3', 'creating a swap transaction (network error, trading for coin halted)'),
),
'signsend': (
'Swap TX create, sign and send operations (LTC => BCH)',
('swaptxsign1_create', 'creating a swap transaction (full args)'),
@ -376,6 +383,8 @@ class CmdTestSwap(
('swaptxsign_bad1', 'signing the transaction (non-wallet swap address)'),
('swaptxsign_bad2_create', 'creating a swap transaction'),
('swaptxsign_bad2', 'signing the transaction'),
('swaptxsend_neterror1', 'sending the transaction (LTC swaps halted)'),
('swaptxsend_neterror2', 'sending the transaction (BCH swaps halted)'),
('swaptxsend_bad2', 'sending the transaction (swap quote expired)'),
),
'autosign': (
@ -567,6 +576,23 @@ class CmdTestSwap(
def swaptxcreate_bad9(self):
return self._swaptxcreate_bad(['BCH', '1.234', 'S', 'LTC', 'B'], exit_val=2, expect1='invalid command-')
def swaptxcreate_neterror1(self):
return self._swaptxcreate_neterror('ltc_global_paused', 'Trading is paused on the')
def swaptxcreate_neterror2(self):
return self._swaptxcreate_neterror('ltc_paused', 'Trading is paused for asset')
def swaptxcreate_neterror3(self):
return self._swaptxcreate_neterror('ltc_halted', 'Trading is halted for asset')
def _swaptxcreate_neterror(self, key, expect_str, *, add_opts=[]):
if key:
self.rpc_server.setvar(key, True)
ret = self._swaptxcreate_bad(['BCH', 'LTC'], add_opts=add_opts, exit_val=2, expect1=expect_str)
if key:
self.rpc_server.setvar(key, False)
return ret
def swaptxsign1_create(self):
return self._swaptxcreate_ui_common(
self._swaptxcreate(['LTC', '4.321', f'{self.sid}:S:2', 'BCH', f'{self.sid}:C:2']))
@ -642,6 +668,20 @@ class CmdTestSwap(
def swaptxsign_bad2(self):
return self._swaptxsign()
def swaptxsend_neterror1(self):
return self._swaptxsend_bad_neterror('ltc_halted')
def swaptxsend_neterror2(self):
return self._swaptxsend_bad_neterror('bch_halted')
def _swaptxsend_bad_neterror(self, key):
fn = self.get_file_with_ext('sigtx')
self.rpc_server.setvar(key, True)
t = self.spawn('mmgen-txsend', ['-d', self.tmpdir, '--bob', fn], exit_val=2)
t.expect('halted')
self.rpc_server.setvar(key, False)
return t
def swaptxsend_bad2(self):
fn = self.get_file_with_ext('sigtx')
with open(fn) as fh: