support Rust Ethereum client (Reth)
Tested on Linux only
Testing:
$ test/cmdtest.py --coin=eth --daemon-id=reth ethdev
This commit is contained in:
parent
400054975b
commit
1e422b2c2b
25 changed files with 71 additions and 13 deletions
|
|
@ -16,6 +16,7 @@ include test/*/*.py
|
|||
include test/ref/*
|
||||
include test/ref/*/*
|
||||
include test/ref/*/*/*/*
|
||||
include test/ref/*/*/*/*/*
|
||||
include test/overlay/fakemods/mmgen/*.py
|
||||
include test/overlay/fakemods/mmgen/*/*.py
|
||||
include test/overlay/fakemods/mmgen/*/*/*/*.py
|
||||
|
|
|
|||
|
|
@ -287,7 +287,7 @@ class CoinDaemon(Daemon):
|
|||
'BCH': _cd(['bitcoin_cash_node']),
|
||||
'LTC': _cd(['litecoin_core']),
|
||||
'XMR': _cd(['monero']),
|
||||
'ETH': _cd(['geth', 'erigon', 'openethereum']),
|
||||
'ETH': _cd(['geth', 'reth', 'erigon', 'openethereum']),
|
||||
'ETC': _cd(['parity']),
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
15.1.dev18
|
||||
15.1.dev19
|
||||
|
|
|
|||
|
|
@ -113,19 +113,29 @@ class geth_daemon(ethereum_daemon):
|
|||
def init_subclass(self):
|
||||
|
||||
self.coind_args = list_gen(
|
||||
['--verbosity=0'],
|
||||
['node', self.id == 'reth'],
|
||||
['--quiet', self.id == 'reth'],
|
||||
['--verbosity=0', self.id == 'geth'],
|
||||
['--ipcdisable'], # IPC-RPC: if path to socket is longer than 108 chars, geth fails to start
|
||||
['--http'],
|
||||
['--http.api=eth,web3,txpool'],
|
||||
[f'--http.port={self.rpc_port}'],
|
||||
[f'--authrpc.port={self.authrpc_port}'],
|
||||
[f'--port={self.p2p_port}', self.p2p_port], # geth binds p2p port even with --maxpeers=0
|
||||
['--maxpeers=0', not self.opt.online],
|
||||
['--maxpeers=0', self.id == 'geth' and not self.opt.online],
|
||||
[f'--datadir={self.datadir}', self.non_dfl_datadir],
|
||||
['--holesky', self.network=='testnet'],
|
||||
['--dev', self.network=='regtest'],
|
||||
)
|
||||
|
||||
class reth_daemon(geth_daemon):
|
||||
daemon_data = _dd('Reth', 1002002, '1.2.2')
|
||||
version_pat = r'reth/v(\d+)\.(\d+)\.(\d+)'
|
||||
exec_fn = 'reth'
|
||||
datadirs = {
|
||||
'linux': [gc.home_dir, '.local', 'share', 'reth'],
|
||||
}
|
||||
|
||||
# https://github.com/ledgerwatch/erigon
|
||||
class erigon_daemon(geth_daemon):
|
||||
daemon_data = _dd('Erigon', 2022099099, '2022.99.99')
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ class mainnet(CoinProtocol.DummyWIF, CoinProtocol.Secp256k1):
|
|||
avg_bdi = 15
|
||||
decimal_prec = 36
|
||||
|
||||
# https://www.chainid.dev
|
||||
chain_ids = {
|
||||
1: 'ethereum', # ethereum mainnet
|
||||
2: 'morden', # morden testnet (deprecated)
|
||||
|
|
@ -50,6 +51,7 @@ class mainnet(CoinProtocol.DummyWIF, CoinProtocol.Secp256k1):
|
|||
17: 'developmentchain', # parity dev chain
|
||||
1337: 'developmentchain', # geth dev chain
|
||||
711: 'ethereum', # geth mainnet (empty chain)
|
||||
17000: 'holesky', # proof-of-stake testnet
|
||||
}
|
||||
|
||||
coin_cfg_opts = (
|
||||
|
|
|
|||
|
|
@ -25,6 +25,10 @@ class daemon_warning(oneshot_warning_group):
|
|||
color = 'yellow'
|
||||
message = 'Geth has not been tested on mainnet. You may experience problems.'
|
||||
|
||||
class reth:
|
||||
color = 'yellow'
|
||||
message = 'Reth has not been tested on mainnet. You may experience problems.'
|
||||
|
||||
class erigon:
|
||||
color = 'red'
|
||||
message = 'Erigon support is EXPERIMENTAL. Use at your own risk!!!'
|
||||
|
|
@ -80,7 +84,7 @@ class EthereumRPCClient(RPCClient, metaclass=AsyncInit):
|
|||
self.caps += ('full_node',)
|
||||
self.chainID = None if ci is None else Int(ci, 16) # parity/oe return chainID only for dev chain
|
||||
self.chain = (await self.call('parity_chain')).replace(' ', '_').replace('_testnet', '')
|
||||
elif self.daemon.id in ('geth', 'erigon'):
|
||||
elif self.daemon.id in ('geth', 'reth', 'erigon'):
|
||||
if self.daemon.network == 'mainnet':
|
||||
daemon_warning(self.daemon.id)
|
||||
self.caps += ('full_node',)
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ class Status(TxBase.Status):
|
|||
return False
|
||||
if tx.rpc.daemon.id in ('parity', 'openethereum'):
|
||||
pool = [x['hash'] for x in await tx.rpc.call('parity_pendingTransactions')]
|
||||
elif tx.rpc.daemon.id in ('geth', 'erigon'):
|
||||
elif tx.rpc.daemon.id in ('geth', 'reth', 'erigon'):
|
||||
res = await tx.rpc.call('txpool_content')
|
||||
pool = list(res['pending']) + list(res['queued'])
|
||||
return '0x'+tx.coin_txid in pool
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@
|
|||
test.cmdtest_d.ct_ethdev: Ethdev tests for the cmdtest.py test suite
|
||||
"""
|
||||
|
||||
import sys, os, re, shutil, asyncio, json
|
||||
import sys, time, os, re, shutil, asyncio, json
|
||||
from decimal import Decimal
|
||||
from collections import namedtuple
|
||||
from subprocess import run, PIPE, DEVNULL
|
||||
|
|
@ -66,6 +66,15 @@ dfl_sid = '98831F3A'
|
|||
dfl_devaddr = '00a329c0648769a73afac7f9381e08fb43dbea72'
|
||||
dfl_devkey = '4d5db4107d237df6a3d58ee5f70ae63d73d7658d4026f2eefd2f204c81682cb7'
|
||||
|
||||
def get_reth_dev_keypair():
|
||||
from mmgen.bip39 import bip39
|
||||
from mmgen.bip_hd import MasterNode
|
||||
mn = 'test test test test test test test test test test test junk' # See ‘reth node --help’
|
||||
seed = bip39().generate_seed(mn.split())
|
||||
m = MasterNode(cfg, seed)
|
||||
node = m.to_chain(idx=0, coin='eth').derive_private(0)
|
||||
return (node.key.hex(), node.address)
|
||||
|
||||
burn_addr = 'deadbeef'*5
|
||||
burn_addr2 = 'beadcafe'*5
|
||||
|
||||
|
|
@ -85,6 +94,16 @@ def set_vbals(daemon_id):
|
|||
vbal6 = '999904.14880104212345678'
|
||||
vbal7 = '999902.91891764212345678'
|
||||
vbal9 = '1.2262504'
|
||||
elif daemon_id == 'reth':
|
||||
vbal1 = '1.2288334'
|
||||
vbal2 = '99.996560752'
|
||||
vbal3 = '1.23142525'
|
||||
vbal3 = '1.2314176'
|
||||
vbal4 = '127.0287834'
|
||||
vbal5 = '999904.14775104212345678'
|
||||
vbal6 = '999904.14880104212345678'
|
||||
vbal7 = '999902.91891764212345678'
|
||||
vbal9 = '1.2262504'
|
||||
else:
|
||||
vbal1 = '1.2288396'
|
||||
vbal2 = '99.997088092'
|
||||
|
|
@ -409,6 +428,10 @@ class CmdTestEthdev(CmdTestBase, CmdTestShared):
|
|||
from mmgen.daemon import CoinDaemon
|
||||
self.daemon = CoinDaemon( cfg, self.proto.coin+'_rt', test_suite=True)
|
||||
|
||||
if self.daemon.id == 'reth':
|
||||
global dfl_devkey, dfl_devaddr
|
||||
dfl_devkey, dfl_devaddr = get_reth_dev_keypair()
|
||||
|
||||
set_vbals(self.daemon.id)
|
||||
|
||||
self.using_solc = check_solc_ver()
|
||||
|
|
@ -432,16 +455,21 @@ class CmdTestEthdev(CmdTestBase, CmdTestShared):
|
|||
from mmgen.rpc import rpc_init
|
||||
return await rpc_init(cfg, self.proto)
|
||||
|
||||
def mining_delay(self): # workaround for mining race condition in dev mode
|
||||
if self.daemon.id == 'reth':
|
||||
time.sleep(0.5)
|
||||
|
||||
async def setup(self):
|
||||
self.spawn('', msg_only=True)
|
||||
|
||||
d = self.daemon
|
||||
|
||||
if not self.using_solc:
|
||||
srcdir = os.path.join(self.tr.repo_root, 'test', 'ref', 'ethereum', 'bin')
|
||||
subdir = 'reth' if d.id == 'reth' else 'geth'
|
||||
srcdir = os.path.join(self.tr.repo_root, 'test', 'ref', 'ethereum', 'bin', subdir)
|
||||
from shutil import copytree
|
||||
for d in ('mm1', 'mm2'):
|
||||
copytree(os.path.join(srcdir, d), os.path.join(self.tmpdir, d))
|
||||
for _ in ('mm1', 'mm2'):
|
||||
copytree(os.path.join(srcdir, _), os.path.join(self.tmpdir, _))
|
||||
|
||||
if d.id in ('geth', 'erigon'):
|
||||
self.genesis_setup(d)
|
||||
|
|
@ -575,6 +603,8 @@ class CmdTestEthdev(CmdTestBase, CmdTestShared):
|
|||
[f'--coin={self.proto.coin}', '--regtest=1', 'eth_getBalance', '0x'+dfl_devaddr, 'latest'])
|
||||
if self.daemon.id == 'geth':
|
||||
t.expect('0x33b2e3c91ec0e9113986000')
|
||||
elif self.daemon.id == 'reth':
|
||||
t.expect('0xd3c21bcecceda1000000')
|
||||
return t
|
||||
|
||||
async def _wallet_upgrade(self, src_fn, expect1, expect2=None):
|
||||
|
|
@ -763,6 +793,7 @@ class CmdTestEthdev(CmdTestBase, CmdTestShared):
|
|||
return self.bal(n='3')
|
||||
|
||||
def tx_status(self, ext, expect_str, expect_str2='', add_args=[], exit_val=0):
|
||||
self.mining_delay()
|
||||
ext = ext.format('-α' if cfg.debug_utf8 else '')
|
||||
txfile = self.get_file_with_ext(ext, no_dot=True)
|
||||
t = self.spawn(
|
||||
|
|
@ -893,6 +924,7 @@ class CmdTestEthdev(CmdTestBase, CmdTestShared):
|
|||
return self.bal(n='5')
|
||||
|
||||
def bal(self, n):
|
||||
self.mining_delay()
|
||||
t = self.spawn('mmgen-tool', self.eth_args + ['twview', 'wide=1'])
|
||||
text = t.read(strip_color=True)
|
||||
for addr, amt in bals(n):
|
||||
|
|
@ -903,6 +935,7 @@ class CmdTestEthdev(CmdTestBase, CmdTestShared):
|
|||
return t
|
||||
|
||||
def token_bal(self, n=None):
|
||||
self.mining_delay()
|
||||
t = self.spawn('mmgen-tool', self.eth_args + ['--token=mm1', 'twview', 'wide=1'])
|
||||
text = t.read(strip_color=True)
|
||||
for addr, _amt1, _amt2 in token_bals(n):
|
||||
|
|
@ -982,8 +1015,8 @@ class CmdTestEthdev(CmdTestBase, CmdTestShared):
|
|||
return self.token_compile(token_data)
|
||||
|
||||
async def get_tx_receipt(self, txid):
|
||||
if self.daemon.id == 'geth': # yet another Geth bug
|
||||
await asyncio.sleep(0.5)
|
||||
if self.daemon.id in ('geth', 'reth'): # workaround for mining race condition in dev mode
|
||||
await asyncio.sleep(1 if self.daemon.id == 'reth' else 0.5)
|
||||
from mmgen.tx import NewTX
|
||||
tx = await NewTX(cfg=cfg, proto=self.proto, target='tx')
|
||||
tx.rpc = await self.rpc
|
||||
|
|
@ -1313,6 +1346,8 @@ class CmdTestEthdev(CmdTestBase, CmdTestShared):
|
|||
|
||||
def _txcreate_refresh_balances(self, bals, args, total, adj_total, total_coin):
|
||||
|
||||
self.mining_delay()
|
||||
|
||||
if total_coin is None:
|
||||
total_coin = self.proto.coin
|
||||
|
||||
|
|
|
|||
|
|
@ -201,7 +201,7 @@ class unit_tests:
|
|||
'rpc_port': 32323, # ignored
|
||||
'btc_tw_name': 'ignored',
|
||||
'tw_name': 'also-ignored',
|
||||
'eth_testnet_chain_names': ['goerli', 'foo', 'bar', 'baz'],
|
||||
'eth_testnet_chain_names': ['goerli', 'holesky', 'foo', 'bar', 'baz'],
|
||||
})
|
||||
|
||||
async def erigon(self, name, ut):
|
||||
|
|
|
|||
0
test/ref/ethereum/bin/reth/mm1/ERC20Interface.bin
Normal file
0
test/ref/ethereum/bin/reth/mm1/ERC20Interface.bin
Normal file
1
test/ref/ethereum/bin/reth/mm1/Owned.bin
Normal file
1
test/ref/ethereum/bin/reth/mm1/Owned.bin
Normal file
|
|
@ -0,0 +1 @@
|
|||
6080604052348015600f57600080fd5b50600080546001600160a01b031916331790556101ca806100316000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c806379ba5097146100515780638da5cb5b1461005b578063d4ee1d901461008a578063f2fde38b1461009d575b600080fd5b6100596100b0565b005b60005461006e906001600160a01b031681565b6040516001600160a01b03909116815260200160405180910390f35b60015461006e906001600160a01b031681565b6100596100ab366004610164565b61012b565b6001546001600160a01b031633146100c757600080fd5b600154600080546040516001600160a01b0393841693909116917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a360018054600080546001600160a01b03199081166001600160a01b03841617909155169055565b6000546001600160a01b0316331461014257600080fd5b600180546001600160a01b0319166001600160a01b0392909216919091179055565b60006020828403121561017657600080fd5b81356001600160a01b038116811461018d57600080fd5b939250505056fea2646970667358221220bcd3e32a06d3bc97ce1339e72449373355373643c31c80385ca5f89938aca39c64736f6c634300081a0033
|
||||
1
test/ref/ethereum/bin/reth/mm1/SafeMath.bin
Normal file
1
test/ref/ethereum/bin/reth/mm1/SafeMath.bin
Normal file
|
|
@ -0,0 +1 @@
|
|||
6080604052348015600f57600080fd5b506102018061001f6000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c8063a293d1e814610051578063b5931f7c14610076578063d05c78da14610089578063e6cb90131461009c575b600080fd5b61006461005f366004610134565b6100af565b60405190815260200160405180910390f35b610064610084366004610134565b6100cf565b610064610097366004610134565b6100e7565b6100646100aa366004610134565b610119565b6000828211156100be57600080fd5b6100c8828461016c565b9392505050565b60008082116100dd57600080fd5b6100c8828461017f565b60006100f382846101a1565b905082158061010a575081610108848361017f565b145b61011357600080fd5b92915050565b600061012582846101b8565b90508281101561011357600080fd5b6000806040838503121561014757600080fd5b50508035926020909101359150565b634e487b7160e01b600052601160045260246000fd5b8181038181111561011357610113610156565b60008261019c57634e487b7160e01b600052601260045260246000fd5b500490565b808202811582820484141761011357610113610156565b808201808211156101135761011361015656fea264697066735822122081e009254874ff32aa4fa09f9d8a315bf6a4e9e870bfb5d8b4e6611f659ed84964736f6c634300081a0033
|
||||
1
test/ref/ethereum/bin/reth/mm1/Token.bin
Normal file
1
test/ref/ethereum/bin/reth/mm1/Token.bin
Normal file
File diff suppressed because one or more lines are too long
0
test/ref/ethereum/bin/reth/mm2/ERC20Interface.bin
Normal file
0
test/ref/ethereum/bin/reth/mm2/ERC20Interface.bin
Normal file
1
test/ref/ethereum/bin/reth/mm2/Owned.bin
Normal file
1
test/ref/ethereum/bin/reth/mm2/Owned.bin
Normal file
|
|
@ -0,0 +1 @@
|
|||
6080604052348015600f57600080fd5b50600080546001600160a01b031916331790556101ca806100316000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c806379ba5097146100515780638da5cb5b1461005b578063d4ee1d901461008a578063f2fde38b1461009d575b600080fd5b6100596100b0565b005b60005461006e906001600160a01b031681565b6040516001600160a01b03909116815260200160405180910390f35b60015461006e906001600160a01b031681565b6100596100ab366004610164565b61012b565b6001546001600160a01b031633146100c757600080fd5b600154600080546040516001600160a01b0393841693909116917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a360018054600080546001600160a01b03199081166001600160a01b03841617909155169055565b6000546001600160a01b0316331461014257600080fd5b600180546001600160a01b0319166001600160a01b0392909216919091179055565b60006020828403121561017657600080fd5b81356001600160a01b038116811461018d57600080fd5b939250505056fea2646970667358221220099e0ef07629964c2926acd072d60ab552ff4e436a34052b97f44c2afb36e84664736f6c634300081a0033
|
||||
1
test/ref/ethereum/bin/reth/mm2/SafeMath.bin
Normal file
1
test/ref/ethereum/bin/reth/mm2/SafeMath.bin
Normal file
|
|
@ -0,0 +1 @@
|
|||
6080604052348015600f57600080fd5b506102018061001f6000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c8063a293d1e814610051578063b5931f7c14610076578063d05c78da14610089578063e6cb90131461009c575b600080fd5b61006461005f366004610134565b6100af565b60405190815260200160405180910390f35b610064610084366004610134565b6100cf565b610064610097366004610134565b6100e7565b6100646100aa366004610134565b610119565b6000828211156100be57600080fd5b6100c8828461016c565b9392505050565b60008082116100dd57600080fd5b6100c8828461017f565b60006100f382846101a1565b905082158061010a575081610108848361017f565b145b61011357600080fd5b92915050565b600061012582846101b8565b90508281101561011357600080fd5b6000806040838503121561014757600080fd5b50508035926020909101359150565b634e487b7160e01b600052601160045260246000fd5b8181038181111561011357610113610156565b60008261019c57634e487b7160e01b600052601260045260246000fd5b500490565b808202811582820484141761011357610113610156565b808201808211156101135761011361015656fea264697066735822122045f0003b01e5d932310b9838629204723acd115b8e8d8a25145a9d08e21cce6164736f6c634300081a0033
|
||||
1
test/ref/ethereum/bin/reth/mm2/Token.bin
Normal file
1
test/ref/ethereum/bin/reth/mm2/Token.bin
Normal file
File diff suppressed because one or more lines are too long
Loading…
Add table
Add a link
Reference in a new issue