Commit 525a8fb3 authored by Barnabas Busa's avatar Barnabas Busa Committed by GitHub

feat!: add mev-rs relay/builder/boost (#586)

This PR introduces a new mev boost/mev relay created by @ralexstokes.
It can be triggered by:
`mev_type: mev-rs`

It gets rid of the previously used `full` flag and flashbots will work
under the `mev_type: flashbots` following this PR.
parent 2a20d5ad
mev_type: full
mev_type: flashbots
additional_services:
- tx_spammer
- blob_spammer
......
participants:
- el_type: geth
cl_type: teku
- el_type: geth
cl_type: prysm
- el_type: erigon
cl_type: nimbus
- el_type: besu
cl_type: lighthouse
- el_type: reth
cl_type: lodestar
- el_type: geth
cl_type: grandine
network_params:
preset: minimal
seconds_per_slot: 6
additional_services:
- dora
- tx_spammer
- apache
mev_type: mev-rs
......@@ -3,21 +3,14 @@ participants:
cl_type: teku
- el_type: geth
cl_type: prysm
cl_extra_params: [--minimal-config=true]
cl_image: ethpandaops/prysm-beacon-chain:develop-minimal
- el_type: erigon
cl_type: nimbus
cl_image: ethpandaops/nimbus-eth2:unstable-minimal
- el_type: besu
cl_type: lighthouse
cl_image: ethpandaops/lighthouse:unstable-minimal
- el_type: reth
cl_type: lodestar
cl_extra_env_vars: { LODESTAR_PRESET: minimal }
vc_extra_env_vars: { LODESTAR_PRESET: minimal }
- el_type: geth
cl_type: grandine
cl_image: ethpandaops/grandine:develop-minimal
network_params:
preset: minimal
seconds_per_slot: 6
......
......@@ -27,7 +27,7 @@ additional_services:
- apache
ethereum_metrics_exporter_enabled: true
snooper_enabled: true
mev_type: full
mev_type: flashbots
mev_params:
mev_relay_image: flashbots/mev-boost-relay:latest
persistent: True
participants:
- el_type: geth
cl_type: nimbus
mev_type: full
mev_type: flashbots
......@@ -36,6 +36,7 @@ v_max_mem -> vc_max_mem
### Global flags
```
global_client_log_level -> global_log_level
mev_type: full -> mev_type: flashbots # new rename as of 3 May 2024
```
To help you with the transition, we have added a script that will automatically update your `yaml` file to the new format. You can run the following command to update your network_params.yaml file:
......@@ -665,7 +666,8 @@ persistent: false
# Supports three valeus
# Default: "null" - no mev boost, mev builder, mev flood or relays are spun up
# "mock" - mock-builder & mev-boost are spun up
# "full" - mev-boost, relays, flooder and builder are all 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/)
# We have seen instances of multibuilder instances failing to start mev-relay-api with non zero epochs
mev_type: null
......@@ -841,7 +843,7 @@ participants:
- el_type: besu
cl_type: prysm
count: 2
mev_type: full
mev_type: flashbots
network_params:
deneb_fork_epoch: 1
additional_services: []
......
......@@ -31,12 +31,21 @@ 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")
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")
mev_flood = import_module("./src/mev/mev_flood/mev_flood_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(
"./src/mev/mev-rs/mev_builder/mev_builder_launcher.star"
)
flashbots_mev_boost = import_module(
"./src/mev/flashbots/mev_boost/mev_boost_launcher.star"
)
flashbots_mev_relay = import_module(
"./src/mev/flashbots/mev_relay/mev_relay_launcher.star"
)
mock_mev = import_module("./src/mev/flashbots/mock_mev/mock_mev_launcher.star")
mev_flood = import_module("./src/mev/flashbots/mev_flood/mev_flood_launcher.star")
mev_custom_flood = import_module(
"./src/mev/mev_custom_flood/mev_custom_flood_launcher.star"
"./src/mev/flashbots/mev_custom_flood/mev_custom_flood_launcher.star"
)
broadcaster = import_module("./src/broadcaster/broadcaster.star")
assertoor = import_module("./src/assertoor/assertoor_launcher.star")
......@@ -49,8 +58,6 @@ FIRST_NODE_FINALIZATION_FACT = "cl-boot-finalization-fact"
HTTP_PORT_ID_FOR_FACT = "http"
MEV_BOOST_SHOULD_CHECK_RELAY = True
MOCK_MEV_TYPE = "mock"
FULL_MEV_TYPE = "full"
PATH_TO_PARSED_BEACON_STATE = "/genesis/output/parsedBeaconState.json"
......@@ -92,6 +99,18 @@ def run(plan, args={}):
plan.print("Read the prometheus, grafana templates")
if args_with_right_defaults.mev_type == constants.MEV_RS_MEV_TYPE:
plan.print("Generating mev-rs builder config file")
mev_rs__builder_config_file = mev_rs_mev_builder.new_builder_config(
plan,
constants.MEV_RS_MEV_TYPE,
network_params.network,
constants.VALIDATING_REWARDS_ACCOUNT,
network_params.preregistered_validator_keys_mnemonic,
args_with_right_defaults.mev_params.mev_builder_extra_data,
global_node_selectors,
)
plan.print(
"Launching participant network with {0} participants and the following network params {1}".format(
num_participants, network_params
......@@ -179,7 +198,7 @@ def run(plan, args={}):
# otherwise dummy relays spinup if chosen
elif (
args_with_right_defaults.mev_type
and args_with_right_defaults.mev_type == MOCK_MEV_TYPE
and args_with_right_defaults.mev_type == constants.MOCK_MEV_TYPE
):
el_uri = "{0}:{1}".format(
all_el_contexts[0].ip_addr,
......@@ -197,13 +216,14 @@ def run(plan, args={}):
global_node_selectors,
)
mev_endpoints.append(endpoint)
elif (
args_with_right_defaults.mev_type
and args_with_right_defaults.mev_type == FULL_MEV_TYPE
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
):
builder_uri = "http://{0}:{1}".format(
all_el_contexts[-1].ip_addr, all_el_contexts[-1].rpc_port_num
)
beacon_uri = all_cl_contexts[-1].beacon_http_url
beacon_uris = ",".join(
["{0}".format(context.beacon_http_url) for context in all_cl_contexts]
)
......@@ -232,17 +252,30 @@ def run(plan, args={}):
timeout="20m",
service_name=first_client_beacon_name,
)
endpoint = mev_relay.launch_mev_relay(
plan,
mev_params,
network_params.network_id,
beacon_uris,
genesis_validators_root,
builder_uri,
network_params.seconds_per_slot,
persistent,
global_node_selectors,
)
if args_with_right_defaults.mev_type == constants.FLASHBOTS_MEV_TYPE:
endpoint = flashbots_mev_relay.launch_mev_relay(
plan,
mev_params,
network_params.network_id,
beacon_uris,
genesis_validators_root,
builder_uri,
network_params.seconds_per_slot,
persistent,
global_node_selectors,
)
elif args_with_right_defaults.mev_type == constants.MEV_RS_MEV_TYPE:
endpoint, relay_ip_address, relay_port = mev_rs_mev_relay.launch_mev_relay(
plan,
mev_params,
network_params.network,
beacon_uri,
el_cl_data_files_artifact_uuid,
global_node_selectors,
)
else:
fail("Invalid MEV type")
mev_flood.spam_in_background(
plan,
fuzz_target,
......@@ -260,26 +293,59 @@ def run(plan, args={}):
index_str = shared_utils.zfill_custom(
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,
plan.print(
"args_with_right_defaults.participants[index].validator_count {0}".format(
args_with_right_defaults.participants[index].validator_count
)
)
if args_with_right_defaults.participants[index].validator_count != 0:
if (
args_with_right_defaults.mev_type == constants.FLASHBOTS_MEV_TYPE
or args_with_right_defaults.mev_type == constants.MOCK_MEV_TYPE
):
mev_boost_launcher = flashbots_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 = flashbots_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,
)
elif args_with_right_defaults.mev_type == constants.MEV_RS_MEV_TYPE:
plan.print("Launching mev-rs mev boost")
mev_boost_launcher = mev_rs_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_rs_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)
if len(args_with_right_defaults.additional_services) == 0:
......
......@@ -74,6 +74,8 @@ replacements=(
vc_max_mem
global_client_log_level
global_log_level
full
flashbots
)
# Perform replacements
......
......@@ -38,13 +38,13 @@ def launch(
cl_launchers = {
constants.CL_TYPE.lighthouse: {
"launcher": lighthouse.new_lighthouse_launcher(
el_cl_data, jwt_file, network_params.network
el_cl_data, jwt_file, network_params
),
"launch_method": lighthouse.launch,
},
constants.CL_TYPE.lodestar: {
"launcher": lodestar.new_lodestar_launcher(
el_cl_data, jwt_file, network_params.network
el_cl_data, jwt_file, network_params
),
"launch_method": lodestar.launch,
},
......@@ -52,7 +52,7 @@ def launch(
"launcher": nimbus.new_nimbus_launcher(
el_cl_data,
jwt_file,
network_params.network,
network_params,
keymanager_file,
),
"launch_method": nimbus.launch,
......@@ -61,7 +61,7 @@ def launch(
"launcher": prysm.new_prysm_launcher(
el_cl_data,
jwt_file,
network_params.network,
network_params,
prysm_password_relative_filepath,
prysm_password_artifact_uuid,
),
......@@ -71,7 +71,7 @@ def launch(
"launcher": teku.new_teku_launcher(
el_cl_data,
jwt_file,
network_params.network,
network_params,
keymanager_file,
),
"launch_method": teku.launch,
......@@ -80,7 +80,7 @@ def launch(
"launcher": grandine.new_grandine_launcher(
el_cl_data,
jwt_file,
network_params.network,
network_params,
),
"launch_method": grandine.launch,
},
......
......@@ -422,10 +422,10 @@ def get_beacon_config(
def new_grandine_launcher(
el_cl_genesis_data,
jwt_file,
network,
network_params,
):
return struct(
el_cl_genesis_data=el_cl_genesis_data,
jwt_file=jwt_file,
network=network,
network=network_params.network,
)
......@@ -414,9 +414,9 @@ def get_beacon_config(
)
def new_lighthouse_launcher(el_cl_genesis_data, jwt_file, network):
def new_lighthouse_launcher(el_cl_genesis_data, jwt_file, network_params):
return struct(
el_cl_genesis_data=el_cl_genesis_data,
jwt_file=jwt_file,
network=network,
network=network_params.network,
)
......@@ -140,6 +140,7 @@ def launch(
tolerations,
node_selectors,
port_publisher,
launcher.preset,
)
beacon_service = plan.add_service(beacon_service_name, beacon_config)
......@@ -239,6 +240,7 @@ def get_beacon_config(
tolerations,
node_selectors,
port_publisher,
preset,
):
el_client_rpc_url_str = "http://{0}:{1}".format(
el_context.ip_addr,
......@@ -367,6 +369,10 @@ def get_beacon_config(
persistent_key="data-{0}".format(service_name),
size=cl_volume_size,
)
if preset == "minimal":
extra_env_vars["LODESTAR_PRESET"] = "minimal"
return ServiceConfig(
image=image,
ports=used_ports,
......@@ -394,9 +400,10 @@ def get_beacon_config(
)
def new_lodestar_launcher(el_cl_genesis_data, jwt_file, network):
def new_lodestar_launcher(el_cl_genesis_data, jwt_file, network_params):
return struct(
el_cl_genesis_data=el_cl_genesis_data,
jwt_file=jwt_file,
network=network,
network=network_params.network,
preset=network_params.preset,
)
......@@ -407,10 +407,10 @@ def get_beacon_config(
)
def new_nimbus_launcher(el_cl_genesis_data, jwt_file, network, keymanager_file):
def new_nimbus_launcher(el_cl_genesis_data, jwt_file, network_params, keymanager_file):
return struct(
el_cl_genesis_data=el_cl_genesis_data,
jwt_file=jwt_file,
network=network,
network=network_params.network,
keymanager_file=keymanager_file,
)
......@@ -148,6 +148,7 @@ def launch(
tolerations,
node_selectors,
port_publisher,
launcher.preset,
)
beacon_service = plan.add_service(beacon_service_name, beacon_config)
......@@ -226,6 +227,7 @@ def get_beacon_config(
tolerations,
node_selectors,
port_publisher,
preset,
):
# If snooper is enabled use the snooper engine context, otherwise use the execution client context
if snooper_enabled:
......@@ -282,6 +284,9 @@ def get_beacon_config(
# ^^^^^^^^^^^^^^^^^^^ METRICS CONFIG ^^^^^^^^^^^^^^^^^^^^^
]
if preset == "minimal":
cmd.append("--minimal-config=true")
if network not in constants.PUBLIC_NETWORKS:
cmd.append("--p2p-static-id=true")
cmd.append(
......@@ -382,14 +387,15 @@ def get_beacon_config(
def new_prysm_launcher(
el_cl_genesis_data,
jwt_file,
network,
network_params,
prysm_password_relative_filepath,
prysm_password_artifact_uuid,
):
return struct(
el_cl_genesis_data=el_cl_genesis_data,
jwt_file=jwt_file,
network=network,
network=network_params.network,
preset=network_params.preset,
prysm_password_artifact_uuid=prysm_password_artifact_uuid,
prysm_password_relative_filepath=prysm_password_relative_filepath,
)
......@@ -442,10 +442,10 @@ def get_beacon_config(
)
def new_teku_launcher(el_cl_genesis_data, jwt_file, network, keymanager_file):
def new_teku_launcher(el_cl_genesis_data, jwt_file, network_params, keymanager_file):
return struct(
el_cl_genesis_data=el_cl_genesis_data,
jwt_file=jwt_file,
network=network,
network=network_params.network,
keymanager_file=keymanager_file,
)
......@@ -37,7 +37,7 @@ def launch(
),
"launch_method": geth.launch,
},
constants.EL_TYPE.gethbuilder: {
constants.EL_TYPE.geth_builder: {
"launcher": geth.new_geth_launcher(
el_cl_data,
jwt_file,
......@@ -82,6 +82,15 @@ def launch(
),
"launch_method": reth.launch,
},
constants.EL_TYPE.reth_builder: {
"launcher": reth.new_reth_launcher(
el_cl_data,
jwt_file,
network_params.network,
builder=True,
),
"launch_method": reth.launch,
},
constants.EL_TYPE.ethereumjs: {
"launcher": ethereumjs.new_ethereumjs_launcher(
el_cl_data,
......@@ -115,7 +124,7 @@ def launch(
if el_type not in el_launchers:
fail(
"Unsupported launcher '{0}', need one of '{1}'".format(
el_type, ",".join([el.name for el in el_launchers.keys()])
el_type, ",".join(el_launchers.keys())
)
)
......
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")
el_context = import_module("../el_context.star")
el_admin_node_info = import_module("../el_admin_node_info.star")
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")
RPC_PORT_NUM = 8545
WS_PORT_NUM = 8546
......@@ -135,6 +136,7 @@ def launch(
el_volume_size,
tolerations,
node_selectors,
launcher.builder,
port_publisher,
)
......@@ -181,13 +183,9 @@ def get_config(
el_volume_size,
tolerations,
node_selectors,
builder,
port_publisher,
):
init_datadir_cmd_str = "reth init --datadir={0} --chain={1}".format(
EXECUTION_DATA_DIRPATH_ON_CLIENT_CONTAINER,
constants.GENESIS_CONFIG_MOUNT_PATH_ON_CONTAINER + "/genesis.json",
)
public_ports = {}
discovery_port = DISCOVERY_PORT_NUM
if port_publisher.public_port_start:
......@@ -203,7 +201,7 @@ def get_config(
used_ports = get_used_ports(discovery_port)
cmd = [
"reth",
"/usr/local/bin/mev build" if builder else "reth",
"node",
"-{0}".format(verbosity_level),
"--datadir=" + EXECUTION_DATA_DIRPATH_ON_CLIENT_CONTAINER,
......@@ -232,6 +230,7 @@ def get_config(
"--discovery.port={0}".format(discovery_port),
"--port={0}".format(discovery_port),
]
if network == constants.NETWORK_NAME.kurtosis:
if len(existing_el_clients) > 0:
cmd.append(
......@@ -256,15 +255,6 @@ def get_config(
cmd.extend([param for param in extra_params])
cmd_str = " ".join(cmd)
if network not in constants.PUBLIC_NETWORKS:
subcommand_strs = [
init_datadir_cmd_str,
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,
......@@ -277,11 +267,16 @@ def get_config(
size=el_volume_size,
)
if builder:
files[
mev_rs_builder.MEV_BUILDER_MOUNT_DIRPATH_ON_SERVICE
] = mev_rs_builder.MEV_BUILDER_FILES_ARTIFACT_NAME
return ServiceConfig(
image=image,
ports=used_ports,
public_ports=public_ports,
cmd=[command_str],
cmd=[cmd_str],
files=files,
entrypoint=ENTRYPOINT_ARGS,
private_ip_address_placeholder=constants.PRIVATE_IP_ADDRESS_PLACEHOLDER,
......@@ -302,9 +297,10 @@ def get_config(
)
def new_reth_launcher(el_cl_genesis_data, jwt_file, network):
def new_reth_launcher(el_cl_genesis_data, jwt_file, network, builder=False):
return struct(
el_cl_genesis_data=el_cl_genesis_data,
jwt_file=jwt_file,
network=network,
builder=builder,
)
shared_utils = import_module("../../shared_utils/shared_utils.star")
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")
input_parser = import_module("../../../package_io/input_parser.star")
FLASHBOTS_MEV_BOOST_PROTOCOL = "TCP"
USED_PORTS = {
"api": shared_utils.new_port_spec(
input_parser.FLASHBOTS_MEV_BOOST_PORT, FLASHBOTS_MEV_BOOST_PROTOCOL, wait="5s"
input_parser.MEV_BOOST_PORT, shared_utils.TCP_PROTOCOL, wait="5s"
)
}
......@@ -43,7 +43,7 @@ def launch(
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
mev_boost_service.ip_address, input_parser.MEV_BOOST_PORT
)
......@@ -66,9 +66,7 @@ def get_config(
# latest-notes
# does this need genesis time to be set as well
"GENESIS_FORK_VERSION": "0x10000038",
"BOOST_LISTEN_ADDR": "0.0.0.0:{0}".format(
input_parser.FLASHBOTS_MEV_BOOST_PORT
),
"BOOST_LISTEN_ADDR": "0.0.0.0:{0}".format(input_parser.MEV_BOOST_PORT),
# maybe this is breaking; this isn't verifyign the bid and not sending it to the validator
"SKIP_RELAY_SIGNATURE_CHECK": "1",
"RELAYS": mev_boost_launcher.relay_end_points[0],
......
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")
DUMMY_SECRET_KEY = "0x607a11b45a7219cc61a3d9c5fd08c7eebd602a6a19a977f8d3771d5711a550f2"
DUMMY_PUB_KEY = "0xa55c1285d84ba83a5ad26420cd5ad3091e49c55a813eee651cd467db38a8c8e63192f47955e9376f6b42f6d190571cb5"
constants = import_module("../../../package_io/constants.star")
MEV_RELAY_WEBSITE = "mev-relay-website"
MEV_RELAY_ENDPOINT = "mev-relay-api"
......@@ -129,7 +126,7 @@ def launch_mev_relay(
"--db",
postgres_url,
"--secret-key",
DUMMY_SECRET_KEY,
constants.DEFAULT_MEV_SECRET_KEY,
"--listen-addr",
"0.0.0.0:{0}".format(MEV_RELAY_ENDPOINT_PORT),
"--redis-uri",
......@@ -168,7 +165,9 @@ def launch_mev_relay(
"0.0.0.0:{0}".format(MEV_RELAY_WEBSITE_PORT),
"--redis-uri",
redis_url,
"https://{0}@{1}".format(DUMMY_PUB_KEY, MEV_RELAY_ENDPOINT),
"https://{0}@{1}".format(
constants.DEFAULT_MEV_PUBKEY, MEV_RELAY_ENDPOINT
),
]
+ mev_params.mev_relay_website_extra_args,
ports={
......@@ -188,5 +187,5 @@ def launch_mev_relay(
)
return "http://{0}@{1}:{2}".format(
DUMMY_PUB_KEY, api.ip_address, MEV_RELAY_ENDPOINT_PORT
constants.DEFAULT_MEV_PUBKEY, api.ip_address, MEV_RELAY_ENDPOINT_PORT
)
constants = import_module("../../../package_io/constants.star")
MOCK_MEV_IMAGE = "ethpandaops/mock-builder:latest"
MOCK_MEV_SERVICE_NAME = "mock-mev"
MOCK_MEV_BUILDER_PORT = 18550
DEFAULT_MOCK_MEV_PUB_KEY = "0x95fde78acd5f6886ddaf5d0056610167c513d09c1c0efabbc7cdcc69beea113779c4a81e2d24daafc5387dbf6ac5fe48"
# The min/max CPU/memory that mev-mock-builder can use
MIN_CPU = 100
......@@ -42,5 +43,5 @@ def launch_mock_mev(
),
)
return "http://{0}@{1}:{2}".format(
DEFAULT_MOCK_MEV_PUB_KEY, mock_builder.ip_address, MOCK_MEV_BUILDER_PORT
constants.DEFAULT_MEV_PUBKEY, mock_builder.ip_address, MOCK_MEV_BUILDER_PORT
)
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")
MEV_BOOST_CONFIG_FILENAME = "config.toml"
MEV_BOOST_MOUNT_DIRPATH_ON_SERVICE = "/config"
MEV_BOOST_FILES_ARTIFACT_NAME = "mev-rs-mev-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_DATA_MOUNTPOINT_ON_CLIENTS
)
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.MEV_RS_MEV_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[
MEV_BOOST_CONFIG_FILENAME
] = template_and_data
config_files_artifact_name = plan.render_templates(
template_and_data_by_rel_dest_filepath,
MEV_BOOST_FILES_ARTIFACT_NAME + service_name,
)
config_file_path = shared_utils.path_join(
MEV_BOOST_MOUNT_DIRPATH_ON_SERVICE, MEV_BOOST_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=[
"boost",
config_file_path,
],
files={
MEV_BOOST_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,
}
shared_utils = import_module("../../../shared_utils/shared_utils.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")
mev_rs_relay = import_module("../mev_relay/mev_relay_launcher.star")
# MEV Builder flags
MEV_BUILDER_CONFIG_FILENAME = "config.toml"
MEV_BUILDER_MOUNT_DIRPATH_ON_SERVICE = "/config"
MEV_BUILDER_FILES_ARTIFACT_NAME = "mev-rs-mev-builder-config"
MEV_FILE_PATH_ON_CONTAINER = (
MEV_BUILDER_MOUNT_DIRPATH_ON_SERVICE + MEV_BUILDER_CONFIG_FILENAME
)
def new_builder_config(
plan,
service_name,
network,
fee_recipient,
mnemonic,
extra_data,
global_node_selectors,
):
builder_template_data = new_builder_config_template_data(
network,
constants.DEFAULT_MEV_PUBKEY,
constants.DEFAULT_MEV_SECRET_KEY,
mnemonic,
fee_recipient,
extra_data,
)
mev_rs_builder_config_template = read_file(
static_files.MEV_RS_MEV_BUILDER_CONFIG_FILEPATH
)
template_and_data = shared_utils.new_template_and_data(
mev_rs_builder_config_template, builder_template_data
)
template_and_data_by_rel_dest_filepath = {}
template_and_data_by_rel_dest_filepath[
MEV_BUILDER_CONFIG_FILENAME
] = template_and_data
config_files_artifact_name = plan.render_templates(
template_and_data_by_rel_dest_filepath, MEV_BUILDER_FILES_ARTIFACT_NAME
)
config_file_path = shared_utils.path_join(
MEV_BUILDER_MOUNT_DIRPATH_ON_SERVICE, MEV_BUILDER_CONFIG_FILENAME
)
return config_files_artifact_name
def new_builder_config_template_data(
network,
pubkey,
secret,
mnemonic,
fee_recipient,
extra_data,
):
return {
"Network": network,
"Relay": "mev-rs-relay",
"RelayPort": mev_rs_relay.MEV_RELAY_ENDPOINT_PORT,
"PublicKey": pubkey,
"SecretKey": secret,
"Mnemonic": mnemonic,
"FeeRecipient": fee_recipient,
"ExtraData": extra_data,
}
shared_utils = import_module("../../../shared_utils/shared_utils.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")
MEV_RELAY_CONFIG_FILENAME = "config.toml"
MEV_RELAY_MOUNT_DIRPATH_ON_SERVICE = "/config"
MEV_RELAY_FILES_ARTIFACT_NAME = "mev-rs-relay-config"
MEV_RELAY_ENDPOINT_PORT = 28545
USED_PORTS = {
"http": shared_utils.new_port_spec(
MEV_RELAY_ENDPOINT_PORT,
"TCP",
)
}
# The min/max CPU/memory that mev-relay can use
MIN_CPU = 10
MAX_CPU = 500
MIN_MEMORY = 16
MAX_MEMORY = 256
def launch_mev_relay(
plan,
mev_params,
network,
beacon_uri,
el_cl_genesis_data,
global_node_selectors,
):
node_selectors = global_node_selectors
image = mev_params.mev_relay_image
network = (
network
if network in constants.PUBLIC_NETWORKS
else constants.GENESIS_DATA_MOUNTPOINT_ON_CLIENTS
)
relay_template_data = new_relay_config_template_data(
network,
MEV_RELAY_ENDPOINT_PORT,
beacon_uri,
constants.DEFAULT_MEV_PUBKEY,
constants.DEFAULT_MEV_SECRET_KEY,
)
mev_rs_relay_config_template = read_file(
static_files.MEV_RS_MEV_RELAY_CONFIG_FILEPATH
)
template_and_data = shared_utils.new_template_and_data(
mev_rs_relay_config_template, relay_template_data
)
template_and_data_by_rel_dest_filepath = {}
template_and_data_by_rel_dest_filepath[
MEV_RELAY_CONFIG_FILENAME
] = template_and_data
config_files_artifact_name = plan.render_templates(
template_and_data_by_rel_dest_filepath, MEV_RELAY_FILES_ARTIFACT_NAME
)
config_file_path = shared_utils.path_join(
MEV_RELAY_MOUNT_DIRPATH_ON_SERVICE, MEV_RELAY_CONFIG_FILENAME
)
mev_relay_service = plan.add_service(
name="mev-rs-relay",
config=ServiceConfig(
image=image,
cmd=[
"relay",
config_file_path,
],
files={
MEV_RELAY_MOUNT_DIRPATH_ON_SERVICE: config_files_artifact_name,
constants.GENESIS_DATA_MOUNTPOINT_ON_CLIENTS: el_cl_genesis_data,
},
ports=USED_PORTS,
min_cpu=MIN_CPU,
max_cpu=MAX_CPU,
min_memory=MIN_MEMORY,
max_memory=MAX_MEMORY,
node_selectors=node_selectors,
env_vars={"RUST_BACKTRACE": "1"},
),
)
return (
"http://{0}@{1}:{2}".format(
constants.DEFAULT_MEV_PUBKEY,
mev_relay_service.ip_address,
MEV_RELAY_ENDPOINT_PORT,
),
mev_relay_service.ip_address,
MEV_RELAY_ENDPOINT_PORT,
)
def new_relay_config_template_data(network, port, beacon_uri, pubkey, secret):
return {
"Network": network,
"Port": port,
"BeaconNodeURL": beacon_uri,
"PublicKey": pubkey,
"SecretKey": secret,
}
EL_TYPE = struct(
gethbuilder="geth-builder",
geth_builder="geth-builder",
geth="geth",
erigon="erigon",
nethermind="nethermind",
besu="besu",
reth="reth",
reth_builder="reth-builder",
ethereumjs="ethereumjs",
nimbus="nimbus",
)
......@@ -60,12 +61,21 @@ KEYMANAGER_MOUNT_PATH_ON_CLIENTS = "/keymanager"
KEYMANAGER_MOUNT_PATH_ON_CONTAINER = (
KEYMANAGER_MOUNT_PATH_ON_CLIENTS + "/keymanager.txt"
)
KEYMANAGER_P12_MOUNT_PATH_ON_CLIENTS = "/keymanager-p12"
KEYMANAGER_P12_MOUNT_PATH_ON_CONTAINER = (
KEYMANAGER_P12_MOUNT_PATH_ON_CLIENTS + "/validator_keystore.p12"
)
MOCK_MEV_TYPE = "mock"
FLASHBOTS_MEV_TYPE = "flashbots"
MEV_RS_MEV_TYPE = "mev-rs"
DEFAULT_SNOOPER_IMAGE = "ethpandaops/rpc-snooper:latest"
DEFAULT_FLASHBOTS_RELAY_IMAGE = "flashbots/mev-boost-relay:0.27"
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_MEV_PUBKEY = "0xa55c1285d84ba83a5ad26420cd5ad3091e49c55a813eee651cd467db38a8c8e63192f47955e9376f6b42f6d190571cb5"
DEFAULT_MEV_SECRET_KEY = (
"0x607a11b45a7219cc61a3d9c5fd08c7eebd602a6a19a977f8d3771d5711a550f2"
)
PRIVATE_IP_ADDRESS_PLACEHOLDER = "KURTOSIS_IP_ADDR_PLACEHOLDER"
......@@ -77,7 +87,7 @@ ELECTRA_FORK_VERSION = "0x60000038"
ETHEREUM_GENESIS_GENERATOR = struct(
capella_genesis="ethpandaops/ethereum-genesis-generator:2.0.12", # Deprecated (no support for minimal config)
deneb_genesis="ethpandaops/ethereum-genesis-generator:3.0.3", # Default
deneb_genesis="ethpandaops/ethereum-genesis-generator:3.0.5", # Default
verkle_support_genesis="ethpandaops/ethereum-genesis-generator:3.0.0-rc.19", # soon to be deneb genesis, waiting for rebase
verkle_genesis="ethpandaops/ethereum-genesis-generator:verkle-gen-v1.0.0",
)
......
This diff is collapsed.
......@@ -337,6 +337,7 @@ def launch_participant_network(
global_tolerations=global_tolerations,
node_selectors=node_selectors,
keymanager_enabled=participant.keymanager_enabled,
preset=network_params.preset,
network=network_params.network,
electra_fork_epoch=network_params.electra_fork_epoch,
)
......
......@@ -77,8 +77,16 @@ CL_GENESIS_GENERATION_MNEMONICS_TEMPLATE_FILEPATH = (
JWT_PATH_FILEPATH = STATIC_FILES_DIRPATH + "/jwt/jwtsecret"
KEYMANAGER_PATH_FILEPATH = STATIC_FILES_DIRPATH + "/keymanager/keymanager.txt"
KEYMANAGER_P12_PATH_FILEPATH = (
STATIC_FILES_DIRPATH + "/keymanager/validator_keystore.p12"
)
SHADOWFORK_FILEPATH = "/network-configs/latest_block.json"
MEV_RS_MEV_BOOST_CONFIG_FILEPATH = (
STATIC_FILES_DIRPATH + "/mev/mev-rs/mev_boost/config.toml.tmpl"
)
MEV_RS_MEV_RELAY_CONFIG_FILEPATH = (
STATIC_FILES_DIRPATH + "/mev/mev-rs/mev_relay/config.toml.tmpl"
)
MEV_RS_MEV_BUILDER_CONFIG_FILEPATH = (
STATIC_FILES_DIRPATH + "/mev/mev-rs/mev_builder/config.toml.tmpl"
)
......@@ -33,11 +33,7 @@ def get_config(
electra_fork_epoch,
node_selectors,
):
# Temp hack to use the old tx-fuzz image until we can get the new one working
if electra_fork_epoch != None:
tx_spammer_image = "ethpandaops/tx-fuzz:kaustinen-281adbc"
else:
tx_spammer_image = "ethpandaops/tx-fuzz:master"
tx_spammer_image = "ethpandaops/tx-fuzz:master"
cmd = [
"spam",
......
......@@ -33,6 +33,7 @@ def get_config(
tolerations,
node_selectors,
keymanager_enabled,
preset,
):
log_level = input_parser.get_client_log_level_or_default(
participant_log_level, global_log_level, VERBOSITY_LEVELS
......@@ -93,6 +94,9 @@ def get_config(
cmd.extend(keymanager_api_cmd)
ports.update(vc_shared.VALIDATOR_KEYMANAGER_USED_PORTS)
if preset == "minimal":
extra_env_vars["LODESTAR_PRESET"] = "minimal"
return ServiceConfig(
image=image,
ports=ports,
......
......@@ -46,6 +46,7 @@ def launch(
global_tolerations,
node_selectors,
keymanager_enabled,
preset,
network, # TODO: remove when deneb rebase is done
electra_fork_epoch, # TODO: remove when deneb rebase is done
):
......@@ -116,6 +117,7 @@ def launch(
tolerations=tolerations,
node_selectors=node_selectors,
keymanager_enabled=keymanager_enabled,
preset=preset,
)
elif vc_type == constants.VC_TYPE.teku:
config = teku.get_config(
......
network = "{{ .Network }}"
[boost]
host = "0.0.0.0"
port = {{ .Port }}
relays = [
{{ range $relays := .Relays }}
"{{ $relays }}",
{{- end }}
]
network = "{{ .Network }}"
[builder]
# number of milliseconds to submit bids ahead of the target slot
bidding_deadline_ms = 1000
# amount of value to bid as a fraction of the payload's revenue
bid_percent = 0.9
# amount to add to the bid on top of the payload's revenue,
# currently sourced from the builder's wallet authoring the payment transaction
subsidy_gwei = 100000000 # 0.1 eth
[builder.auctioneer]
# builder BLS secret key
secret_key = "{{ .SecretKey }}"
# list of relays to connect to
relays = [
"http://{{ .PublicKey }}@{{ .Relay }}:{{ .RelayPort }}",
]
[builder.builder]
# address to collect transaction fees
fee_recipient = "{{ .FeeRecipient }}"
# [optional] extra data to write into built execution payload
extra_data = "{{ .ExtraData }}"
# wallet seed for builder to author payment transactions
execution_mnemonic = "{{ .Mnemonic }}"
[builder.bidder]
# amount in milliseconds of time to wait until submitting bids
wait_until_ms = 3000
# [optional] amount of value to bid as a fraction of the payload's revenue
# if missing, defaults to 1.0 (100%)
# validation: should be between [0, 1] inclusive.
bid_percent = 0.9
# [optional] amount to add to the bid on top of the payload's revenue,
# if missing, defaults to 0 wei
# currently sourced from the builder's wallet authoring the payment transaction
subsidy_wei = "0x0000000000000000000000000000000000000000000000000000000000000001"
network = "{{ .Network }}"
[relay]
host = "0.0.0.0"
port = {{ .Port }}
beacon_node_url = "{{ .BeaconNodeURL }}"
secret_key = "{{ .SecretKey }}"
accepted_builders = [
"{{ .PublicKey }}",
]
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