From 877be3f87754069e8eff414aaade0a4dbbfebffd Mon Sep 17 00:00:00 2001 From: The MMGen Project Date: Sun, 26 Sep 2021 21:16:54 +0000 Subject: [PATCH] test.py ethdev: support Erigon (WIP) --- mmgen/altcoins/eth/contract.py | 3 ++ mmgen/altcoins/eth/tx.py | 3 ++ mmgen/daemon.py | 8 ++-- test/test_py_d/ts_ethdev.py | 72 ++++++++++++++++++++++++++++++---- test/test_py_d/ts_shared.py | 9 ++++- 5 files changed, 82 insertions(+), 13 deletions(-) diff --git a/mmgen/altcoins/eth/contract.py b/mmgen/altcoins/eth/contract.py index 19cdde14..2e45b12a 100755 --- a/mmgen/altcoins/eth/contract.py +++ b/mmgen/altcoins/eth/contract.py @@ -53,6 +53,9 @@ class TokenBase(MMGenObject): # ERC20 if g.debug: msg('ETH_CALL {}: {}'.format(method_sig,'\n '.join(parse_abi(data)))) ret = await self.rpc.call('eth_call',{ 'to': '0x'+self.addr, 'data': '0x'+data },'pending') + if self.proto.network == 'regtest' and g.daemon_id == 'erigon': # ERIGON + import asyncio + await asyncio.sleep(5) if toUnit: return int(ret,16) * self.base_unit else: diff --git a/mmgen/altcoins/eth/tx.py b/mmgen/altcoins/eth/tx.py index 2d33077a..f52e7db6 100755 --- a/mmgen/altcoins/eth/tx.py +++ b/mmgen/altcoins/eth/tx.py @@ -468,6 +468,9 @@ class EthereumMMGenTX: else: m = 'Transaction sent: {}' assert ret == '0x'+self.coin_txid,'txid mismatch (after sending)' + if self.proto.network == 'regtest' and g.daemon_id == 'erigon': # ERIGON + import asyncio + await asyncio.sleep(5) self.desc = 'sent transaction' msg(m.format(self.coin_txid.hl())) self.add_timestamp() diff --git a/mmgen/daemon.py b/mmgen/daemon.py index 5d02e6ca..93a3585a 100755 --- a/mmgen/daemon.py +++ b/mmgen/daemon.py @@ -693,7 +693,7 @@ class geth_daemon(ethereum_daemon): # https://github.com/ledgerwatch/erigon class erigon_daemon(geth_daemon): - daemon_data = _dd('Erigon', 2021007005, '2021.07.5') + daemon_data = _dd('Erigon', 2021009005, '2021.09.5') version_pat = r'erigon/(\d+)\.(\d+)\.(\d+)' exec_fn = 'erigon' private_ports = _nw(9090,9091,9092) # testnet and regtest are non-standard @@ -708,10 +708,10 @@ class erigon_daemon(geth_daemon): [f'--port={self.p2p_port}', self.p2p_port], ['--maxpeers=0', not self.opt.online], [f'--private.api.addr=127.0.0.1:{self.private_port}'], - [f'--datadir={self.datadir}', self.non_dfl_datadir], - ['--chain=dev', self.network=='regtest'], + [f'--datadir={self.datadir}', self.non_dfl_datadir and not self.network=='regtest'], ['--chain=goerli', self.network=='testnet'], - ['--miner.etherbase=00a329c0648769a73afac7f9381e08fb43dbea72', self.network=='regtest'], + ['--chain=dev', self.network=='regtest'], + ['--mine', self.network=='regtest'], ) self.rpc_d = erigon_rpcdaemon( proto = self.proto, diff --git a/test/test_py_d/ts_ethdev.py b/test/test_py_d/ts_ethdev.py index 3cea6f7c..be090e9a 100755 --- a/test/test_py_d/ts_ethdev.py +++ b/test/test_py_d/ts_ethdev.py @@ -22,6 +22,7 @@ ts_ethdev.py: Ethdev tests for the test.py test suite import sys,os,re,shutil from decimal import Decimal +from collections import namedtuple from subprocess import run,PIPE,DEVNULL from mmgen.globalvars import g @@ -39,11 +40,17 @@ dfl_sid = '98831F3A' # The OpenEthereum dev address with lots of coins. Create with "ethkey -b info ''": dfl_devaddr = '00a329c0648769a73afac7f9381e08fb43dbea72' dfl_devkey = '4d5db4107d237df6a3d58ee5f70ae63d73d7658d4026f2eefd2f204c81682cb7' -burn_addr = 'deadbeef'*5 + +prealloc_amt = ETHAmt('1_000_000_000') + +burn_addr = 'deadbeef'*5 +burn_addr2 = 'babaeb1a'*5 + amt1 = '999999.12345689012345678' amt2 = '888.111122223333444455' parity_devkey_fn = 'parity.devkey' +erigon_devkey_fn = 'erigon.devkey' tested_solc_ver = '0.8.7' @@ -151,7 +158,9 @@ class TestSuiteEthdev(TestSuiteBase,TestSuiteShared): ('addrgen', 'generating addresses'), ('addrimport', 'importing addresses'), ('addrimport_dev_addr', "importing dev faucet address 'Ox00a329c..'"), + ('addrimport_erigon_dev_addr', 'importing Erigon dev faucet address'), + ('fund_dev_address', 'funding the default (Parity dev) address'), ('txcreate1', 'creating a transaction (spend from dev address to address :1)'), ('txview1_raw', 'viewing the raw transaction'), ('txsign1', 'signing the transaction'), @@ -316,6 +325,22 @@ class TestSuiteEthdev(TestSuiteBase,TestSuiteShared): from mmgen.daemon import CoinDaemon self.rpc_port = CoinDaemon(proto=self.proto,test_suite=True).rpc_port self.using_solc = check_solc_ver() + + write_to_file( + joinpath(self.tmpdir,parity_devkey_fn), + dfl_devkey+'\n' ) + + if g.daemon_id == 'erigon': + from hashlib import sha256 + from mmgen.tool import tool_api + devkey = sha256(b'erigon devnet key').hexdigest() + t = tool_api() + t.init_coin(g.coin,'regtest') + self.erigon_devaddr = t.wif2addr(devkey) + write_to_file( + joinpath(self.tmpdir,erigon_devkey_fn), + devkey+'\n' ) + os.environ['MMGEN_BOGUS_SEND'] = '' def __del__(self): @@ -339,7 +364,7 @@ class TestSuiteEthdev(TestSuiteBase,TestSuiteShared): self.geth_setup() if not start_test_daemons( self.proto.coin+'_rt', - remove_datadir = not g.daemon_id=='geth' ): + remove_datadir = not g.daemon_id in ('geth','erigon') ): return False from mmgen.rpc import rpc_init rpc = await rpc_init(self.proto) @@ -360,7 +385,7 @@ class TestSuiteEthdev(TestSuiteBase,TestSuiteShared): keyfile = os.path.join(keystore,os.listdir(keystore)[0]) return json.loads(open(keyfile).read())['address'] - def make_genesis(signer_addr,prealloc_addr,prealloc_amt): + def make_genesis(signer_addr,prealloc_addr): return { 'config': { 'chainId': 1337, # TODO: replace constant with var @@ -405,10 +430,9 @@ class TestSuiteEthdev(TestSuiteBase,TestSuiteShared): signer_addr = make_key(keystore) imsg(f' Signer address: {signer_addr}') - prealloc_amt = ETHAmt('1_000_000_000') imsg(f' Faucet: {dfl_devaddr} ({prealloc_amt} ETH)') - genesis_data = make_genesis(signer_addr,dfl_devaddr,prealloc_amt) + genesis_data = make_genesis(signer_addr,dfl_devaddr) genesis_fn = joinpath(self.tmpdir,'genesis.json') imsg(f' Genesis block data: {genesis_fn}') @@ -467,6 +491,11 @@ class TestSuiteEthdev(TestSuiteBase,TestSuiteShared): def addrimport_dev_addr(self): return self.addrimport_one_addr(addr=dfl_devaddr) + def addrimport_erigon_dev_addr(self): + if not g.daemon_id == 'erigon': + return 'skip' + return self.addrimport_one_addr(addr=self.erigon_devaddr) + def addrimport_burn_addr(self): return self.addrimport_one_addr(addr=burn_addr) @@ -505,7 +534,6 @@ class TestSuiteEthdev(TestSuiteBase,TestSuiteShared): def txsign(self,ni=False,ext='{}.regtest.rawtx',add_args=[]): ext = ext.format('-α' if g.debug_utf8 else '') keyfile = joinpath(self.tmpdir,parity_devkey_fn) - write_to_file(keyfile,dfl_devkey+'\n') txfile = self.get_file_with_ext(ext,no_dot=True) t = self.spawn( 'mmgen-txsign', ['--outdir={}'.format(self.tmpdir),'--coin='+self.proto.coin,'--quiet'] @@ -532,9 +560,37 @@ class TestSuiteEthdev(TestSuiteBase,TestSuiteShared): t.read() return t + def fund_dev_address(self): + """ + For Erigon, fund the default (Parity) dev address from the Erigon dev address + For the others, send a junk TX to keep block counts equal for all daemons + """ + dt = namedtuple('data',['devkey_fn','dest','amt']) + if g.daemon_id == 'erigon': + d = dt( erigon_devkey_fn, dfl_devaddr, prealloc_amt ) + else: + d = dt( parity_devkey_fn, burn_addr2, '1' ) + t = self.txcreate( + args = [ + f'--keys-from-file={joinpath(self.tmpdir,d.devkey_fn)}', + f'{d.dest},{d.amt}', + ], + menu = ['a','r'], + caller = 'txdo', + acct = '1', + no_read = True ) + self._do_confirm_send(t,quiet=not g.debug,sure=False) + t.read() + self.get_file_with_ext('sigtx',delete_all=True) + return t + def txcreate1(self): - # valid_keypresses = EthereumTwUnspentOutputs.key_mappings.keys() - menu = ['a','d','r','M','X','e','m','m'] # include one invalid keypress, 'X' + if g.daemon_id == 'erigon': + # delete Erigon devaddr so that wallet is same as for other daemons + menu = ['a','r','D','1\n','y\n'] # sort by reverse amount + else: + # include one invalid keypress 'X' -- see EthereumTwUnspentOutputs.key_mappings + menu = ['a','d','r','M','X','e','m','m'] args = ['98831F3A:E:1,123.456'] return self.txcreate(args=args,menu=menu,acct='1',tweaks=['confirm_non_mmgen']) def txview1_raw(self): diff --git a/test/test_py_d/ts_shared.py b/test/test_py_d/ts_shared.py index 65779a6c..6e33acda 100755 --- a/test/test_py_d/ts_shared.py +++ b/test/test_py_d/ts_shared.py @@ -49,8 +49,15 @@ class TestSuiteShared(object): txdo = (caller or self.test_name)[:4] == 'txdo' + expect_pat = r'\[q\]uit view, .*?:.' + delete_pat = r'Enter account number .*:.' + confirm_pat = r'Is this what you want.*:.' + pat = expect_pat for choice in menu + ['q']: - t.expect(r'\[q\]uit view, .*?:.',choice,regex=True) + t.expect(pat,choice,regex=True) + if self.proto.base_proto == 'Ethereum': + pat = confirm_pat if pat == delete_pat else delete_pat if choice == 'D' else expect_pat + if bad_input_sels: for r in ('x','3-1','9999'): t.expect(input_sels_prompt+': ',r+'\n')