Skip to content

Merge ethrex-integration-pectra into main #15

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 36 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
24f8f81
Merge pull request #5 from ethpandaops/main
rodrigo-o Mar 3, 2025
be2d0e4
Add support for `ethereum_rust`.
mpaulucci Jun 11, 2024
54f3167
Remove port arg.
mpaulucci Jun 11, 2024
7e3f9cf
Rename chain to network.
mpaulucci Jun 11, 2024
4604b6a
Rename metrics_info.
mpaulucci Jun 11, 2024
05a2185
chore: rename ethereum_rust/ethereumrust -> ethrex
MegaRedHand Jun 25, 2024
34bb9f4
uncomment stuff related to genesis and kurtosis bootnodes
ricomateo Jun 27, 2024
3697ebb
chore: rename ethrex -> ethereum_rust
MegaRedHand Jul 3, 2024
7e3af36
Fix renaming issues.
mpaulucci Jul 24, 2024
12fceeb
Add datadir arg
fmoletta Aug 12, 2024
acb5b6b
pass jwt secret to client
vicentevieytes Aug 23, 2024
c5cbfba
Point to the correct repo in kurtosis.yml (needed for assertoor)
rodrigo-o Oct 23, 2024
6afa75c
Rename to ethrex
jrchatruc Nov 20, 2024
f9a9008
Rename file
jrchatruc Nov 20, 2024
5879bcd
Update ethrex integration
Feb 27, 2025
8a26540
Fix active ports
Feb 28, 2025
a58d66a
Fix labels
Feb 28, 2025
42963f5
Remove legacy config and update ethrex-launcher to support that change
Mar 5, 2025
e73f52c
Merge remote-tracking branch 'upstream/main' into ethrex-integration-…
rodrigo-o Apr 9, 2025
5b7aefb
Merge remote-tracking branch 'upstream/main' into ethrex-integration-…
rodrigo-o Apr 28, 2025
e9abded
Fixed network params usage after syncing with upstream/main (#10)
fedacking Apr 28, 2025
b90f1c0
Changed the value in the file
santiago-MV May 26, 2025
9de19db
fix in to be able to have multiple ethrex instances
santiago-MV May 26, 2025
b32a30b
Changes in to follow the defaults
santiago-MV May 26, 2025
f47c98c
Update per-pr.yml
santiago-MV May 26, 2025
a2a2533
Changes for lint
santiago-MV May 26, 2025
4879716
Update conventional-pr-title-checker.yml
santiago-MV May 26, 2025
db8f24c
Revert "Update conventional-pr-title-checker.yml"
santiago-MV May 28, 2025
369e845
Revert "Update per-pr.yml"
santiago-MV May 28, 2025
a844f83
reverting unrelated changes
santiago-MV Jun 3, 2025
ef1bd96
fix port assignment
santiago-MV Jun 3, 2025
45877ef
run lint
santiago-MV Jun 3, 2025
0428592
Removed unnecesary print
santiago-MV Jun 4, 2025
7d7864c
Merge pull request #11 from lambdaclass/fix-ethrex-container
santiago-MV Jun 4, 2025
731d7c9
Removed commented code and added enr
santiago-MV Jun 11, 2025
6509f47
Merge pull request #12 from lambdaclass/add-enr-and-clean
santiago-MV Jun 13, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion kurtosis.yml
Original file line number Diff line number Diff line change
@@ -1 +1 @@
name: "github.com/ethpandaops/ethereum-package"
name: "github.com/lambdaclass/ethereum-package"
9 changes: 8 additions & 1 deletion src/el/el_launcher.star
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ nethermind = import_module("./nethermind/nethermind_launcher.star")
reth = import_module("./reth/reth_launcher.star")
ethereumjs = import_module("./ethereumjs/ethereumjs_launcher.star")
nimbus_eth1 = import_module("./nimbus-eth1/nimbus_launcher.star")

ethrex = import_module("./ethrex/ethrex_launcher.star")

def launch(
plan,
Expand Down Expand Up @@ -90,6 +90,13 @@ def launch(
),
"launch_method": nimbus_eth1.launch,
},
constants.EL_TYPE.ethrex: {
"launcher": ethrex.new_ethrex_launcher(
el_cl_data,
jwt_file,
),
"launch_method": ethrex.launch,
},
}

