cmdtest ethdev, swap, ethswap, ethbump: changes and fixes
This commit is contained in:
parent
b3bc4c5215
commit
b485d7a99a
5 changed files with 94 additions and 62 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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'):
|
||||
|
|
|
|||
|
|
@ -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')
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -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'
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue