From 81d19b444159e20da3cd24db3242ea09820a94a0 Mon Sep 17 00:00:00 2001 From: thedevbirb Date: Fri, 27 Sep 2024 09:56:37 +0200 Subject: [PATCH 01/11] feat: helix config stub --- main.star | 6 +- src/mev/mev_relay/helix_launcher.star | 205 ++++++++++++++++++ src/mev/mev_sidecar/mev_sidecar_launcher.star | 4 +- src/package_io/input_parser.star | 1 + src/static_files/static_files.star | 10 + .../helix-relay-config/config.yaml.tmpl | 23 ++ .../network-config.yaml.tmpl | 35 +++ 7 files changed, 280 insertions(+), 4 deletions(-) create mode 100644 src/mev/mev_relay/helix_launcher.star create mode 100644 static_files/helix-relay-config/config.yaml.tmpl create mode 100644 static_files/helix-relay-config/network-config.yaml.tmpl diff --git a/main.star b/main.star index c9ea27d3b..5e9682140 100644 --- a/main.star +++ b/main.star @@ -31,6 +31,7 @@ grafana = import_module("./src/grafana/grafana_launcher.star") mev_boost = import_module("./src/mev/mev_boost/mev_boost_launcher.star") mock_mev = import_module("./src/mev/mock_mev/mock_mev_launcher.star") mev_relay = import_module("./src/mev/mev_relay/mev_relay_launcher.star") +helix_relay = import_module("./src/mev/mev_relay/helix_launcher.star") mev_flood = import_module("./src/mev/mev_flood/mev_flood_launcher.star") mev_custom_flood = import_module( "./src/mev/mev_custom_flood/mev_custom_flood_launcher.star" @@ -237,15 +238,16 @@ def run(plan, args={}): timeout="20m", service_name=first_client_beacon_name, ) - endpoint = mev_relay.launch_mev_relay( + endpoint = helix_relay.launch_helix_relay( plan, mev_params, - network_params.network_id, + network_params, beacon_uris, genesis_validators_root, builder_uri, network_params.seconds_per_slot, persistent, + final_genesis_timestamp, global_node_selectors, ) mev_flood.spam_in_background( diff --git a/src/mev/mev_relay/helix_launcher.star b/src/mev/mev_relay/helix_launcher.star new file mode 100644 index 000000000..2d4b1846f --- /dev/null +++ b/src/mev/mev_relay/helix_launcher.star @@ -0,0 +1,205 @@ +redis_module = import_module("github.com/kurtosis-tech/redis-package/main.star") +postgres_module = import_module("github.com/kurtosis-tech/postgres-package/main.star") +constants = import_module("../../package_io/constants.star") +shared_utils = import_module("../../shared_utils/shared_utils.star") +static_files = import_module("../../static_files/static_files.star") + +# Misc constants +SERVICE_NAME="helix-relay" +HELIX_CONFIG_FILENAME="helix-config.yaml" +HELIX_NETWORK_CONFIG_FILENAME = "network-config.yaml" +HELIX_CONFIG_MOUNT_DIRPATH_ON_SERVICE="/config" + +# The secret key and public key for the relay, exposed as environment variables +DUMMY_SECRET_KEY = "0x607a11b45a7219cc61a3d9c5fd08c7eebd602a6a19a977f8d3771d5711a550f2" +DUMMY_PUB_KEY = "0xa55c1285d84ba83a5ad26420cd5ad3091e49c55a813eee651cd467db38a8c8e63192f47955e9376f6b42f6d190571cb5" + +# This is currenlty hardcoded in the Helix relay +HELIX_RELAY_ENDPOINT_PORT = 4040 + +# The min/max CPU/memory that mev-relay can use +RELAY_MIN_CPU = 2000 # 2 cores +RELAY_MAX_CPU = 4000 # 2 cores +RELAY_MIN_MEMORY = 128 +RELAY_MAX_MEMORY = 1024 + +# The min/max CPU/memory that postgres can use +POSTGRES_MIN_CPU = 10 +POSTGRES_MAX_CPU = 1000 +POSTGRES_MIN_MEMORY = 32 +POSTGRES_MAX_MEMORY = 1024 + +# The min/max CPU/memory that redis can use +REDIS_MIN_CPU = 10 +REDIS_MAX_CPU = 1000 +REDIS_MIN_MEMORY = 16 +REDIS_MAX_MEMORY = 1024 + + +def launch_helix_relay( + plan, + mev_params, + network_params, + beacon_uris, + validator_root, + builder_uri, + seconds_per_slot, + persistent, + genesis_timestamp, + global_node_selectors, +): + plan.print(network_params) + + node_selectors = global_node_selectors + + # Read the template files with Helix configuration and network configuration + helix_config_template = read_file( + static_files.HELIX_CONFIG_TEMPLATE_FILEPATH + ) + helix_network_config_template = read_file( + static_files.HELIX_NETWORK_CONFIG_TEMPLATE_FILEPATH + ) + + # Start both the Redis and Postgres services + redis = redis_module.run( + plan, + service_name="mev-relay-redis", + min_cpu=REDIS_MIN_CPU, + max_cpu=REDIS_MAX_CPU, + min_memory=REDIS_MIN_MEMORY, + max_memory=REDIS_MAX_MEMORY, + node_selectors=node_selectors, + ) + postgres = postgres_module.run( + plan, + # Postgres image with TimescaleDB extension: + # References: + # - https://docs.timescale.com/ + # - https://github.com/gattaca-com/helix/blob/9e078f1ec4710869b2e41e1ca20d31e1c7cfde52/crates/database/src/postgres/postgres_db_service_tests.rs#L41-L44 + image="timescale/timescaledb-ha:pg16", + password="postgres", + user="postgres", + database="postgres", + service_name="helix-postgres", + persistent=persistent, + launch_adminer=True, + min_cpu=POSTGRES_MIN_CPU, + max_cpu=POSTGRES_MAX_CPU, + min_memory=POSTGRES_MIN_MEMORY, + max_memory=POSTGRES_MAX_MEMORY, + node_selectors=node_selectors, + ) + + image = mev_params.helix_relay_image + + # Convert beacon_uris from a comma-separated string to a list of URIs + beacon_uris = [uri.strip() for uri in beacon_uris.split(",")] + + network_config_dir_path_on_service = "{0}/{1}".format( + HELIX_CONFIG_MOUNT_DIRPATH_ON_SERVICE, HELIX_NETWORK_CONFIG_FILENAME + ) + + # See https://github.com/kurtosis-tech/postgres-package#use-this-package-in-your-package + # and https://docs.kurtosis.com/api-reference/starlark-reference/service/ + helix_config_template_data = new_config_template_data( + postgres.service.hostname, + postgres.port.number, + postgres.database, + postgres.user, + postgres.password, + redis.url, + builder_uri, + beacon_uris, + network_config_dir_path_on_service, + validator_root, + genesis_timestamp, + ) + + helix_config_template_and_data = shared_utils.new_template_and_data( + helix_config_template, helix_config_template_data + ) + + helix_network_config_template_and_data = shared_utils.new_template_and_data( + helix_network_config_template, network_params + ) + template_and_data_by_rel_dest_filepath = {} + template_and_data_by_rel_dest_filepath[HELIX_CONFIG_FILENAME] = helix_config_template_and_data + template_and_data_by_rel_dest_filepath[HELIX_NETWORK_CONFIG_FILENAME] = helix_network_config_template_and_data + + config_files_artifact_name = plan.render_templates( + template_and_data_by_rel_dest_filepath + ) + + env_vars = { + "RELAY_KEY": DUMMY_SECRET_KEY, + "RUST_LOG": "debug", + } + + helix = plan.add_service( + name=SERVICE_NAME, + config=ServiceConfig( + image=image, + files={ + HELIX_CONFIG_MOUNT_DIRPATH_ON_SERVICE: config_files_artifact_name + }, + cmd=[ + "--config", + shared_utils.path_join( + HELIX_CONFIG_MOUNT_DIRPATH_ON_SERVICE, + HELIX_CONFIG_FILENAME, + ) + ], + ports={ + "api": PortSpec( + number=HELIX_RELAY_ENDPOINT_PORT, transport_protocol="TCP" + ) + }, + env_vars=env_vars, + min_cpu=RELAY_MIN_CPU, + max_cpu=RELAY_MAX_CPU, + min_memory=RELAY_MIN_MEMORY, + max_memory=RELAY_MAX_MEMORY, + node_selectors=node_selectors, + ), + ) + + return "http://{0}@{1}:{2}".format( + DUMMY_PUB_KEY, helix.ip_address, HELIX_RELAY_ENDPOINT_PORT + ) + +def new_config_template_data( + postgres_hostname, + postgres_port, + postgres_db_name, + postgres_user, + postgres_password, + redis_url, + blocksim_url, + beacon_uris, + network_config_dir_path, + genesis_validator_root, + genesis_time, +): + return { + "PostgresConfig": { + "hostname": postgres_hostname, + "port": postgres_port, + "db_name": postgres_db_name, + "user": postgres_user, + "password": postgres_password, + }, + "RedisConfig": { + "url": redis_url, + }, + "BlockSimulatorConfig": { + "url": blocksim_url, + }, + "BeaconClientsConfig": [ + {"url": uri} for uri in beacon_uris + ], + "NetworkConfig": { + "dir_path": network_config_dir_path, + "genesis_validator_root": genesis_validator_root, + "genesis_time": genesis_time, + }, + } diff --git a/src/mev/mev_sidecar/mev_sidecar_launcher.star b/src/mev/mev_sidecar/mev_sidecar_launcher.star index 1d45fa4ed..9dfb3ef37 100644 --- a/src/mev/mev_sidecar/mev_sidecar_launcher.star +++ b/src/mev/mev_sidecar/mev_sidecar_launcher.star @@ -42,9 +42,9 @@ def launch_mev_sidecar( "--private-key", # Random private key for testing, generated with `openssl rand -hex 32` "18d1c5302e734fd6fbfaa51828d42c4c6d3cbe020c42bab7dd15a2799cf00b82", - "--mevboost-url", + "--constraints-url", mev_boost_context_util.mev_boost_endpoint(mev_boost_context), - "--mevboost-proxy-port", + "--constraints-proxy-port", str(MEV_SIDECAR_BOOST_PROXY_PORT), "--beacon-api-url", beacon_api_url, diff --git a/src/package_io/input_parser.star b/src/package_io/input_parser.star index 0697750dc..b59141d8d 100644 --- a/src/package_io/input_parser.star +++ b/src/package_io/input_parser.star @@ -237,6 +237,7 @@ def input_parser(plan, input_args): preset=result["network_params"]["preset"], ), mev_params=struct( + helix_relay_image=result["mev_params"]["helix_relay_image"], mev_relay_image=result["mev_params"]["mev_relay_image"], mev_builder_image=result["mev_params"]["mev_builder_image"], mev_builder_cl_image=result["mev_params"]["mev_builder_cl_image"], diff --git a/src/static_files/static_files.star b/src/static_files/static_files.star index 98d2c838e..250e6c275 100644 --- a/src/static_files/static_files.star +++ b/src/static_files/static_files.star @@ -31,6 +31,16 @@ ASSERTOOR_TESTS_CONFIG_DIRPATH = ( STATIC_FILES_DIRPATH + ASSERTOOR_CONFIG_DIRPATH + "/tests" ) +# helix config +HELIX_CONFIG_DIRPATH = "/helix-relay-config" +HELIX_CONFIG_FULL_DIRPATH = ( + STATIC_FILES_DIRPATH + HELIX_CONFIG_DIRPATH +) +HELIX_CONFIG_TEMPLATE_FILEPATH = ( + STATIC_FILES_DIRPATH + HELIX_CONFIG_DIRPATH + "/config.yaml.tmpl" +) +HELIX_NETWORK_CONFIG_TEMPLATE_FILEPATH=HELIX_CONFIG_FULL_DIRPATH + "/network-config.yaml.tmpl" + # xatu-sentry config XATU_SENTRY_CONFIG_DIRPATH = "/xatu-sentry-config" XATU_SENTRY_CONFIG_TEMPLATE_FILEPATH = ( diff --git a/static_files/helix-relay-config/config.yaml.tmpl b/static_files/helix-relay-config/config.yaml.tmpl new file mode 100644 index 000000000..538bfd16d --- /dev/null +++ b/static_files/helix-relay-config/config.yaml.tmpl @@ -0,0 +1,23 @@ +postgres: + hostname: {{ .PostgresConfig.hostname }} + port: {{ .PostgresConfig.port }} + db_name: {{ .PostgresConfig.db_name }} + user: {{ .PostgresConfig.user }} + password: {{ .PostgresConfig.password }} + +redis: + url: {{ .RedisConfig.url }} + +simulator: + url: {{ .BlockSimulatorConfig.url }} + +beacon_clients: + {{ range $bcConfig := .BeaconClientsConfig }} + - url: "{{ $bcConfig.url }}" + {{- end }} + +network_config: + !Custom # this is a custom enum type and requies a '!' + dir_path: {{ .NetworkConfig.dir_path }} + genesis_validator_root: {{ .NetworkConfig.genesis_validator_root }} + genesis_time: {{ .NetworkConfig.genesis_time }} diff --git a/static_files/helix-relay-config/network-config.yaml.tmpl b/static_files/helix-relay-config/network-config.yaml.tmpl new file mode 100644 index 000000000..2bcaee005 --- /dev/null +++ b/static_files/helix-relay-config/network-config.yaml.tmpl @@ -0,0 +1,35 @@ +# The preset for the network configuration. +# Needed for `NetworkConfig` inside Helix + +PRESET_BASE: {{ .preset }} +CONFIG_NAME: "mainnet" +TERMINAL_TOTAL_DIFFICULTY: 0 +TERMINAL_BLOCK_HASH: "0x0000000000000000000000000000000000000000000000000000000000000000" +TERMINAL_BLOCK_HASH_ACTIVATION_EPOCH: 18446744073709551615 +MIN_GENESIS_ACTIVE_VALIDATOR_COUNT: 2 +MIN_GENESIS_TIME: 1727185220 +GENESIS_FORK_VERSION: "0x10000038" +GENESIS_DELAY: 20 +ALTAIR_FORK_VERSION: "0x20000038" +ALTAIR_FORK_EPOCH: 0 +BELLATRIX_FORK_VERSION: "0x30000038" +BELLATRIX_FORK_EPOCH: 0 +CAPELLA_FORK_VERSION: "0x40000038" +CAPELLA_FORK_EPOCH: 0 +DENEB_FORK_VERSION: "0x50000038" +DENEB_FORK_EPOCH: 0 +SECONDS_PER_SLOT: {{ .seconds_per_slot }} +SECONDS_PER_ETH1_BLOCK: {{ .seconds_per_slot }} +MIN_VALIDATOR_WITHDRAWABILITY_DELAY: {{ .min_validator_withdrawability_delay }} +SHARD_COMMITTEE_PERIOD: {{ .shard_committee_period }} +ETH1_FOLLOW_DISTANCE: {{ .eth1_follow_distance }} +INACTIVITY_SCORE_BIAS: 4 +INACTIVITY_SCORE_RECOVERY_RATE: 16 +EJECTION_BALANCE: {{ .ejection_balance }} +MIN_PER_EPOCH_CHURN_LIMIT: 4 +MAX_PER_EPOCH_ACTIVATION_CHURN_LIMIT: {{ .max_churn }} +CHURN_LIMIT_QUOTIENT: 65536 +PROPOSER_SCORE_BOOST: 40 +DEPOSIT_CHAIN_ID: {{ .network_id }} +DEPOSIT_NETWORK_ID: {{ .network_id }} +DEPOSIT_CONTRACT_ADDRESS: {{ .deposit_contract_address }} From fba4a8951eeead757ef14edc9cd30f34636d8c3e Mon Sep 17 00:00:00 2001 From: thedevbirb Date: Mon, 30 Sep 2024 15:31:43 +0200 Subject: [PATCH 02/11] chore(helix): test sleep before starting it --- main.star | 4 ++-- src/mev/mev_relay/helix_launcher.star | 10 +++++++--- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/main.star b/main.star index 5e9682140..8e867a3aa 100644 --- a/main.star +++ b/main.star @@ -238,7 +238,7 @@ def run(plan, args={}): timeout="20m", service_name=first_client_beacon_name, ) - endpoint = helix_relay.launch_helix_relay( + helix_endpoint = helix_relay.launch_helix_relay( plan, mev_params, network_params, @@ -258,7 +258,7 @@ def run(plan, args={}): contract_owner.private_key, normal_user.private_key, ) - mev_endpoints.append(endpoint) + mev_endpoints.append(helix_endpoint) # spin up the mev boost contexts if some endpoints for relays have been passed all_mevboost_contexts = [] diff --git a/src/mev/mev_relay/helix_launcher.star b/src/mev/mev_relay/helix_launcher.star index 2d4b1846f..c612b4f92 100644 --- a/src/mev/mev_relay/helix_launcher.star +++ b/src/mev/mev_relay/helix_launcher.star @@ -35,7 +35,6 @@ REDIS_MAX_CPU = 1000 REDIS_MIN_MEMORY = 16 REDIS_MAX_MEMORY = 1024 - def launch_helix_relay( plan, mev_params, @@ -79,7 +78,7 @@ def launch_helix_relay( image="timescale/timescaledb-ha:pg16", password="postgres", user="postgres", - database="postgres", + database="helixdb", service_name="helix-postgres", persistent=persistent, launch_adminer=True, @@ -132,9 +131,14 @@ def launch_helix_relay( env_vars = { "RELAY_KEY": DUMMY_SECRET_KEY, - "RUST_LOG": "debug", + "RUST_LOG": "trace", } + # Sleep `network_params.seconds_per_slot * 32` seconds (1 epoch) + genesis_delay before starting the relay + sleep_time = network_params.seconds_per_slot * 32 + network_params.genesis_delay + + plan.print("Sleeping for {0} seconds before starting the relay".format(sleep_time)) + helix = plan.add_service( name=SERVICE_NAME, config=ServiceConfig( From e5e945622186929821cfbc53194129afe6d8e24d Mon Sep 17 00:00:00 2001 From: thedevbirb Date: Mon, 30 Sep 2024 17:53:24 +0200 Subject: [PATCH 03/11] fix(helix): add it to builder --- src/package_io/input_parser.star | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/package_io/input_parser.star b/src/package_io/input_parser.star index b59141d8d..76656a45c 100644 --- a/src/package_io/input_parser.star +++ b/src/package_io/input_parser.star @@ -856,7 +856,8 @@ def enrich_mev_extra_params(parsed_arguments_dict, mev_prefix, mev_port, mev_typ # TODO(maybe) make parts of this more passable like the mev-relay-endpoint & forks "el_extra_params": [ "--builder", - "--builder.remote_relay_endpoint=http://mev-relay-api:9062", + # TODO: (thedevbirb) this should indeed more passable. Now hardcoded for Helix relay + "--builder.remote_relay_endpoint=http://helix-relay:4040", "--builder.beacon_endpoints=http://cl-{0}-lighthouse-geth-builder:4000".format( index_str ), From 869b437d7808159cdd356c3d6e9d9b634997ebc4 Mon Sep 17 00:00:00 2001 From: thedevbirb Date: Tue, 1 Oct 2024 11:51:11 +0200 Subject: [PATCH 04/11] chore(helix): log level --- src/mev/mev_relay/helix_launcher.star | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/mev/mev_relay/helix_launcher.star b/src/mev/mev_relay/helix_launcher.star index c612b4f92..d5d363cd0 100644 --- a/src/mev/mev_relay/helix_launcher.star +++ b/src/mev/mev_relay/helix_launcher.star @@ -131,14 +131,9 @@ def launch_helix_relay( env_vars = { "RELAY_KEY": DUMMY_SECRET_KEY, - "RUST_LOG": "trace", + "RUST_LOG": "RUST_LOG=helix_cmd=trace,helix_api=trace,helix_common=trace,helix_datastore=trace,helix_housekeeper=trace,helix_database=trace,helix_beacon_client=trace", } - # Sleep `network_params.seconds_per_slot * 32` seconds (1 epoch) + genesis_delay before starting the relay - sleep_time = network_params.seconds_per_slot * 32 + network_params.genesis_delay - - plan.print("Sleeping for {0} seconds before starting the relay".format(sleep_time)) - helix = plan.add_service( name=SERVICE_NAME, config=ServiceConfig( From 7c8549160a48ddf668773d3fba98cb7e1b168629 Mon Sep 17 00:00:00 2001 From: thedevbirb Date: Tue, 1 Oct 2024 16:09:56 +0200 Subject: [PATCH 05/11] test: logs --- main.star | 1 + src/mev/mev_relay/helix_launcher.star | 1 + 2 files changed, 2 insertions(+) diff --git a/main.star b/main.star index 8e867a3aa..277eca2c8 100644 --- a/main.star +++ b/main.star @@ -213,6 +213,7 @@ def run(plan, args={}): beacon_uris = ",".join( ["{0}".format(context.beacon_http_url) for context in all_cl_contexts] ) + plan.print(beacon_uris) first_cl_client = all_cl_contexts[0] first_client_beacon_name = first_cl_client.beacon_service_name diff --git a/src/mev/mev_relay/helix_launcher.star b/src/mev/mev_relay/helix_launcher.star index d5d363cd0..065c0239c 100644 --- a/src/mev/mev_relay/helix_launcher.star +++ b/src/mev/mev_relay/helix_launcher.star @@ -93,6 +93,7 @@ def launch_helix_relay( # Convert beacon_uris from a comma-separated string to a list of URIs beacon_uris = [uri.strip() for uri in beacon_uris.split(",")] + plan.print(beacon_uris) network_config_dir_path_on_service = "{0}/{1}".format( HELIX_CONFIG_MOUNT_DIRPATH_ON_SERVICE, HELIX_NETWORK_CONFIG_FILENAME From 351ecbd87b6654bfff32e287621f865b74b2a9e1 Mon Sep 17 00:00:00 2001 From: thedevbirb Date: Tue, 1 Oct 2024 16:52:02 +0200 Subject: [PATCH 06/11] test: beacon uris --- src/mev/mev_relay/helix_launcher.star | 1 - 1 file changed, 1 deletion(-) diff --git a/src/mev/mev_relay/helix_launcher.star b/src/mev/mev_relay/helix_launcher.star index 065c0239c..d5d363cd0 100644 --- a/src/mev/mev_relay/helix_launcher.star +++ b/src/mev/mev_relay/helix_launcher.star @@ -93,7 +93,6 @@ def launch_helix_relay( # Convert beacon_uris from a comma-separated string to a list of URIs beacon_uris = [uri.strip() for uri in beacon_uris.split(",")] - plan.print(beacon_uris) network_config_dir_path_on_service = "{0}/{1}".format( HELIX_CONFIG_MOUNT_DIRPATH_ON_SERVICE, HELIX_NETWORK_CONFIG_FILENAME From c29e4bfa3af339c30d425cf492a43d1bb2d553d8 Mon Sep 17 00:00:00 2001 From: thedevbirb Date: Wed, 2 Oct 2024 11:16:55 +0200 Subject: [PATCH 07/11] feat(bolt-boost): toml tmpl config file stub test template test tempalte asdf test temaplate asdf --- .../cb-bolt-boost-config.toml.tmpl | 139 ++++++++++++++++++ 1 file changed, 139 insertions(+) create mode 100644 static_files/bolt-boost-config/cb-bolt-boost-config.toml.tmpl diff --git a/static_files/bolt-boost-config/cb-bolt-boost-config.toml.tmpl b/static_files/bolt-boost-config/cb-bolt-boost-config.toml.tmpl new file mode 100644 index 000000000..cbd91c1b0 --- /dev/null +++ b/static_files/bolt-boost-config/cb-bolt-boost-config.toml.tmpl @@ -0,0 +1,139 @@ +# The main configuration file for the Commit-Boost sidecar. +# Some fields are optional and can be omitted, in which case the default value, if present, will be used. + +# Chain spec id. Supported values: Mainnet, Holesky, Helder +chain = "{{ or .chain "Mainnet" }}" + +# Configuration for the PBS module +[pbs] +# Docker image to use for the PBS module. +# BOLT: We use the bolt-boost PBS module here. +docker_image = "{{ .image }}" + +# Whether to enable the PBS module to request signatures from the Signer module (not used in the default PBS image) +# OPTIONAL, DEFAULT: false +with_signer = {{ or .with_signer false }} + +# Port to receive BuilderAPI calls from beacon node +port = {{ .port }} + +# Whether to forward `status` calls to relays or skip and return 200 +# OPTIONAL, DEFAULT: true +relay_check = {{ or .relay_check true }} + +# Timeout in milliseconds for the `get_header` call to relays. Note that the CL has also a timeout (e.g. 1 second) so +# this should be lower than that, leaving some margin for overhead +# OPTIONAL, DEFAULT: 950 +timeout_get_header_ms = {{ or .timeout_get_header_ms "950" }} + +# Timeout in milliseconds for the `submit_blinded_block` call to relays. +# OPTIONAL, DEFAULT: 4000 +timeout_get_payload_ms = {{ or .timeout_get_payload_ms "4000" }} + +# Timeout in milliseconds for the `register_validator` call to relays. +# OPTIONAL, DEFAULT: 3000 +timeout_register_validator_ms = {{ or .timeout_register_validator_ms "3000" }} + +# Whether to skip signature verification of headers against the relay pubkey +# OPTIONAL, DEFAULT: false +skip_sigverify = {{ or .skip_sigverify false }} + +# Minimum bid in ETH that will be accepted from `get_header` +# OPTIONAL, DEFAULT: 0.0 +min_bid_eth = {{ or .min_bid_eth "0.0" }} + +# List of URLs of relay monitors to send registrations to +# OPTIONAL +relay_monitors = [] + +# How late in milliseconds in the slot is "late". This impacts the `get_header` requests, by shortening timeouts for `get_header` calls to +# relays and make sure a header is returned within this deadline. If the request from the CL comes later in the slot, then fetching headers is skipped +# to force local building and minimizing the risk of missed slots. +# OPTIONAL, DEFAULT: 2000 +late_in_slot_time_ms = {{ or .late_in_slot_time_ms "2000" }} + +# The PBS module needs one or more [[relays]] as defined below. +{{ range $relay_config := .relays_config }} +[[relays]] +# Relay ID to use in telemetry +# OPTIONAL, DEFAULT: URL hostname +id = "{{ $relay_config.id }}" + +# Relay URL in the format scheme://pubkey@host +url = "{{ $relay_config.url }}" + +# Headers to send with each request for this relay +# OPTIONAL +# headers = {{ or $relay_config.headers "{}" }} + +# Whether to enable timing games, as tuned by `target_first_request_ms` and `frequency_get_header_ms`. +# OPTIONAL, DEFAULT: false +enable_timing_games = {{ or $relay_config.enable_timing_games false }} + +# Target time in slot when to send the first header request +# OPTIONAL +target_first_request_ms = {{ or $relay_config.target_first_request_ms "200" }} + +# Frequency in ms to send get_header requests +# OPTIONAL +frequency_get_header_ms = {{ or .frequency_get_header_ms "300" }} + +{{ end }} + +# Configuration for the Signer Module, only required if any `commit` module is present, or if `pbs.with_signer = true` +# OPTIONAL +[signer] +# Docker image to use for the Signer module. +# OPTIONAL, DEFAULT: ghcr.io/commit-boost/signer:latest +docker_image = "{{ or .signer_image "ghcr.io/commit-boost/signer:latest" }}" + +# Configuration for how the Signer module should load validator keys. Currently two types of loaders are supported: +# - File: load keys from a plain text file (unsafe, use only for testing purposes) +# - ValidatorsDir: load keys from a `keys` and `secrets` folder (ERC-2335 style keystores as used in Lighthouse) +[signer.loader] +# File: path to the keys file +key_path = "./keys.json" +# ValidatorsDir: path to the keys directory +# keys_path = "" +# ValidatorsDir: path to the secrets directory +# secrets_path = "" + +# Commit-Boost can optionally run "modules" which extend the capabilities of the sidecar. +# Currently, two types of modules are supported: +# - "commit": modules which request commitment signatures from the validator keys +# - "events": modules which callback to BuilderAPI events as triggered from the PBS modules, used e.g. for monitoring +# If any "commit" module is present, then the [signer] section should also be configured +# OPTIONAL +[[modules]] +# Unique ID of the module +id = "BOLT" +# Type of the module. Supported values: commit, events +type = "commit" +# Docker image of the module +docker_image = "{{ .image }}" + +[modules.env] +BOLT_SIDECAR_CHAIN = "{{ or .chain "Kurtosis" }}" + +# The address of the PBS module +BOLT_SIDECAR_CONSTRAINTS_API = "{{ .bolt_sidecar_config.constraints_api_url }}" +BOLT_SIDECAR_BEACON_API = "{{ .bolt_sidecar_config.beacon_api_url }}" +BOLT_SIDECAR_EXECUTION_API = "{{ .bolt_sidecar_config.execution_api_url }}" + +# The execution layer engine API endpoint +BOLT_SIDECAR_ENGINE_API = "{{ .bolt_sidecar_config.engine_api_url }}" + +# The engine JWT +BOLT_SIDECAR_JWT_HEX = "{{ .bolt_sidecar_config.jwt_hex }}" + +# The port on which the sidecar builder-API will listen on. This is what your beacon node should connect to. +BOLT_SIDECAR_BUILDER_PROXY_PORT = {{ .bolt_sidecar_config.builder_proxy_port }} + +# The fee recipient +BOLT_SIDECAR_FEE_RECIPIENT = "{{ or .bolt_sidecar_config.fee_recipient "0x0000000000000000000000000000000000000000" }}" + +# The active validator indexes e.g 1..2 +BOLT_SIDECAR_VALIDATOR_INDEXES = "{{ or .bolt_sidecar_config.validator_indexes "0..64" }}" + +# Metrics port +BOLT_SIDECAR_METRICS_PORT = {{ or .bolt_sidecar_config.metrics_port "10000" }} From a7d243ed4bb7181f46447ffee3ee20f3b515d525 Mon Sep 17 00:00:00 2001 From: thedevbirb Date: Wed, 2 Oct 2024 11:23:30 +0200 Subject: [PATCH 08/11] chore(bolt-boost): update static files constants --- src/static_files/static_files.star | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/static_files/static_files.star b/src/static_files/static_files.star index 250e6c275..c5d81d4be 100644 --- a/src/static_files/static_files.star +++ b/src/static_files/static_files.star @@ -41,6 +41,15 @@ HELIX_CONFIG_TEMPLATE_FILEPATH = ( ) HELIX_NETWORK_CONFIG_TEMPLATE_FILEPATH=HELIX_CONFIG_FULL_DIRPATH + "/network-config.yaml.tmpl" +# bolt-boost config +BOLT_BOOST_CONFIG_DIRPATH = "/bolt-boost-config" +BOLT_BOOST_CONFIG_FULL_DIRPATH = ( + STATIC_FILES_DIRPATH + BOLT_BOOST_CONFIG_DIRPATH +) +BOLT_BOOST_CONFIG_TEMPLATE_FILEPATH = ( + STATIC_FILES_DIRPATH + BOLT_BOOST_CONFIG_DIRPATH + "/cb-bolt-boost-config.toml.tmpl" +) + # xatu-sentry config XATU_SENTRY_CONFIG_DIRPATH = "/xatu-sentry-config" XATU_SENTRY_CONFIG_TEMPLATE_FILEPATH = ( From 3d48b989ef2297676264bf0307a349e0b28e7efd Mon Sep 17 00:00:00 2001 From: thedevbirb Date: Wed, 2 Oct 2024 11:47:54 +0200 Subject: [PATCH 09/11] feat(bolt-boost): launcher stub boost launch boost boost asdf asdf --- src/mev/bolt-boost/bolt-boost-launcher.star | 117 ++++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100644 src/mev/bolt-boost/bolt-boost-launcher.star diff --git a/src/mev/bolt-boost/bolt-boost-launcher.star b/src/mev/bolt-boost/bolt-boost-launcher.star new file mode 100644 index 000000000..b7d1da774 --- /dev/null +++ b/src/mev/bolt-boost/bolt-boost-launcher.star @@ -0,0 +1,117 @@ +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") + +FLASHBOTS_MEV_BOOST_PROTOCOL = "TCP" + +SERVICE_NAME="bolt-boost" +BOLT_BOOST_CONFIG_FILENAME="cb-bolt-config.toml" +BOLT_BOOST_CONFIG_MOUNT_DIRPATH_ON_SERVICE="/config" +BOLT_BOOST_BUILDER_PROXY_PORT=18551 + +USED_PORTS = { + "api": shared_utils.new_port_spec( + input_parser.FLASHBOTS_MEV_BOOST_PORT, FLASHBOTS_MEV_BOOST_PROTOCOL, wait="5s" + ) +} + +# 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, + bolt_boost_image, + service_name, + relays_config, + bolt_sidecar_config, + network_params, + global_node_selectors, +): + config = get_bolt_boost_config( + plan, + bolt_boost_image, + relays_config, + bolt_sidecar_config, + 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.FLASHBOTS_MEV_BOOST_PORT + ) + + +def get_bolt_boost_config( + plan, + image, + relays_config, + bolt_sidecar_config, + node_selectors, +): + # Read the template file for Bolt Boost configuration + bolt_boost_config_template = read_file( + static_files.BOLT_BOOST_CONFIG_TEMPLATE_FILEPATH + ) + + # Generate the data to be used in the Bolt Boost configuration, + # wrap them together in a struct + bolt_boost_config_template_data = new_bolt_boost_config_template_data(image, relays_config, bolt_sidecar_config) + bolt_boost_config_template_and_data = shared_utils.new_template_and_data( + bolt_boost_config_template, bolt_boost_config_template_data + ) + + # Map the relative destination filepaths to the template/data pairs + template_and_data_by_rel_dest_filepath = {} + template_and_data_by_rel_dest_filepath[BOLT_BOOST_CONFIG_FILENAME] = bolt_boost_config_template_and_data + + # Render the templates to files in the artifact directory + config_files_artifact_name = plan.render_templates( + template_and_data_by_rel_dest_filepath + ) + + return ServiceConfig( + image=image, + ports=USED_PORTS, + files={ + BOLT_BOOST_CONFIG_MOUNT_DIRPATH_ON_SERVICE: config_files_artifact_name + }, + env_vars={ + "CB_CONFIG": shared_utils.path_join( + BOLT_BOOST_CONFIG_MOUNT_DIRPATH_ON_SERVICE, + BOLT_BOOST_CONFIG_FILENAME, + ) + }, + min_cpu=MIN_CPU, + max_cpu=MAX_CPU, + min_memory=MIN_MEMORY, + max_memory=MAX_MEMORY, + node_selectors=node_selectors, + ) + +def new_bolt_boost_config_template_data(image, relays_config, bolt_sidecar_config): + return { + "chain": "Holesky", + "image": image, + "port": input_parser.FLASHBOTS_MEV_BOOST_PORT, + "relays_config": [ + { + "id": relay_config["id"], + "url": relay_config["url"], + } for relay_config in relays_config + ], + "bolt_sidecar_config": { + "constraints_api_url": bolt_sidecar_config["constraints_api_url"], + "beacon_api_url": bolt_sidecar_config["beacon_api_url"], + "execution_api_url": bolt_sidecar_config["execution_api_url"], + "engine_api_url": bolt_sidecar_config["engine_api_url"], + "jwt_hex": bolt_sidecar_config["jwt_hex"], + "metrics_port": bolt_sidecar_config["metrics_port"], + "builder_proxy_port": BOLT_BOOST_BUILDER_PROXY_PORT, + } + } From fea7f348a7801d64052641e191edd38f18d0d4c7 Mon Sep 17 00:00:00 2001 From: thedevbirb Date: Wed, 2 Oct 2024 12:23:44 +0200 Subject: [PATCH 10/11] chore(bolt-boost): support in input parser --- src/package_io/input_parser.star | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/package_io/input_parser.star b/src/package_io/input_parser.star index 76656a45c..1c6b1bc48 100644 --- a/src/package_io/input_parser.star +++ b/src/package_io/input_parser.star @@ -44,6 +44,7 @@ HIGH_DENEB_VALUE_FORK_VERKLE = 2000000000 # MEV Params FLASHBOTS_MEV_BOOST_PORT = 18550 MEV_BOOST_SERVICE_NAME_PREFIX = "mev-boost" +BOLT_BOOST_SERVICE_NAME_PREFIX = "bolt-boost" # Minimum number of validators required for a network to be valid is 64 MIN_VALIDATORS = 64 @@ -237,6 +238,7 @@ def input_parser(plan, input_args): preset=result["network_params"]["preset"], ), mev_params=struct( + bolt_boost_image=result["mev_params"]["bolt_boost_image"], helix_relay_image=result["mev_params"]["helix_relay_image"], mev_relay_image=result["mev_params"]["mev_relay_image"], mev_builder_image=result["mev_params"]["mev_builder_image"], @@ -711,6 +713,7 @@ def default_participant(): def get_default_mev_params(): return { + "bolt_boost_image": None, "mev_relay_image": MEV_BOOST_RELAY_DEFAULT_IMAGE, "mev_builder_image": "flashbots/builder:latest", "mev_builder_cl_image": "sigp/lighthouse:latest", From f1b04795c6859e7cf364030ec74b4e14643ce9c9 Mon Sep 17 00:00:00 2001 From: thedevbirb Date: Wed, 2 Oct 2024 12:24:35 +0200 Subject: [PATCH 11/11] feat!(bolt-boost): support in main.star; refactor of mev_sidecar_launcher --- main.star | 117 +++++++++++------- src/mev/mev_sidecar/mev_sidecar_launcher.star | 28 ++--- 2 files changed, 84 insertions(+), 61 deletions(-) diff --git a/main.star b/main.star index 277eca2c8..d67a2d69b 100644 --- a/main.star +++ b/main.star @@ -29,6 +29,7 @@ blockscout = import_module("./src/blockscout/blockscout_launcher.star") prometheus = import_module("./src/prometheus/prometheus_launcher.star") grafana = import_module("./src/grafana/grafana_launcher.star") mev_boost = import_module("./src/mev/mev_boost/mev_boost_launcher.star") +bolt_boost = import_module("./src/mev/bolt-boost/bolt-boost-launcher.star") mock_mev = import_module("./src/mev/mock_mev/mock_mev_launcher.star") mev_relay = import_module("./src/mev/mev_relay/mev_relay_launcher.star") helix_relay = import_module("./src/mev/mev_relay/helix_launcher.star") @@ -127,10 +128,11 @@ def run(plan, args={}): ) ) - mev_sidecar_context=struct( - ip_addr="", - metrics_port_num=0, - ) + #mev_sidecar_context=struct( + # ip_addr="", + # metrics_port_num=0, + #) + mev_sidecar_context = None all_el_contexts = [] all_cl_contexts = [] all_vc_contexts = [] @@ -269,47 +271,74 @@ def run(plan, args={}): index + 1, len(str(len(all_participants))) ) if args_with_right_defaults.participants[index].validator_count != 0: - mev_boost_launcher = 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 = mev_boost.launch( - plan, - mev_boost_launcher, - mev_boost_service_name, - network_params.network_id, - mev_params.mev_boost_image, - mev_params.mev_boost_args, - global_node_selectors, - network_params, - ) - all_mevboost_contexts.append(mev_boost_context) + if mev_params.bolt_boost_image == None: + mev_boost_launcher = 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 = mev_boost.launch( + plan, + mev_boost_launcher, + mev_boost_service_name, + network_params.network_id, + mev_params.mev_boost_image, + mev_params.mev_boost_args, + global_node_selectors, + network_params, + ) + all_mevboost_contexts.append(mev_boost_context) - # add mev-sidecar - mev_sidecar_ctx = mev_sidecar.launch_mev_sidecar( - plan, - mev_params, - global_node_selectors, - mev_boost_context, - all_cl_contexts[0].beacon_http_url, - "http://{0}:{1}".format( - all_el_contexts[0].ip_addr, - all_el_contexts[0].rpc_port_num, - ), - "http://{0}:{1}".format( - all_el_contexts[0].ip_addr, - all_el_contexts[0].engine_rpc_port_num - ), - raw_jwt_secret, - network_params.seconds_per_slot - ) - mev_sidecar_context = mev_sidecar_ctx + else: + bolt_boost_service_name = "{0}-{1}-{2}-{3}".format( + input_parser.BOLT_BOOST_SERVICE_NAME_PREFIX, + index_str, + participant.cl_type, + participant.el_type, + ) + relays_config = [{ + "id": "helix_relay", + "url": helix_endpoint, + }] + bolt_sidecar_config = { + "constraints_api_url": "{0}:{1}".format( + mev_sidecar.MEV_SIDECAR_ENDPOINT, mev_sidecar.MEV_SIDECAR_ENDPOINT_PORT + ), + "beacon_api_url": all_cl_contexts[0].beacon_http_url, + "execution_api_url": "http://{0}:{1}".format( + all_el_contexts[0].ip_addr, + all_el_contexts[0].rpc_port_num, + ), + "engine_api_url": "http://{0}:{1}".format( + all_el_contexts[0].ip_addr, + all_el_contexts[0].engine_rpc_port_num + ), + "jwt_hex": raw_jwt_secret, + "metrics_port": mev_sidecar.MEV_SIDECAR_METRICS_PORT, + } + bolt_boost_context = bolt_boost.launch( + plan, + mev_params.bolt_boost_image, + bolt_boost_service_name, + relays_config, + bolt_sidecar_config, + network_params, + global_node_selectors, + ) + all_mevboost_contexts.append(bolt_boost_context) + # add mev-sidecar + mev_sidecar_context = mev_sidecar.launch_mev_sidecar( + plan, + mev_params.mev_sidecar_image, + bolt_sidecar_config, + network_params, + global_node_selectors, + ) if len(args_with_right_defaults.additional_services) == 0: output = struct( diff --git a/src/mev/mev_sidecar/mev_sidecar_launcher.star b/src/mev/mev_sidecar/mev_sidecar_launcher.star index 9dfb3ef37..05fce5d16 100644 --- a/src/mev/mev_sidecar/mev_sidecar_launcher.star +++ b/src/mev/mev_sidecar/mev_sidecar_launcher.star @@ -3,7 +3,7 @@ postgres_module = import_module("github.com/kurtosis-tech/postgres-package/main. constants = import_module("../../package_io/constants.star") mev_boost_context_util = import_module("../mev_boost/mev_boost_context.star") -MEV_SIDECAR_ENDPOINT = "mev-sidecar-api" +MEV_SIDECAR_ENDPOINT = "http://mev-sidecar-api" MEV_SIDECAR_ENDPOINT_PORT = 9061 MEV_SIDECAR_BOOST_PROXY_PORT = 9062 @@ -17,23 +17,17 @@ MEV_SIDECAR_MAX_MEMORY = 1024 def launch_mev_sidecar( plan, - mev_params, + image, + sidecar_config, + network_params, node_selectors, - mev_boost_context, - beacon_api_url, - execution_api_url, - engine_api_url, - raw_jwt_secret, - seconds_per_slot, ): - image = mev_params.mev_sidecar_image - env_vars = { "RUST_LOG": "bolt_sidecar=trace", } api = plan.add_service( - name=MEV_SIDECAR_ENDPOINT, + name="mev-sidecar-api", config=ServiceConfig( image=image, cmd=[ @@ -43,19 +37,19 @@ def launch_mev_sidecar( # Random private key for testing, generated with `openssl rand -hex 32` "18d1c5302e734fd6fbfaa51828d42c4c6d3cbe020c42bab7dd15a2799cf00b82", "--constraints-url", - mev_boost_context_util.mev_boost_endpoint(mev_boost_context), + sidecar_config["constraints_api_url"], "--constraints-proxy-port", str(MEV_SIDECAR_BOOST_PROXY_PORT), "--beacon-api-url", - beacon_api_url, + sidecar_config["beacon_api_url"], "--execution-api-url", - execution_api_url, + sidecar_config["execution_api_url"], "--engine-api-url", - engine_api_url, + sidecar_config["engine_api_url"], "--fee-recipient", "0x0000000000000000000000000000000000000000", "--jwt-hex", - raw_jwt_secret, + sidecar_config["jwt_hex"], "--commitment-deadline", str(100), "--chain", @@ -63,7 +57,7 @@ def launch_mev_sidecar( "--validator-indexes", "0..64", "--slot-time", - str(seconds_per_slot), + str(network_params.seconds_per_slot), "--metrics-port", str(MEV_SIDECAR_METRICS_PORT), ],