diff --git a/test/cmdtest_d/ethbump.py b/test/cmdtest_d/ethbump.py index 486cc131..89cb7db5 100755 --- a/test/cmdtest_d/ethbump.py +++ b/test/cmdtest_d/ethbump.py @@ -16,14 +16,32 @@ import sys, time, asyncio, json from mmgen.util import ymsg, suf -from .ethdev import CmdTestEthdev, CmdTestEthdevMethods, dfl_sid from ..include.common import imsg, omsg_r + from .include.common import cleanup_env, dfl_words_file +from .ethdev import CmdTestEthdev, CmdTestEthdevMethods, dfl_sid +from .regtest import CmdTestRegtest +from .swap import CmdTestSwapMethods + burn_addr = 'beefcafe22' * 4 +method_template = """ +def {name}(self): + self.spawn(log_only=True) + return ethbump_ltc.run_test("{ltc_name}", sub=True) +""" class CmdTestEthBumpMethods: + def init_block_period(self): + d = self.daemon + bp = self.cfg.devnet_block_period or self.dfl_devnet_block_period[d.id] + d.usr_coind_args = { + 'reth': [f'--dev.block-time={bp}s'], + 'geth': [f'--dev.period={bp}'] + }[d.id] + self.devnet_block_period = bp + def _txcreate(self, args, acct): self.get_file_with_ext('rawtx', delete_all=True) return self.txcreate(args, acct=acct, interactive_fee='0.9G', fee_info_data=('0.0000189', '0.9')) @@ -90,32 +108,34 @@ class CmdTestEthBumpMethods: return 'ok' -class CmdTestEthBump(CmdTestEthdev, CmdTestEthdevMethods, CmdTestEthBumpMethods): +class CmdTestEthBump(CmdTestEthBumpMethods, CmdTestEthdev, CmdTestSwapMethods): 'Ethereum transaction bumping operations' networks = ('eth',) tmpdir_nums = [42] - dfl_devnet_block_period = 7 + dfl_devnet_block_period = {'geth': 7, 'reth': 9} cmd_group_in = ( - ('setup', 'dev mode transaction bumping tests for Ethereum (start daemon)'), - ('subgroup.init', []), - ('subgroup.feebump', ['init']), - ('subgroup.new_outputs', ['init']), - ('subgroup.token_init', ['init']), + ('subgroup.eth_init', []), + ('subgroup.feebump', ['eth_init']), + ('subgroup.new_outputs', ['eth_init']), + ('subgroup.token_init', ['eth_init']), ('subgroup.token_feebump', ['token_init']), ('subgroup.token_new_outputs', ['token_init']), ('stop', 'stopping daemon'), ) - cmd_subgroups = CmdTestEthdev.cmd_subgroups | { - 'init': ( - 'initializing wallets', + cmd_subgroups = { + 'eth_init': ( + 'initializing ETH tracking wallet', + ('setup', 'dev mode transaction bumping tests for Ethereum (start daemon)'), ('addrgen', 'generating addresses'), ('addrimport', 'importing addresses'), ('addrimport_dev_addr', 'importing dev faucet address ‘Ox00a329c..’'), ('fund_dev_address', 'funding the default (Parity dev) address'), - ('fund_mmgen_address', 'creating a transaction (spend from dev address to address :1)'), - ('wait2', 'waiting for block'), + ('fund_mmgen_address1', 'spend from dev address to address :1)'), + ('fund_mmgen_address2', 'spend from dev address to address :11)'), + ('fund_mmgen_address3', 'spend from dev address to address :21)'), + ('wait1', 'waiting for block'), ), 'feebump': ( 'creating, signing, sending, bumping and resending a transaction (fee-bump only)', @@ -125,7 +145,7 @@ class CmdTestEthBump(CmdTestEthdev, CmdTestEthdevMethods, CmdTestEthBumpMethods) ('txbump1', 'creating a replacement transaction (fee-bump)'), ('txbump1sign', 'signing the replacement transaction'), ('txbump1send', 'sending the replacement transaction'), - ('wait3', 'waiting for block'), + ('wait2', 'waiting for block'), ('bal1', 'checking the balance'), ), 'new_outputs': ( @@ -136,7 +156,7 @@ class CmdTestEthBump(CmdTestEthdev, CmdTestEthdevMethods, CmdTestEthBumpMethods) ('txbump2', 'creating a replacement transaction (new outputs)'), ('txbump2sign', 'signing the replacement transaction'), ('txbump2send', 'sending the replacement transaction'), - ('wait4', 'waiting for block'), + ('wait3', 'waiting for block'), ('bal2', 'checking the balance'), ), 'token_init': ( @@ -171,11 +191,17 @@ class CmdTestEthBump(CmdTestEthdev, CmdTestEthdevMethods, CmdTestEthBumpMethods) } def __init__(self, cfg, trunner, cfgs, spawn): - self.devnet_block_period = cfg.devnet_block_period or self.dfl_devnet_block_period + CmdTestEthdev.__init__(self, cfg, trunner, cfgs, spawn) - def fund_mmgen_address(self): - return self._fund_mmgen_address(arg=f'{dfl_sid}:E:1,98765.4321') + def fund_mmgen_address1(self): + return self._fund_mmgen_address(arg=f'{dfl_sid}:E:1,100000') + + def fund_mmgen_address2(self): + return self._fund_mmgen_address(arg=f'{dfl_sid}:E:11,100000') + + def fund_mmgen_address3(self): + return self._fund_mmgen_address(arg=f'{dfl_sid}:E:21,100000') def txcreate1(self): return self._txcreate(args=[f'{burn_addr},987'], acct='1') @@ -190,7 +216,7 @@ class CmdTestEthBump(CmdTestEthdev, CmdTestEthdevMethods, CmdTestEthBumpMethods) return self._txbump_new_outputs(args=[f'{dfl_sid}:E:2,777'], fee='1.3G') def bal1(self): - return self._bal_check(pat=rf'{dfl_sid}:E:1\s+97778\.4320727\s') + 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') @@ -230,7 +256,7 @@ class CmdTestEthBump(CmdTestEthdev, CmdTestEthdevMethods, CmdTestEthBumpMethods) return t def token_bal2(self): - return self._token_bal_check(pat=rf'{dfl_sid}:E:1\s+998.76544\s.*\s{dfl_sid}:E:2\s+1\.23456') + return self._token_bal_check(pat=rf'{dfl_sid}:E:2\s+1\.23456') def token_txdo2(self): return self._token_txcreate(cmd='txdo', args=[f'{dfl_sid}:E:3,5.4321', dfl_words_file]) @@ -254,5 +280,6 @@ class CmdTestEthBump(CmdTestEthdev, CmdTestEthdevMethods, CmdTestEthBumpMethods) return self._wait_for_block() if self.daemon.id == 'reth' else 'silent' wait1 = wait2 = wait3 = wait4 = wait5 = wait6 = wait7 = wait8 = CmdTestEthBumpMethods._wait_for_block + txsign1 = txsign2 = txbump1sign = txbump2sign = CmdTestEthBumpMethods._txsign txsend1 = txsend2 = txbump1send = txbump2send = CmdTestEthBumpMethods._txsend diff --git a/test/cmdtest_d/ethdev.py b/test/cmdtest_d/ethdev.py index 0c25fe77..848bacc4 100755 --- a/test/cmdtest_d/ethdev.py +++ b/test/cmdtest_d/ethdev.py @@ -26,7 +26,7 @@ from collections import namedtuple from subprocess import run, PIPE, DEVNULL from pathlib import Path -from mmgen.color import red, yellow, blue, cyan, set_vt100 +from mmgen.color import red, yellow, blue, cyan, orange, set_vt100 from mmgen.util import msg, rmsg, die from mmgen.proto.eth.misc import compute_contract_addr @@ -353,7 +353,6 @@ class CmdTestEthdev(CmdTestBase, CmdTestShared, CmdTestEthdevMethods): color = True menu_prompt = 'efresh balance:\b' input_sels_prompt = 'to spend from: ' - devnet_block_period = None bals = lambda self, k: { '1': [ ('98831F3A:E:1', '123.456')], @@ -679,7 +678,7 @@ class CmdTestEthdev(CmdTestBase, CmdTestShared, CmdTestEthdevMethods): if not self.using_solc: omsg(yellow('Using precompiled contract data')) - omsg(blue(f'Coin daemon {self.daemon.id!r} selected')) + omsg(orange(f'Coin daemon {self.daemon.id!r} selected')) self.genesis_fn = joinpath(self.tmpdir, 'genesis.json') self.keystore_dir = os.path.relpath(joinpath(self.daemon.datadir, 'keystore')) @@ -729,16 +728,16 @@ class CmdTestEthdev(CmdTestBase, CmdTestShared, CmdTestEthdevMethods): if not d.id in ('geth', 'erigon'): d.stop(silent=True) d.remove_datadir() - if d.id in ('geth', 'reth'): - if bp := self.devnet_block_period: - d.usr_coind_args = [ - f'--dev.block-time={bp}s' if d.id == 'reth' else f'--dev.period={bp}'] + self.init_block_period() d.start(silent=self.tr.quiet) rpc = await self.rpc imsg(f'Daemon: {rpc.daemon.coind_name} v{rpc.daemon_version_str}') return 'ok' + def init_block_period(self): + pass + @property def keystore_data(self): if not hasattr(self, '_keystore_data'): diff --git a/test/cmdtest_d/ethswap.py b/test/cmdtest_d/ethswap.py index 88820165..fd24a2b2 100755 --- a/test/cmdtest_d/ethswap.py +++ b/test/cmdtest_d/ethswap.py @@ -12,12 +12,11 @@ test.cmdtest_d.ethswap: Ethereum swap tests for the cmdtest.py test suite """ -from mmgen.wallet.mmgen import wallet as MMGenWallet from mmgen.cfg import Config from mmgen.protocol import init_proto from .include.runner import CmdTestRunner -from .include.common import dfl_words_file, dfl_seed_id, rt_pw +from .include.common import dfl_seed_id from .httpd.thornode import ThornodeServer from .regtest import CmdTestRegtest @@ -123,31 +122,19 @@ class CmdTestEthSwap(CmdTestRegtest, CmdTestSwapMethods): global ethswap_eth cfg = Config({ '_clone': trunner.cfg, - 'proto': init_proto(cfg, network_id='eth'), + 'coin': 'eth', + 'eth_daemon_id': trunner.cfg.eth_daemon_id, 'resume': None, 'resume_after': None, 'exit_after': None, - 'eth_daemon_id': trunner.cfg.eth_daemon_id, - 'log': None, - 'coin': 'eth'}) + 'log': None}) t = trunner ethswap_eth = CmdTestRunner(cfg, t.repo_root, t.data_dir, t.trash_dir, t.trash_dir2) ethswap_eth.init_group(self.eth_group) thornode_server.start() - def walletconv_bob(self): - t = self.spawn( - 'mmgen-walletconv', - ['--bob', '--quiet', '-r0', f'-d{self.cfg.data_dir}/regtest/bob', dfl_words_file], - no_passthru_opts = ['coin', 'eth_daemon_id']) - t.hash_preset(MMGenWallet.desc, '1') - t.passphrase_new('new '+MMGenWallet.desc, rt_pw) - t.label() - return t - def swaptxcreate1(self): - self.get_file_with_ext('rawtx', delete_all=True) t = self._swaptxcreate(['BTC', '8.765', 'ETH']) t.expect('OK? (Y/n): ', 'y') t.expect(':E:2') @@ -155,7 +142,6 @@ class CmdTestEthSwap(CmdTestRegtest, CmdTestSwapMethods): return self._swaptxcreate_ui_common(t) def swaptxcreate2(self): - self.get_file_with_ext('rawtx', delete_all=True) t = self._swaptxcreate(['BTC', '8.765', 'ETH', f'{dfl_seed_id}:E:1']) t.expect('OK? (Y/n): ', 'y') return self._swaptxcreate_ui_common(t) @@ -216,7 +202,6 @@ class CmdTestEthSwapEth(CmdTestEthdev, CmdTestSwapMethods): ) def swaptxcreate1(self): - self.get_file_with_ext('rawtx', delete_all=True) t = self._swaptxcreate(['ETH', '8.765', 'BTC']) t.expect('Continue? (Y/n):', 'y') t.expect('OK? (Y/n): ', 'y') diff --git a/test/cmdtest_d/swap.py b/test/cmdtest_d/swap.py index 71cb7bd6..f93b80bc 100755 --- a/test/cmdtest_d/swap.py +++ b/test/cmdtest_d/swap.py @@ -15,8 +15,10 @@ test.cmdtest_d.swap: asset swap tests for the cmdtest.py test suite from pathlib import Path from mmgen.protocol import init_proto +from mmgen.wallet.mmgen import wallet as MMGenWallet + from ..include.common import make_burn_addr, gr_uc -from .include.common import dfl_bip39_file +from .include.common import dfl_bip39_file, dfl_words_file from .httpd.thornode import ThornodeServer from .autosign import CmdTestAutosign, CmdTestAutosignThreaded @@ -31,6 +33,24 @@ class CmdTestSwapMethods: menu_prompt = 'abel:\b' input_sels_prompt = 'to spend: ' + @property + def bob_opt(self): + return ['--bob'] if self.proto.base_proto == 'Bitcoin' else ['--regtest=1'] + + @property + def fee_desc(self): + return 'fee or gas price' if self.proto.is_evm else 'fee' + + def walletconv_bob(self): + t = self.spawn( + 'mmgen-walletconv', + ['--bob', '--quiet', '-r0', f'-d{self.cfg.data_dir}/regtest/bob', dfl_words_file], + no_passthru_opts = ['coin', 'eth_daemon_id']) + t.hash_preset(MMGenWallet.desc, '1') + t.passphrase_new('new '+MMGenWallet.desc, rt_pw) + t.label() + return t + def _addrgen_bob(self, proto_idx, mmtypes, subseed_idx=None): return self.addrgen('bob', subseed_idx=subseed_idx, mmtypes=mmtypes, proto=self.protos[proto_idx]) @@ -133,6 +153,7 @@ class CmdTestSwapMethods: return t def _swaptxcreate(self, args, *, action='txcreate', add_opts=[], exit_val=None): + self.get_file_with_ext('rawtx', delete_all=True) return self.spawn( f'mmgen-swap{action}', ['-q', '-d', self.tmpdir, '-B', '--bob'] @@ -196,23 +217,29 @@ class CmdTestSwapMethods: fn = self.get_file_with_ext('sigtx') t = self.spawn( 'mmgen-txbump', - ['-q', '-d', self.tmpdir, '--bob'] + add_opts + output_args + [fn], + ['-q', '-d', self.tmpdir] + self.bob_opt + add_opts + output_args + [fn], exit_val = exit_val) return self._swaptxbump_ui_common(t, interactive_fee=fee, new_outputs=bool(output_args)) def _swaptxbump_ui_common_new_outputs(self, t, *, inputs=None, interactive_fee=None, file_desc=None): return self._swaptxbump_ui_common(t, interactive_fee=interactive_fee, new_outputs=True) - def _swaptxbump_ui_common(self, t, *, inputs=None, interactive_fee=None, file_desc=None, new_outputs=False): + def _swaptxbump_ui_common(self, t, *, + inputs = None, + interactive_fee = None, + file_desc = None, + new_outputs = False): if new_outputs: - t.expect('fee: ', interactive_fee + '\n') + if not self.proto.is_evm: + t.expect(f'{self.fee_desc}: ', interactive_fee + '\n') t.expect('(Y/n): ', 'y') # fee ok? t.expect('(Y/n): ', 'y') # change ok? else: - t.expect('ENTER for the change output): ', '\n') - t.expect('(Y/n): ', 'y') # confirm deduct from chg output + if not self.proto.is_evm: + t.expect('ENTER for the change output): ', '\n') + t.expect('(Y/n): ', 'y') # confirm deduct from chg output t.expect('to continue: ', '\n') # exit swap quote - t.expect('fee: ', interactive_fee + '\n') + t.expect(f'{self.fee_desc}: ', interactive_fee + '\n') t.expect('(Y/n): ', 'y') # fee ok? t.expect('(y/N): ', 'n') # comment? t.expect('(y/N): ', 'y') # save? @@ -222,6 +249,7 @@ class CmdTestSwapMethods: return self.generate(num_blocks=1, add_opts=[f'--coin={self.protos[proto_idx].coin}']) def _swaptxsign_bad(self, expect, *, add_opts=[], exit_val=1): + self.get_file_with_ext('sigtx', delete_all=True) fn = self.get_file_with_ext('rawtx') t = self.spawn('mmgen-txsign', add_opts + ['-d', self.tmpdir, '--bob', fn], exit_val=exit_val) t.expect('view: ', '\n') @@ -596,7 +624,6 @@ class CmdTestSwap(CmdTestRegtest, CmdTestAutosignThreaded, CmdTestSwapMethods): return self._swaptxcreate_bad(['BCH', '1.234', 'S', 'LTC', 'B'], exit_val=2, expect1='invalid command-') def swaptxsign1_create(self): - self.get_file_with_ext('rawtx', delete_all=True) return self._swaptxcreate_ui_common( self._swaptxcreate(['LTC', '4.321', f'{self.sid}:S:2', 'BCH', f'{self.sid}:C:2'])) @@ -612,7 +639,6 @@ class CmdTestSwap(CmdTestRegtest, CmdTestAutosignThreaded, CmdTestSwapMethods): return t def swaptxsign2_create(self): - self.get_file_with_ext('rawtx', delete_all=True) addr = make_burn_addr(self.protos[2], mmtype='compressed') t = self._swaptxcreate(['LTC', '4.56789', f'{self.sid}:S:3', 'BCH', addr]) t.expect('to confirm: ', 'YES\n') # confirm non-MMGen destination @@ -667,15 +693,12 @@ class CmdTestSwap(CmdTestRegtest, CmdTestAutosignThreaded, CmdTestSwapMethods): file_desc = 'Sent transaction') def swaptxsign_bad1_create(self): - self.get_file_with_ext('rawtx', delete_all=True) return self.swaptxcreate6() def swaptxsign_bad1(self): - self.get_file_with_ext('sigtx', delete_all=True) return self._swaptxsign_bad('non-wallet address forbidden') def swaptxsign_bad2_create(self): - self.get_file_with_ext('rawtx', delete_all=True) return self.swaptxcreate1(idx=4) def swaptxsign_bad2(self): diff --git a/test/test-release.d/cfg.sh b/test/test-release.d/cfg.sh index 1a68f1c1..62c2d5a6 100755 --- a/test/test-release.d/cfg.sh +++ b/test/test-release.d/cfg.sh @@ -245,10 +245,8 @@ init_tests() { d_eth="operations for Ethereum using devnet" t_eth=" - geth $cmdtest_py --coin=eth --daemon-id=geth ethdev - geth $cmdtest_py --coin=eth --daemon-id=geth ethbump - reth $cmdtest_py --coin=eth --daemon-id=reth ethdev - reth $cmdtest_py --coin=eth --daemon-id=reth ethbump + geth $cmdtest_py --coin=eth --eth-daemon-id=geth ethdev ethbump + reth $cmdtest_py --coin=eth --eth-daemon-id=reth ethdev ethbump " [ "$FAST" ] && t_eth_skip='reth'