all_el_contexts = []
Expand Down
255 changes: 255 additions & 0 deletions src/el/ethrex/ethrex_launcher.star
Original file line number Diff line number Diff line change
@@ -0,0 +1,255 @@
shared_utils = import_module("../../shared_utils/shared_utils.star")
input_parser = import_module("../../package_io/input_parser.star")
el_context = import_module("../../el/el_context.star")
el_admin_node_info = import_module("../../el/el_admin_node_info.star")
node_metrics = import_module("../../node_metrics_info.star")
constants = import_module("../../package_io/constants.star")
el_shared = import_module("../el_shared.star")

RPC_PORT_NUM = 8545
WS_PORT_NUM = 8546
DISCOVERY_PORT_NUM = 30303
ENGINE_RPC_PORT_NUM = 8551
METRICS_PORT_NUM = 9001

# Port IDs
RPC_PORT_ID = "rpc"
WS_PORT_ID = "ws"
TCP_DISCOVERY_PORT_ID = "tcp-discovery"
UDP_DISCOVERY_PORT_ID = "udp-discovery"
ENGINE_RPC_PORT_ID = "engine-rpc"
METRICS_PORT_ID = "metrics"

# Paths
METRICS_PATH = "/metrics"
EXECUTION_DATA_DIRPATH_ON_CLIENT_CONTAINER = "/data/ethrex/execution-data"


def get_used_ports(discovery_port):
used_ports = {
RPC_PORT_ID: shared_utils.new_port_spec(
RPC_PORT_NUM,
shared_utils.TCP_PROTOCOL,
shared_utils.HTTP_APPLICATION_PROTOCOL,
),
ENGINE_RPC_PORT_ID: shared_utils.new_port_spec(
ENGINE_RPC_PORT_NUM, shared_utils.TCP_PROTOCOL
),
}
return used_ports


ENTRYPOINT_ARGS = ["sh", "-c"]

VERBOSITY_LEVELS = {
constants.GLOBAL_LOG_LEVEL.error: "1",
constants.GLOBAL_LOG_LEVEL.warn: "2",
constants.GLOBAL_LOG_LEVEL.info: "3",
constants.GLOBAL_LOG_LEVEL.debug: "4",
constants.GLOBAL_LOG_LEVEL.trace: "5",
}


def launch(
plan,
launcher,
service_name,
participant,
global_log_level,
# If empty then the node will be launched as a bootnode
existing_el_clients,
persistent,
tolerations,
node_selectors,
port_publisher,
participant_index,
network_params,
):
image = participant.el_image
participant_log_level = participant.el_log_level
extra_params = participant.el_extra_params
extra_env_vars = participant.el_extra_env_vars
extra_labels = participant.el_extra_labels
el_volume_size = participant.el_volume_size

log_level = input_parser.get_client_log_level_or_default(
participant_log_level, global_log_level, VERBOSITY_LEVELS
)

cl_client_name = service_name.split("-")[3]

config = get_config(
plan,
launcher.el_cl_genesis_data,
launcher.jwt_file,
image,
service_name,
existing_el_clients,
cl_client_name,
log_level,
participant,
extra_params,
extra_env_vars,
extra_labels,
persistent,
el_volume_size,
tolerations,
node_selectors,
port_publisher,
participant_index,
network_params,
)

service = plan.add_service(service_name, config)

enode, enr = el_admin_node_info.get_enode_enr_for_node(plan, service_name, RPC_PORT_ID)

metric_url = "{0}:{1}".format(service.ip_address, METRICS_PORT_NUM)
metrics_info = node_metrics.new_node_metrics_info(
service_name, METRICS_PATH, metric_url
)

http_url = "http://{0}:{1}".format(service.ip_address, RPC_PORT_NUM)
ws_url = "ws://{0}:{1}".format(service.ip_address, WS_PORT_NUM)

return el_context.new_el_context(
client_name="ethrex",
enode=enode,
ip_addr=service.ip_address,
rpc_port_num=RPC_PORT_NUM,
ws_port_num=WS_PORT_NUM,
engine_rpc_port_num=ENGINE_RPC_PORT_NUM,
rpc_http_url=http_url,
ws_url=ws_url,
enr=enr,
service_name=service_name,
el_metrics_info=[metrics_info],
)


def get_config(
plan,
el_cl_genesis_data,
jwt_file,
image,
service_name,
existing_el_clients,
cl_client_name,
verbosity_level,
participant,
extra_params,
extra_env_vars,
extra_labels,
persistent,
el_volume_size,
tolerations,
node_selectors,
port_publisher,
participant_index,
network_params,
):
network = network_params.network
public_ports = {}
discovery_port = DISCOVERY_PORT_NUM
if port_publisher.el_enabled:
public_ports_for_component = shared_utils.get_public_ports_for_component(
"el", port_publisher, participant_index
)
discovery_port = public_ports_for_component[0]
public_port_assignments = {
constants.ENGINE_RPC_PORT_ID: public_ports_for_component[1],
}
public_ports = shared_utils.get_port_specs(public_port_assignments)
additional_public_port_assignments = {
constants.RPC_PORT_ID: public_ports_for_component[2],
# constants.WS_PORT_ID: public_ports_for_component[3],
# constants.METRICS_PORT_ID: public_ports_for_component[4],
}
public_ports.update(
shared_utils.get_port_specs(additional_public_port_assignments)
)
used_ports = get_used_ports(discovery_port)
cmd = [
"ethrex",
"--datadir=" + EXECUTION_DATA_DIRPATH_ON_CLIENT_CONTAINER,
"--network={0}".format(
network
if network in constants.PUBLIC_NETWORKS
else constants.GENESIS_CONFIG_MOUNT_PATH_ON_CONTAINER + "/genesis.json"
),
"--http.port={0}".format(RPC_PORT_NUM),
"--http.addr=0.0.0.0",
"--authrpc.port={0}".format(ENGINE_RPC_PORT_NUM),
"--authrpc.jwtsecret=" + constants.JWT_MOUNT_PATH_ON_CONTAINER,
"--authrpc.addr=0.0.0.0",
]
if network == constants.NETWORK_NAME.kurtosis:
if len(existing_el_clients) > 0:
cmd.append(
"--bootnodes="
+ ",".join(
[
ctx.enode
for ctx in existing_el_clients[: constants.MAX_ENODE_ENTRIES]
]
)
)
elif network not in constants.PUBLIC_NETWORKS:
cmd.append(
"--bootnodes="
+ shared_utils.get_devnet_enodes(
plan, el_cl_genesis_data.files_artifact_uuid
)
)

if len(extra_params) > 0:
# this is a repeated<proto type>, we convert it into Starlark
cmd.extend([param for param in extra_params])

cmd_str = " ".join(cmd)
if network not in constants.PUBLIC_NETWORKS:
subcommand_strs = [cmd_str]
else:
subcommand_strs = [cmd_str]

command_str = " && ".join(subcommand_strs)

files = {
constants.GENESIS_DATA_MOUNTPOINT_ON_CLIENTS: el_cl_genesis_data.files_artifact_uuid,
constants.JWT_MOUNTPOINT_ON_CLIENTS: jwt_file,
}

config_args = {
"image": image,
"ports": used_ports,
"public_ports": public_ports,
"cmd": [command_str],
"files": files,
"entrypoint": ENTRYPOINT_ARGS,
"private_ip_address_placeholder": constants.PRIVATE_IP_ADDRESS_PLACEHOLDER,
"env_vars": extra_env_vars,
"labels": shared_utils.label_maker(
constants.EL_TYPE.ethrex,
constants.CLIENT_TYPES.el,
image,
cl_client_name,
extra_labels,
),
"tolerations": tolerations,
"node_selectors": node_selectors,
}

