Commit ebbbe836 authored by ltitanb's avatar ltitanb Committed by GitHub

feat: add commit-boost support (#779)

Initial support for Commit-Boost, adding for now only the PBS module
(equivalent to MEV-Boost).

Note that this depends on [this
PR](https://github.com/Commit-Boost/commit-boost-client/pull/138) being
merged and released.

There is sometimes some ambiguity between mev-boost (go client) and
mev-boost (protocol via the Builder API), so to disambiguate within
commit boost we call the PBS module the sidecar implementing the
mev-boost protocol.
Here I followed the existing convention as much as possible even if it
sounds somewhat repetitive at times (commit-boost-mev-boost).

EDIT: the blocking PR is now merged and released in `0.3.0`

---------
Co-authored-by: default avatarBarnabas Busa <busa.barnabas@gmail.com>
Co-authored-by: default avatarBarnabas Busa <barnabas.busa@ethereum.org>
parent 1825dbfc
participants:
- el_type: geth
cl_type: lighthouse
mev_type: commit-boost
additional_services:
- tx_spammer
- blob_spammer
- custom_flood
- el_forkmon
- beacon_metrics_gazer
- dora
- prometheus_grafana
mev_params:
mev_boost_image: ghcr.io/commit-boost/pbs:latest
mev_relay_image: flashbots/mev-boost-relay:latest
network_params:
seconds_per_slot: 3
......@@ -782,6 +782,7 @@ persistent: false
# "mock" - mock-builder & mev-boost are spun up
# "flashbots" - mev-boost, relays, flooder and builder are all spun up, powered by [flashbots](https://github.com/flashbots)
# "mev-rs" - mev-boost, relays and builder are all spun up, powered by [mev-rs](https://github.com/ralexstokes/mev-rs/)
# "commit-boost" - mev-boost, relays and builder are all spun up, powered by [commit-boost](https://github.com/Commit-Boost/commit-boost-client)
# We have seen instances of multibuilder instances failing to start mev-relay-api with non zero epochs
mev_type: null
......
......@@ -33,6 +33,9 @@ full_beaconchain_explorer = import_module(
blockscout = import_module("./src/blockscout/blockscout_launcher.star")
prometheus = import_module("./src/prometheus/prometheus_launcher.star")
grafana = import_module("./src/grafana/grafana_launcher.star")
commit_boost_mev_boost = import_module(
"./src/mev/commit-boost/mev_boost/mev_boost_launcher.star"
)
mev_rs_mev_boost = import_module("./src/mev/mev-rs/mev_boost/mev_boost_launcher.star")
mev_rs_mev_relay = import_module("./src/mev/mev-rs/mev_relay/mev_relay_launcher.star")
mev_rs_mev_builder = import_module(
......@@ -243,6 +246,7 @@ def run(plan, args={}):
elif args_with_right_defaults.mev_type and (
args_with_right_defaults.mev_type == constants.FLASHBOTS_MEV_TYPE
or args_with_right_defaults.mev_type == constants.MEV_RS_MEV_TYPE
or args_with_right_defaults.mev_type == constants.COMMIT_BOOST_MEV_TYPE
):
builder_uri = "http://{0}:{1}".format(
all_el_contexts[-1].ip_addr, all_el_contexts[-1].rpc_port_num
......@@ -276,7 +280,10 @@ def run(plan, args={}):
timeout="20m",
service_name=first_client_beacon_name,
)
if args_with_right_defaults.mev_type == constants.FLASHBOTS_MEV_TYPE:
if (
args_with_right_defaults.mev_type == constants.FLASHBOTS_MEV_TYPE
or args_with_right_defaults.mev_type == constants.COMMIT_BOOST_MEV_TYPE
):
endpoint = flashbots_mev_relay.launch_mev_relay(
plan,
mev_params,
......@@ -369,6 +376,30 @@ def run(plan, args={}):
el_cl_data_files_artifact_uuid,
global_node_selectors,
)
elif (
args_with_right_defaults.mev_type == constants.COMMIT_BOOST_MEV_TYPE
):
plan.print("Launching commit-boost PBS service")
mev_boost_launcher = commit_boost_mev_boost.new_mev_boost_launcher(
MEV_BOOST_SHOULD_CHECK_RELAY,
mev_endpoints,
)
mev_boost_service_name = "{0}-{1}-{2}-{3}".format(
input_parser.MEV_BOOST_SERVICE_NAME_PREFIX,
index_str,
participant.cl_type,
participant.el_type,
)
mev_boost_context = commit_boost_mev_boost.launch(
plan,
mev_boost_launcher,
mev_boost_service_name,
network_params.network,
mev_params,
mev_endpoints,
el_cl_data_files_artifact_uuid,
global_node_selectors,
)
else:
fail("Invalid MEV type")
all_mevboost_contexts.append(mev_boost_context)
......
def new_mev_boost_context(private_ip_address, port):
return struct(
private_ip_address=private_ip_address,
port=port,
)
def mev_boost_endpoint(mev_boost_context):
return "http://{0}:{1}".format(
mev_boost_context.private_ip_address, mev_boost_context.port
)
shared_utils = import_module("../../../shared_utils/shared_utils.star")
mev_boost_context_module = import_module("../mev_boost/mev_boost_context.star")
input_parser = import_module("../../../package_io/input_parser.star")
static_files = import_module("../../../static_files/static_files.star")
constants = import_module("../../../package_io/constants.star")
CB_CONFIG_FILENAME = "cb-config.toml"
CB_CONFIG_MOUNT_DIRPATH_ON_SERVICE = "/config"
CB_CONFIG_FILES_ARTIFACT_NAME = "commit-boost-config"
USED_PORTS = {
"http": shared_utils.new_port_spec(
input_parser.MEV_BOOST_PORT, shared_utils.TCP_PROTOCOL
)
}
# The min/max CPU/memory that mev-boost can use
MIN_CPU = 10
MAX_CPU = 500
MIN_MEMORY = 16
MAX_MEMORY = 256
def launch(
plan,
mev_boost_launcher,
service_name,
network,
mev_params,
relays,
el_cl_genesis_data,
global_node_selectors,
):
network = (
network
if network in constants.PUBLIC_NETWORKS
else constants.GENESIS_CONFIG_MOUNT_PATH_ON_CONTAINER + "/config.yaml"
)
image = mev_params.mev_boost_image
template_data = new_config_template_data(
network,
input_parser.MEV_BOOST_PORT,
relays,
)
mev_rs_boost_config_template = read_file(static_files.COMMIT_BOOST_CONFIG_FILEPATH)
template_and_data = shared_utils.new_template_and_data(
mev_rs_boost_config_template, template_data
)
template_and_data_by_rel_dest_filepath = {}
template_and_data_by_rel_dest_filepath[CB_CONFIG_FILENAME] = template_and_data
config_files_artifact_name = plan.render_templates(
template_and_data_by_rel_dest_filepath,
CB_CONFIG_FILES_ARTIFACT_NAME + service_name,
)
config_file_path = shared_utils.path_join(
CB_CONFIG_MOUNT_DIRPATH_ON_SERVICE, CB_CONFIG_FILENAME
)
config = get_config(
mev_boost_launcher,
image,
config_file_path,
config_files_artifact_name,
el_cl_genesis_data,
global_node_selectors,
)
mev_boost_service = plan.add_service(service_name, config)
return mev_boost_context_module.new_mev_boost_context(
mev_boost_service.ip_address, input_parser.MEV_BOOST_PORT
)
def get_config(
mev_boost_launcher,
image,
config_file_path,
config_file,
el_cl_genesis_data,
node_selectors,
):
return ServiceConfig(
image=image,
ports=USED_PORTS,
cmd=[],
env_vars={
"CB_CONFIG": config_file_path,
},
files={
CB_CONFIG_MOUNT_DIRPATH_ON_SERVICE: config_file,
constants.GENESIS_DATA_MOUNTPOINT_ON_CLIENTS: el_cl_genesis_data,
},
min_cpu=MIN_CPU,
max_cpu=MAX_CPU,
min_memory=MIN_MEMORY,
max_memory=MAX_MEMORY,
node_selectors=node_selectors,
)
def new_mev_boost_launcher(should_check_relay, relay_end_points):
return struct(
should_check_relay=should_check_relay, relay_end_points=relay_end_points
)
def new_config_template_data(network, port, relays):
return {
"Network": network,
"Port": port,
"Relays": relays,
}
......@@ -82,6 +82,7 @@ KEYMANAGER_MOUNT_PATH_ON_CONTAINER = (
MOCK_MEV_TYPE = "mock"
FLASHBOTS_MEV_TYPE = "flashbots"
MEV_RS_MEV_TYPE = "mev-rs"
COMMIT_BOOST_MEV_TYPE = "commit-boost"
DEFAULT_SNOOPER_IMAGE = "ethpandaops/rpc-snooper:latest"
DEFAULT_FLASHBOTS_RELAY_IMAGE = "flashbots/mev-boost-relay:0.27"
......@@ -89,6 +90,7 @@ DEFAULT_FLASHBOTS_BUILDER_IMAGE = "flashbots/builder:latest"
DEFAULT_FLASHBOTS_MEV_BOOST_IMAGE = "flashbots/mev-boost"
DEFAULT_MEV_RS_IMAGE = "ethpandaops/mev-rs:main"
DEFAULT_MEV_RS_IMAGE_MINIMAL = "ethpandaops/mev-rs:main-minimal"
DEFAULT_COMMIT_BOOST_MEV_BOOST_IMAGE = "ghcr.io/commit-boost/pbs:latest"
DEFAULT_MEV_PUBKEY = "0xa55c1285d84ba83a5ad26420cd5ad3091e49c55a813eee651cd467db38a8c8e63192f47955e9376f6b42f6d190571cb5"
DEFAULT_MEV_SECRET_KEY = (
"0x607a11b45a7219cc61a3d9c5fd08c7eebd602a6a19a977f8d3771d5711a550f2"
......
......@@ -170,6 +170,7 @@ def input_parser(plan, input_args):
constants.MOCK_MEV_TYPE,
constants.FLASHBOTS_MEV_TYPE,
constants.MEV_RS_MEV_TYPE,
constants.COMMIT_BOOST_MEV_TYPE,
):
result = enrich_mev_extra_params(
result,
......@@ -181,7 +182,7 @@ def input_parser(plan, input_args):
pass
else:
fail(
"Unsupported MEV type: {0}, please use 'mock', 'flashbots' or 'mev-rs' type".format(
"Unsupported MEV type: {0}, please use 'mock', 'flashbots', 'mev-rs' or 'commit-boost' type".format(
result.get("mev_type")
)
)
......@@ -1017,6 +1018,15 @@ def get_default_mev_params(mev_type, preset):
mev_builder_extra_data = "0x68656C6C6F20776F726C640A" # "hello world\n"
mev_builder_extra_args = ["--mev-builder-config=" + "/config/config.toml"]
if mev_type == constants.COMMIT_BOOST_MEV_TYPE:
mev_relay_image = constants.DEFAULT_FLASHBOTS_RELAY_IMAGE
mev_builder_image = constants.DEFAULT_FLASHBOTS_BUILDER_IMAGE
mev_boost_image = constants.DEFAULT_COMMIT_BOOST_MEV_BOOST_IMAGE
mev_builder_cl_image = DEFAULT_CL_IMAGES[constants.CL_TYPE.lighthouse]
mev_builder_extra_data = (
"0x436f6d6d69742d426f6f737420f09f93bb" # Commit-Boost 📻
)
return {
"mev_relay_image": mev_relay_image,
"mev_builder_image": mev_builder_image,
......@@ -1195,7 +1205,10 @@ def enrich_mev_extra_params(parsed_arguments_dict, mev_prefix, mev_port, mev_typ
index_str = shared_utils.zfill_custom(
num_participants + 1, len(str(num_participants + 1))
)
if mev_type == constants.FLASHBOTS_MEV_TYPE:
if (
mev_type == constants.FLASHBOTS_MEV_TYPE
or mev_type == constants.COMMIT_BOOST_MEV_TYPE
):
mev_participant = default_participant()
mev_participant["el_type"] = "geth"
mev_participant.update(
......
......@@ -96,3 +96,7 @@ MEV_RS_MEV_RELAY_CONFIG_FILEPATH = (
MEV_RS_MEV_BUILDER_CONFIG_FILEPATH = (
STATIC_FILES_DIRPATH + "/mev/mev-rs/mev_builder/config.toml.tmpl"
)
COMMIT_BOOST_CONFIG_FILEPATH = (
STATIC_FILES_DIRPATH + "/mev/commit-boost/cb-config.toml.tmpl"
)
chain = "{{ .Network }}"
[pbs]
port = {{ .Port }}
{{ range $index, $relay := .Relays }}
[[relays]]
id = "mev_relay_{{$index}}"
url = "{{ $relay }}"
{{- end }}
[logs]
log_level = "debug"
max_log_files = 7
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment