Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
14 changes: 13 additions & 1 deletion src/el/reth/reth_launcher.star
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ node_metrics = import_module("../../node_metrics_info.star")
constants = import_module("../../package_io/constants.star")
mev_rs_builder = import_module("../../mev/mev-rs/mev_builder/mev_builder_launcher.star")
lighthouse = import_module("../../cl/lighthouse/lighthouse_launcher.star")
prysm = import_module("../../cl/prysm/prysm_launcher.star")
teku = import_module("../../cl/teku/teku_launcher.star")
flashbots_rbuilder = import_module(
"../../mev/flashbots/mev_builder/mev_builder_launcher.star"
)
Expand Down Expand Up @@ -289,13 +291,23 @@ def get_config(
files[
flashbots_rbuilder.MEV_BUILDER_MOUNT_DIRPATH_ON_SERVICE
] = flashbots_rbuilder.MEV_BUILDER_FILES_ARTIFACT_NAME

# Infer builder CL type from image and get correct port
# Note: Only Lighthouse, Lodestar, Prysm, and Teku are supported as builder CLs.
mev_cl_image = launcher.mev_params.mev_builder_cl_image
mev_cl_port = lighthouse.BEACON_HTTP_PORT_NUM # default
if constants.CL_TYPE.prysm in mev_cl_image:
mev_cl_port = prysm.BEACON_HTTP_PORT_NUM
elif constants.CL_TYPE.teku in mev_cl_image:
mev_cl_port = teku.BEACON_HTTP_PORT_NUM

env_vars.update(
{
"CL_ENDPOINT": "http://cl-{0}-{1}-{2}:{3}".format(
participant_index + 1,
cl_client_name,
constants.EL_TYPE.reth_builder,
lighthouse.BEACON_HTTP_PORT_NUM,
mev_cl_port,
),
}
)
Expand Down
32 changes: 30 additions & 2 deletions src/mev/flashbots/mev_builder/mev_builder_launcher.star
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ constants = import_module("../../../package_io/constants.star")
flashbots_relay = import_module("../mev_relay/mev_relay_launcher.star")
helix_relay = import_module("../../helix/helix_relay_launcher.star")
lighthouse = import_module("../../../cl/lighthouse/lighthouse_launcher.star")
prysm = import_module("../../../cl/prysm/prysm_launcher.star")
teku = import_module("../../../cl/teku/teku_launcher.star")

# MEV Builder flags

MEV_BUILDER_CONFIG_FILENAME = "config.toml"
Expand All @@ -28,6 +31,27 @@ def new_builder_config(
num_of_participants = shared_utils.zfill_custom(
len(participants), len(str(len(participants)))
)
# Infer the builder CL type from the provided image so CLEndpoint is correct
# Note: Only Lighthouse, Prysm, and Teku are supported as builder CLs.
# Lodestar, Nimbus, and Grandine have incompatible payload_attributes SSE event formats.
mev_cl_image = mev_params.mev_builder_cl_image
mev_cl_type = constants.CL_TYPE.lighthouse
for candidate in [
constants.CL_TYPE.lighthouse,
constants.CL_TYPE.prysm,
constants.CL_TYPE.teku,
]:
if candidate in mev_cl_image:
mev_cl_type = candidate
break

# Map CL type to its beacon HTTP port constant
mev_cl_port = lighthouse.BEACON_HTTP_PORT_NUM
if mev_cl_type == constants.CL_TYPE.prysm:
mev_cl_port = prysm.BEACON_HTTP_PORT_NUM
elif mev_cl_type == constants.CL_TYPE.teku:
mev_cl_port = teku.BEACON_HTTP_PORT_NUM

builder_template_data = new_builder_config_template_data(
network_params,
constants.DEFAULT_MEV_PUBKEY,
Expand All @@ -38,6 +62,8 @@ def new_builder_config(
num_of_participants,
mev_params.mev_builder_subsidy,
mev_type,
mev_cl_type,
mev_cl_port,
)
flashbots_builder_config_template = read_file(
static_files.FLASHBOTS_RBUILDER_CONFIG_FILEPATH
Expand Down Expand Up @@ -73,6 +99,8 @@ def new_builder_config_template_data(
num_of_participants,
subsidy,
mev_type,
builder_cl_type,
builder_cl_port,
):
# Determine relay service name and port based on MEV type
if mev_type == constants.HELIX_MEV_TYPE:
Expand All @@ -91,9 +119,9 @@ def new_builder_config_template_data(
"DataDir": "/data/reth/execution-data",
"CLEndpoint": "http://cl-{0}-{1}-{2}:{3}".format(
num_of_participants,
constants.CL_TYPE.lighthouse,
builder_cl_type,
constants.EL_TYPE.reth_builder,
lighthouse.BEACON_HTTP_PORT_NUM,
builder_cl_port,
),
"GenesisForkVersion": constants.GENESIS_FORK_VERSION,
"Relay": relay_service,
Expand Down
118 changes: 105 additions & 13 deletions src/package_io/input_parser.star
Original file line number Diff line number Diff line change
Expand Up @@ -1865,6 +1865,58 @@ def enrich_disable_peer_scoring(parsed_arguments_dict):
return parsed_arguments_dict


def infer_cl_type_from_image(cl_image):
"""Infer CL client type from given config.

Note: Only Lighthouse, Prysm, and Teku are supported as builder CLs.
Lodestar, Nimbus, and Grandine have incompatible payload_attributes SSE event formats.
"""
for candidate in [
constants.CL_TYPE.lighthouse,
constants.CL_TYPE.prysm,
constants.CL_TYPE.teku,
]:
if candidate in cl_image:
return candidate
return constants.CL_TYPE.lighthouse # default


def get_mev_cl_extra_params(cl_type, mev_url, include_supernode=False):
"""Return CL-specific builder flags for MEV participant.

For MEV builder nodes, the CL needs to prepare payloads for EVERY slot,
not just slots where the validator is proposing. This requires special flags.

Note: Only Lighthouse, Prysm, and Teku are supported as builder CLs.
Lodestar, Nimbus, and Grandine have incompatible payload_attributes SSE event formats.
"""
params = []
if cl_type == constants.CL_TYPE.lighthouse:
params.extend(
[
"--builder={0}".format(mev_url),
"--always-prepare-payload",
"--prepare-payload-lookahead",
"8000",
"--disable-peer-scoring",
]
)
if include_supernode:
params.append("--supernode")
elif cl_type == constants.CL_TYPE.teku:
params.append("--builder-endpoint={0}".format(mev_url))
params.append("--validators-builder-registration-default-enabled=true")
# BUILDER_ALWAYS ensures builder is always used for payload construction
params.append("--builder-bid-compare-factor=BUILDER_ALWAYS")
# This flag makes Teku send payload_attributes on every slot (required for block builders)
params.append("--Xfork-choice-updated-always-send-payload-attributes=true")
elif cl_type == constants.CL_TYPE.prysm:
params.append("--http-mev-relay={0}".format(mev_url))
# prepare-all-payloads tells Prysm to prepare payloads for every slot (required for builders)
params.append("--prepare-all-payloads")
return params


# TODO perhaps clean this up into a map
def enrich_mev_extra_params(parsed_arguments_dict, mev_prefix, mev_port, mev_type):
for index, participant in enumerate(parsed_arguments_dict["participants"]):
Expand Down Expand Up @@ -1943,13 +1995,6 @@ def enrich_mev_extra_params(parsed_arguments_dict, mev_prefix, mev_port, mev_typ
"el_image": parsed_arguments_dict["mev_params"]["mev_builder_image"],
"cl_image": parsed_arguments_dict["mev_params"]["mev_builder_cl_image"],
"cl_log_level": parsed_arguments_dict["global_log_level"],
"cl_extra_params": [
"--always-prepare-payload",
"--prepare-payload-lookahead",
"8000",
"--disable-peer-scoring",
"--supernode",
],
"el_extra_params": parsed_arguments_dict["mev_params"][
"mev_builder_extra_args"
],
Expand All @@ -1960,6 +2005,34 @@ def enrich_mev_extra_params(parsed_arguments_dict, mev_prefix, mev_port, mev_typ
}
)

mev_cl_image = parsed_arguments_dict["mev_params"]["mev_builder_cl_image"]
mev_cl_type = infer_cl_type_from_image(mev_cl_image)
mev_participant["cl_type"] = mev_cl_type
mev_participant["vc_type"] = mev_cl_type

# Compute mev_url for this mev participant so we can set CL-specific
# extra params (different CLs accept different flags).
if mev_type == constants.COMMIT_BOOST_MEV_TYPE:
prefix = constants.COMMIT_BOOST_SERVICE_NAME_PREFIX
else:
prefix = constants.MEV_BOOST_SERVICE_NAME_PREFIX
num_participants = len(parsed_arguments_dict["participants"])
index_str = shared_utils.zfill_custom(
num_participants + 1, len(str(num_participants + 1))
)
mev_url = "http://{0}-{1}-{2}-{3}:{4}".format(
prefix,
index_str,
mev_participant["cl_type"],
mev_participant["el_type"],
constants.MEV_BOOST_PORT,
)

# Use helper to get CL-specific builder flags (with supernode for Flashbots/CommitBoost/Helix)
mev_participant["cl_extra_params"] = get_mev_cl_extra_params(
mev_cl_type, mev_url, include_supernode=True
)

parsed_arguments_dict["participants"].append(mev_participant)

if mev_type == constants.MEV_RS_MEV_TYPE:
Expand All @@ -1970,19 +2043,38 @@ def enrich_mev_extra_params(parsed_arguments_dict, mev_prefix, mev_port, mev_typ
"el_image": parsed_arguments_dict["mev_params"]["mev_builder_image"],
"cl_image": parsed_arguments_dict["mev_params"]["mev_builder_cl_image"],
"cl_log_level": parsed_arguments_dict["global_log_level"],
"cl_extra_params": [
"--always-prepare-payload",
"--prepare-payload-lookahead",
"8000",
"--disable-peer-scoring",
],
"el_extra_params": parsed_arguments_dict["mev_params"][
"mev_builder_extra_args"
],
"validator_count": 0,
}
)

mev_cl_image = parsed_arguments_dict["mev_params"]["mev_builder_cl_image"]
mev_cl_type = infer_cl_type_from_image(mev_cl_image)
mev_participant["cl_type"] = mev_cl_type
mev_participant["vc_type"] = mev_cl_type

prefix = constants.MEV_BOOST_SERVICE_NAME_PREFIX
num_participants = len(parsed_arguments_dict["participants"])
index_str = shared_utils.zfill_custom(
num_participants + 1, len(str(num_participants + 1))
)
mev_url = "http://{0}-{1}-{2}-{3}:{4}".format(
prefix,
index_str,
mev_participant["cl_type"],
mev_participant["el_type"],
constants.MEV_BOOST_PORT,
)

# Use helper to get CL-specific builder flags (no supernode for MEV-RS)
mev_participant["cl_extra_params"] = get_mev_cl_extra_params(
mev_cl_type, mev_url, include_supernode=False
)

parsed_arguments_dict["participants"].append(mev_participant)

if mev_type == constants.MOCK_MEV_TYPE:
parsed_arguments_dict["mev_params"]["mock_mev_image"] = parsed_arguments_dict[
"mev_params"
Expand Down