Browse Source

Ethereum swap transaction bumping

As with ordinary transactions, both fee bumping and sending funds to a new
destination are supported

For more information, see:

    $ mmgen-txbump --coin=eth --help

Testing:

    $ test/cmdtest.py --coin=eth -X bal4 ethbump
The MMGen Project 2 days ago
parent
commit
e025f2704f

+ 1 - 1
mmgen/data/version

@@ -1 +1 @@
-15.1.dev25
+15.1.dev26

+ 3 - 2
mmgen/proto/eth/tx/bump.py

@@ -16,9 +16,10 @@ from decimal import Decimal
 
 from ....tx import bump as TxBase
 from .completed import Completed, TokenCompleted
-from .new import New, TokenNew
+from .new import TokenNew
+from .new_swap import NewSwap
 
-class Bump(Completed, New, TxBase.Bump):
+class Bump(Completed, NewSwap, TxBase.Bump):
 	desc = 'fee-bumped transaction'
 
 	def get_orig_rel_fee(self):

+ 2 - 1
mmgen/proto/eth/tx/new_swap.py

@@ -21,7 +21,8 @@ class NewSwap(New, TxNewSwap):
 
 	def update_data_output(self, trade_limit):
 		sp = get_swap_proto_mod(self.swap_proto)
-		parsed_memo = sp.data.parse(self.usr_contract_data.decode())
+		data = bytes.fromhex(self.txobj['data']) if self.is_bump else self.usr_contract_data
+		parsed_memo = sp.data.parse(data.decode())
 		memo = sp.data(
 			self.recv_proto,
 			self.recv_proto.coin_addr(parsed_memo.address),

+ 98 - 0
test/cmdtest_d/ethbump.py

@@ -14,16 +14,21 @@ test.cmdtest_d.ethbump: Ethereum transaction bumping tests for the cmdtest.py te
 
 import sys, time, asyncio, json
 
+from mmgen.cfg import Config
+from mmgen.protocol import init_proto
 from mmgen.util import ymsg, suf
 
 from ..include.common import imsg, omsg_r
 
 from .include.common import cleanup_env, dfl_words_file
+from .include.runner import CmdTestRunner
+from .httpd.thornode import ThornodeServer
 
 from .ethdev import CmdTestEthdev, CmdTestEthdevMethods, dfl_sid
 from .regtest import CmdTestRegtest
 from .swap import CmdTestSwapMethods
 
+thornode_server = ThornodeServer()
 burn_addr = 'beefcafe22' * 4
 method_template = """
 def {name}(self):
@@ -116,9 +121,12 @@ class CmdTestEthBump(CmdTestEthBumpMethods, CmdTestEthdev, CmdTestSwapMethods):
 	dfl_devnet_block_period = {'geth': 7, 'reth': 9}
 
 	cmd_group_in = (
+		('subgroup.ltc_init',           []),
 		('subgroup.eth_init',           []),
 		('subgroup.feebump',            ['eth_init']),
 		('subgroup.new_outputs',        ['eth_init']),
+		('subgroup.swap_feebump',       ['ltc_init', 'eth_init']),
+		('subgroup.swap_new_outputs',   ['ltc_init', 'eth_init']),
 		('subgroup.token_init',         ['eth_init']),
 		('subgroup.token_feebump',      ['token_init']),
 		('subgroup.token_new_outputs',  ['token_init']),
@@ -137,6 +145,13 @@ class CmdTestEthBump(CmdTestEthBumpMethods, CmdTestEthdev, CmdTestSwapMethods):
 			('fund_mmgen_address3', 'spend from dev address to address :21)'),
 			('wait1',               'waiting for block'),
 		),
+		'ltc_init': (
+			'initializing LTC tracking wallet',
+			('ltc_setup',               'regtest (Bob and Alice) mode setup'),
+			('ltc_walletconv_bob',      'wallet generation (Bob)'),
+			('ltc_addrgen_bob',         'address generation (Bob)'),
+			('ltc_addrimport_bob',      'importing Bob’s addresses'),
+		),
 		'feebump': (
 			'creating, signing, sending, bumping and resending a transaction (fee-bump only)',
 			('txcreate1',   'creating a transaction (send to burn address)'),
@@ -159,6 +174,28 @@ class CmdTestEthBump(CmdTestEthBumpMethods, CmdTestEthdev, CmdTestSwapMethods):
 			('wait3',       'waiting for block'),
 			('bal2',        'checking the balance'),
 		),
+		'swap_feebump': (
+			'creating, signing, sending, bumping and resending a swap transaction (fee-bump only)',
+			('swaptxcreate1',   'creating a swap transaction (from address :11)'),
+			('swaptxsign1',     'signing the transaction'),
+			('swaptxsend1',     'sending the transaction'),
+			('swaptxbump1',     'creating a replacement swap transaction (fee-bump)'),
+			('swaptxbump1sign', 'signing the replacement transaction'),
+			('swaptxbump1send', 'sending the replacement transaction'),
+			('wait4',           'waiting for block'),
+			('bal3',            'checking the balance'),
+		),
+		'swap_new_outputs': (
+			'creating, signing, sending, bumping and resending a swap transaction (new output)',
+			('swaptxcreate2',   'creating a swap transaction (from address :21)'),
+			('swaptxsign2',     'signing the transaction'),
+			('swaptxsend2',     'sending the transaction'),
+			('swaptxbump2',     'creating a replacement swap transaction (new output)'),
+			('swaptxbump2sign', 'signing the replacement transaction'),
+			('swaptxbump2send', 'sending the replacement transaction'),
+			('wait5',           'waiting for block'),
+			('bal4',            'checking the balance'),
+		),
 		'token_init': (
 			'initializing token wallets',
 			('token_compile1',   'compiling ERC20 token #1'),
@@ -190,10 +227,32 @@ class CmdTestEthBump(CmdTestEthBumpMethods, CmdTestEthdev, CmdTestSwapMethods):
 		)
 	}
 
+	ltc_tests = [c[0] for v in tuple(cmd_subgroups.values()) + (cmd_group_in,)
+		for c in v if isinstance(c, tuple) and c[0].startswith('ltc_')]
+
+	exec(''.join(method_template.format(name=k, ltc_name=k.removeprefix('ltc_')) for k in ltc_tests))
+
 	def __init__(self, cfg, trunner, cfgs, spawn):
 
 		CmdTestEthdev.__init__(self, cfg, trunner, cfgs, spawn)
 
+		if not trunner:
+			return
+
+		global ethbump_ltc
+		cfg = Config({
+			'_clone': trunner.cfg,
+			'coin': 'ltc',
+			'resume': None,
+			'resume_after': None,
+			'exit_after': None,
+			'log': None})
+		t = trunner
+		ethbump_ltc = CmdTestRunner(cfg, t.repo_root, t.data_dir, t.trash_dir, t.trash_dir2)
+		ethbump_ltc.init_group('ethbump_ltc')
+
+		thornode_server.start()
+
 	def fund_mmgen_address1(self):
 		return self._fund_mmgen_address(arg=f'{dfl_sid}:E:1,100000')
 
@@ -215,12 +274,35 @@ class CmdTestEthBump(CmdTestEthBumpMethods, CmdTestEthdev, CmdTestSwapMethods):
 	def txbump2(self):
 		return self._txbump_new_outputs(args=[f'{dfl_sid}:E:2,777'], fee='1.3G')
 
+	def swaptxcreate1(self):
+		return self._swaptxcreate_ui_common(
+			self._swaptxcreate(['ETH', '12.34567', 'LTC', f'{dfl_sid}:B:3']),
+			inputs = 4)
+
+	def swaptxsign1(self):
+		return self._swaptxsign()
+
+	def swaptxsend1(self):
+		return self._swaptxsend()
+
+	def swaptxbump1(self):
+		return self._swaptxbump('41.1G')
+
+	def swaptxbump2(self):
+		return self._swaptxbump('1.9G', output_args=[f'{dfl_sid}:E:12,4444.3333'])
+
 	def bal1(self):
 		return self._bal_check(pat=rf'{dfl_sid}:E:1\s+99012\.9999727\s')
 
 	def bal2(self):
 		return self._bal_check(pat=rf'{dfl_sid}:E:2\s+777\s')
 
+	def bal3(self):
+		return self._bal_check(pat=rf'{dfl_sid}:E:11\s+99987\.653431389777251448\s')
+
+	def bal4(self):
+		return self._bal_check(pat=rf'{dfl_sid}:E:12\s+4444\.3333\s')
+
 	async def token_deploy_a(self):
 		return await self._token_deploy_math(num=1, get_receipt=False)
 
@@ -283,3 +365,19 @@ class CmdTestEthBump(CmdTestEthBumpMethods, CmdTestEthdev, CmdTestSwapMethods):
 
 	txsign1 = txsign2 = txbump1sign = txbump2sign = CmdTestEthBumpMethods._txsign
 	txsend1 = txsend2 = txbump1send = txbump2send = CmdTestEthBumpMethods._txsend
+
+	swaptxcreate2 = swaptxcreate1
+	swaptxsign2 = swaptxsign1
+	swaptxsend2 = swaptxsend1
+
+	swaptxbump1sign = swaptxbump2sign = token_txbump2sign
+	swaptxbump1send = swaptxbump2send = token_txbump2send
+
+class CmdTestEthBumpLTC(CmdTestRegtest, CmdTestSwapMethods):
+	network = ('ltc',)
+	tmpdir_nums = [43]
+	cmd_group_in = CmdTestRegtest.cmd_group_in + (
+		('walletconv_bob',  'LTC wallet generation'),
+		('addrgen_bob',     'LTC address generation'),
+		('addrimport_bob',  'importing LTC addresses'),
+	)

+ 2 - 0
test/cmdtest_d/include/cfg.py

@@ -49,6 +49,7 @@ cmd_groups_dfl = {
 
 cmd_groups_extra = {
 	'ethswap_eth':            ('CmdTestEthSwapEth',           {'modname': 'ethswap'}),
+	'ethbump_ltc':            ('CmdTestEthBumpLTC',           {'modname': 'ethbump'}),
 	'dev':                    ('CmdTestDev',                  {'modname': 'misc'}),
 	'regtest_legacy':         ('CmdTestRegtestBDBWallet',     {'modname': 'regtest'}),
 	'autosign_btc':           ('CmdTestAutosignBTC',          {'modname': 'autosign'}),
@@ -245,6 +246,7 @@ cfgs = { # addr_idx_lists (except 31, 32, 33, 34) must contain exactly 8 address
 	'40': {}, # cfgfile
 	'41': {}, # opts
 	'42': {}, # ethbump
+	'43': {}, # ethbump_ltc
 	'47': {}, # ethswap
 	'48': {}, # ethswap_eth
 	'49': {}, # autosign_automount