if participant.el_min_cpu > 0:
config_args["min_cpu"] = participant.el_min_cpu
if participant.el_max_cpu > 0:
config_args["max_cpu"] = participant.el_max_cpu
if participant.el_min_mem > 0:
config_args["min_memory"] = participant.el_min_mem
if participant.el_max_mem > 0:
config_args["max_memory"] = participant.el_max_mem

return ServiceConfig(**config_args)


def new_ethrex_launcher(el_cl_genesis_data, jwt_file):
return struct(el_cl_genesis_data=el_cl_genesis_data, jwt_file=jwt_file)
1 change: 1 addition & 0 deletions src/el/geth/geth_launcher.star
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,7 @@ def get_config(
],
)
env_vars = participant.el_extra_env_vars

config_args = {
"image": participant.el_image,
"ports": used_ports,
Expand Down
15 changes: 11 additions & 4 deletions src/package_io/constants.star
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ EL_TYPE = struct(
reth_builder="reth-builder",
ethereumjs="ethereumjs",
nimbus="nimbus",
ethrex="ethrex",
)

CL_TYPE = struct(
Expand Down Expand Up @@ -202,7 +203,8 @@ VOLUME_SIZE = {
"teku_volume_size": 500000, # 500GB
"nimbus_volume_size": 500000, # 500GB
"lodestar_volume_size": 500000, # 500GB
"grandine_volume_size": 500000, # 500GB
"grandine_volume_size": 500000, # 500GB,
"ethrex_volume_size": 500000, # 500GB
},
"sepolia": {
"geth_volume_size": 300000, # 300GB
Expand All @@ -218,7 +220,8 @@ VOLUME_SIZE = {
"teku_volume_size": 150000, # 150GB
"nimbus_volume_size": 150000, # 150GB
"lodestar_volume_size": 150000, # 150GB
"grandine_volume_size": 150000, # 150GB
"grandine_volume_size": 150000, # 150GB,
"ethrex_volume_size": 150000, # 150GB
},
"holesky": {
"geth_volume_size": 100000, # 100GB
Expand All @@ -234,7 +237,8 @@ VOLUME_SIZE = {
"teku_volume_size": 100000, # 100GB
"nimbus_volume_size": 100000, # 100GB
"lodestar_volume_size": 100000, # 100GB
"grandine_volume_size": 100000, # 100GB
"grandine_volume_size": 100000, # 100GB,
"ethrex_volume_size": 100000, # 100GB
},
"devnets": {
"geth_volume_size": 100000, # 100GB
Expand All @@ -250,7 +254,8 @@ VOLUME_SIZE = {
"teku_volume_size": 100000, # 100GB
"nimbus_volume_size": 100000, # 100GB
"lodestar_volume_size": 100000, # 100GB
"grandine_volume_size": 100000, # 100GB
"grandine_volume_size": 100000, # 100GB,
"ethrex_volume_size": 100000, # 100GB
},
"ephemery": {
"geth_volume_size": 5000, # 5GB
Expand All @@ -267,6 +272,7 @@ VOLUME_SIZE = {
"nimbus_volume_size": 1000, # 1GB
"lodestar_volume_size": 1000, # 1GB
"grandine_volume_size": 1000, # 1GB
"ethrex_volume_size": 1000, # 1GB
},
"kurtosis": {
"geth_volume_size": 5000, # 5GB
Expand All @@ -283,6 +289,7 @@ VOLUME_SIZE = {
"nimbus_volume_size": 1000, # 1GB
"lodestar_volume_size": 1000, # 1GB
"grandine_volume_size": 1000, # 1GB
"ethrex_volume_size": 1000, # 1GB
},
"hoodi": {
"geth_volume_size": 100000, # 100GB
Expand Down
1 change: 1 addition & 0 deletions src/package_io/input_parser.star
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ DEFAULT_EL_IMAGES = {
"reth": "ghcr.io/paradigmxyz/reth",
"ethereumjs": "ethpandaops/ethereumjs:master",
"nimbus": "ethpandaops/nimbus-eth1:master",
"ethrex": "ethrex:latest",
}

DEFAULT_CL_IMAGES = {
Expand Down
Loading