Skip to content

Commit 7fcd3e2

Browse files
authored
feat: launch the mock mev builder (#94)
1 parent 07ed500 commit 7fcd3e2

File tree

5 files changed

+106
-34
lines changed

5 files changed

+106
-34
lines changed

README.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,13 @@ To configure the package behaviour, you can modify your `eth2-package-params.yam
174174
// The global log level that all clients should log at
175175
// Valid values are "error", "warn", "info", "debug", and "trace"
176176
// This value will be overridden by participant-specific values
177-
"global_client_log_level": "info"
177+
"global_client_log_level": "info",
178+
179+
// Supports three valeus
180+
// Default: None - no mev boost, mev builder, mev flood or relays are spun up
181+
// mock - mock-builder & mev-boost are spun up
182+
// full - mev-boost, relays, flooder and builder are all spun up
183+
"mev_type": None
178184
}
179185
```
180186
</details>

main.star

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ prometheus = import_module("github.com/kurtosis-tech/eth2-package/src/prometheus
1010
grafana =import_module("github.com/kurtosis-tech/eth2-package/src/grafana/grafana_launcher.star")
1111
testnet_verifier = import_module("github.com/kurtosis-tech/eth2-package/src/testnet_verifier/testnet_verifier.star")
1212
mev_boost_launcher_module = import_module("github.com/kurtosis-tech/eth2-package/src/mev_boost/mev_boost_launcher.star")
13+
mock_mev_launcher_module = import_module("github.com/kurtosis-tech/eth2-package/src/mock_mev/mock_mev_launcher.star")
1314

1415
GRAFANA_USER = "admin"
1516
GRAFANA_PASSWORD = "admin"
@@ -18,11 +19,11 @@ GRAFANA_DASHBOARD_PATH_URL = "/d/QdTOwy-nz/eth2-merge-kurtosis-module-dashboard?
1819
FIRST_NODE_FINALIZATION_FACT = "cl-boot-finalization-fact"
1920
HTTP_PORT_ID_FOR_FACT = "http"
2021

21-
MEV_BOOST_SERVICE_NAME_PREFIX = "mev-boost-"
2222
MEV_BOOST_SHOULD_CHECK_RELAY = True
23+
MOCK_MEV_TYPE = "mock"
2324

2425
def run(plan, args):
25-
args_with_right_defaults = parse_input.parse_input(args)
26+
args_with_right_defaults, args_with_defaults_dict = parse_input.parse_input(args)
2627

2728
num_participants = len(args_with_right_defaults.participants)
2829
network_params = args_with_right_defaults.network_params
@@ -34,22 +35,35 @@ def run(plan, args):
3435
plan.print("Read the prometheus, grafana templates")
3536

3637
plan.print("Launching participant network with {0} participants and the following network params {1}".format(num_participants, network_params))
37-
all_participants, cl_genesis_timestamp = eth_network_module.run(plan, args)
38+
all_participants, cl_genesis_timestamp = eth_network_module.run(plan, args_with_defaults_dict)
3839

3940
all_el_client_contexts = []
4041
all_cl_client_contexts = []
4142
for participant in all_participants:
4243
all_el_client_contexts.append(participant.el_client_context)
4344
all_cl_client_contexts.append(participant.cl_client_context)
44-
45-
# spin up mev boost contexts
45+
46+
47+
mev_endpoints = []
48+
# passed external relays get priority
49+
# perhaps add mev_type External or remove this
50+
if hasattr(participant, "builder_network_params") and participant.builder_network_params != None:
51+
mev_endpoints = participant.builder_network_params.relay_end_points
52+
# otherwise dummy relays spinup if chosen
53+
elif args_with_right_defaults.mev_type and args_with_right_defaults.mev_type == MOCK_MEV_TYPE:
54+
el_uri = "{0}:{1}".format(all_el_client_contexts[0].ip_addr, all_el_client_contexts[0].engine_rpc_port_num)
55+
beacon_uri = "{0}:{1}".format(all_cl_client_contexts[0].ip_addr, all_cl_client_contexts[0].http_port_num)
56+
jwt_secret = all_el_client_contexts[0].jwt_secret
57+
endpoint = mock_mev_launcher_module.launch_mock_mev(plan, el_uri, beacon_uri, jwt_secret)
58+
mev_endpoints.append(endpoint)
59+
60+
# spin up the mev boost contexts if some endpoints for relays have been passed
4661
all_mevboost_contexts = []
47-
for index, participant in enumerate(args_with_right_defaults.participants):
48-
mev_boost_context = None
49-
if hasattr(participant, "builder_network_params") and participant.builder_network_params != None:
50-
mev_boost_launcher = mev_boost_launcher_module.new_mev_boost_launcher(MEV_BOOST_SHOULD_CHECK_RELAY, participant.builder_network_params.relay_endpoints)
51-
mev_boost_service_name = "{0}{1}".format(MEV_BOOST_SERVICE_NAME_PREFIX, index)
52-
mev_boost_context = mev_boost_launcher_module.launch_mevboost(plan, mev_boost_launcher, mev_boost_service_name, network_params.network_id)
62+
if mev_endpoints:
63+
for index, participant in enumerate(args_with_right_defaults.participants):
64+
mev_boost_launcher = mev_boost_launcher_module.new_mev_boost_launcher(MEV_BOOST_SHOULD_CHECK_RELAY, mev_endpoints)
65+
mev_boost_service_name = "{0}{1}".format(parse_input.MEV_BOOST_SERVICE_NAME_PREFIX, index)
66+
mev_boost_context = mev_boost_launcher_module.launch(plan, mev_boost_launcher, mev_boost_service_name, network_params.network_id)
5367
all_mevboost_contexts.append(mev_boost_context)
5468

5569
if not args_with_right_defaults.launch_additional_services:
@@ -108,6 +122,5 @@ def run(plan, args):
108122
password = GRAFANA_PASSWORD
109123
)
110124
output = struct(grafana_info = grafana_info)
111-
return output
112-
113125

126+
return output

src/mev_boost/mev_boost_launcher.star

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
shared_utils = import_module("github.com/kurtosis-tech/eth2-package/src/shared_utils/shared_utils.star")
2-
mev_boost_context = ("github.com/kurtosis-tech/eth2-package/src/mev_boost/mev_boost_context.star")
2+
mev_boost_context_module = import_module("github.com/kurtosis-tech/eth2-package/src/mev_boost/mev_boost_context.star")
3+
parse_input = import_module("github.com/kurtosis-tech/eth2-package/src/package_io/parse_input.star")
34

45
FLASHBOTS_MEV_BOOST_IMAGE = "flashbots/mev-boost"
5-
FLASHBOTS_MEV_BOOST_PORT = 18550
66
FLASHBOTS_MEV_BOOST_PROTOCOL = "TCP"
77

88
USED_PORTS = {
9-
"api": shared_utils.new_port_spec(FLASHBOTS_MEV_BOOST_PORT, FLASHBOTS_MEV_BOOST_PROTOCOL)
9+
"api": shared_utils.new_port_spec(parse_input.FLASHBOTS_MEV_BOOST_PORT, FLASHBOTS_MEV_BOOST_PROTOCOL, wait="5s")
1010
}
1111

1212
NETWORK_ID_TO_NAME = {
@@ -20,26 +20,27 @@ def launch(plan, mev_boost_launcher, service_name, network_id):
2020

2121
mev_boost_service = plan.add_service(service_name, config)
2222

23-
return mev_boost_context.new_mev_boost_context(mev_boost_service.ip_address, FLASHBOTS_MEV_BOOST_PORT)
23+
return mev_boost_context_module.new_mev_boost_context(mev_boost_service.ip_address, parse_input.FLASHBOTS_MEV_BOOST_PORT)
2424

2525

2626
def get_config(mev_boost_launcher, network_id):
27-
network_name = NETWORK_ID_TO_NAME.get(network_id, "network-{0}".format(network_id))
28-
2927
command = ["mev-boost"]
30-
command.append("-{0}".format(network_name))
3128

3229
if mev_boost_launcher.should_check_relay:
3330
command.append("-relay-check")
3431

35-
if len(mev_boost_launcher.relay_end_points) != 0:
36-
command.append("-relays")
37-
command.append(",".join(mev_boost_launcher.relay_end_points))
38-
3932
return ServiceConfig(
4033
image = FLASHBOTS_MEV_BOOST_IMAGE,
4134
ports = USED_PORTS,
42-
cmd = command
35+
cmd = command,
36+
env_vars = {
37+
# TODO remove the hardcoding
38+
# This is set to match this file https://github.com/kurtosis-tech/eth-network-package/blob/main/static_files/genesis-generation-config/cl/config.yaml.tmpl#L11
39+
"GENESIS_FORK_VERSION": "0x10000038",
40+
"BOOST_LISTEN_ADDR": "0.0.0.0:{0}".format(parse_input.FLASHBOTS_MEV_BOOST_PORT),
41+
"SKIP_RELAY_SIGNATURE_CHECK": "true",
42+
"RELAYS": mev_boost_launcher.relay_end_points[0]
43+
}
4344
)
4445

4546

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MOCK_MEV_IMAGE = "ethpandaops/mock-builder:latest"
2+
MOCK_MEV_SERVICE_NAME = "mock-mev"
3+
MOCK_MEV_BUILDER_PORT = 18550
4+
DUMMY_PUB_KEY_THAT_ISNT_VERIFIED = "0xae1c2ca7bbd6f415a5aa5bb4079caf0a5c273104be5fb5e40e2b5a2f080b2f5bd945336f2a9e8ba346299cb65b0f84c8"
5+
6+
def launch_mock_mev(plan, el_uri, beacon_uri, jwt_secret):
7+
mock_builder = plan.add_service(
8+
name = MOCK_MEV_SERVICE_NAME,
9+
config = ServiceConfig(
10+
image = MOCK_MEV_IMAGE,
11+
ports = {
12+
"rest": PortSpec(number = MOCK_MEV_BUILDER_PORT, transport_protocol="TCP"),
13+
},
14+
cmd = [
15+
"--jwt-secret={0}".format(jwt_secret),
16+
"--el={0}".format(el_uri),
17+
"--cl={0}".format(beacon_uri)
18+
]
19+
)
20+
)
21+
return "http://{0}@{1}:{2}".format(DUMMY_PUB_KEY_THAT_ISNT_VERIFIED, mock_builder.ip_address, MOCK_MEV_BUILDER_PORT)

src/package_io/parse_input.star

Lines changed: 39 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,28 @@
11
DEFAULT_EL_IMAGES = {
2-
"geth": "ethereum/client-go:latest",
2+
"geth": "ethereum/client-go:v1.11.5",
33
"erigon": "thorax/erigon:devel",
4-
"nethermind": "nethermind/nethermind:latest",
4+
"nethermind": "nethermind/nethermind:1.14.0",
55
"besu": "hyperledger/besu:develop"
66
}
77

88
DEFAULT_CL_IMAGES = {
9-
"lighthouse": "sigp/lighthouse:latest",
10-
"teku": "consensys/teku:latest",
9+
"lighthouse": "sigp/lighthouse:v3.5.0",
10+
"teku": "consensys/teku:23.1",
1111
"nimbus": "statusim/nimbus-eth2:multiarch-latest",
12-
"prysm": "gcr.io/prysmaticlabs/prysm/beacon-chain:latest,gcr.io/prysmaticlabs/prysm/validator:latest",
13-
"lodestar": "chainsafe/lodestar:next",
12+
"prysm": "prysmaticlabs/prysm/beacon-chain:latest,prysmaticlabs/prysm/validator:latest",
13+
"lodestar": "chainsafe/lodestar:v1.7.2",
1414
}
1515

1616
BESU_NODE_NAME = "besu"
1717
NETHERMIND_NODE_NAME = "nethermind"
1818

1919
ATTR_TO_BE_SKIPPED_AT_ROOT = ("network_params", "participants")
2020

21+
# MEV Params
22+
FLASHBOTS_MEV_BOOST_PORT = 18550
23+
MEV_BOOST_SERVICE_NAME_PREFIX = "mev-boost-"
24+
25+
2126
def parse_input(input_args):
2227
result = default_input_args()
2328
for attr in input_args:
@@ -100,6 +105,9 @@ def parse_input(input_args):
100105
if len(result["participants"]) >= 2 and result["participants"][1]["el_client_type"] == NETHERMIND_NODE_NAME:
101106
fail("nethermind can't be the first or second node")
102107

108+
if result.get("mev_type") in ("mock", "full"):
109+
result = enrich_mev_extra_params(result, MEV_BOOST_SERVICE_NAME_PREFIX, FLASHBOTS_MEV_BOOST_PORT)
110+
103111
return struct(
104112
participants=[struct(
105113
el_client_type=participant["el_client_type"],
@@ -128,8 +136,9 @@ def parse_input(input_args):
128136
wait_for_finalization=result["wait_for_finalization"],
129137
wait_for_verifications=result["wait_for_verifications"],
130138
verifications_epoch_limit=result["verifications_epoch_limit"],
131-
global_client_log_level=result["global_client_log_level"]
132-
)
139+
global_client_log_level=result["global_client_log_level"],
140+
mev_type=result["mev_type"],
141+
), result
133142

134143
def get_client_log_level_or_default(participant_log_level, global_log_level, client_log_levels):
135144
log_level = participant_log_level
@@ -143,6 +152,7 @@ def default_input_args():
143152
network_params = default_network_params()
144153
participants = [default_participant()]
145154
return {
155+
"mev_type": None,
146156
"participants": participants,
147157
"network_params": network_params,
148158
"launch_additional_services" : True,
@@ -179,3 +189,24 @@ def default_participant():
179189
"validator_extra_params": [],
180190
"builder_network_params": None
181191
}
192+
193+
194+
# TODO perhaps clean this up into a map
195+
def enrich_mev_extra_params(parsed_arguments_dict, mev_prefix, mev_port):
196+
for index, participant in enumerate(parsed_arguments_dict["participants"]):
197+
mev_url = "http://{0}{1}:{2}".format(mev_prefix, index, mev_port)
198+
if participant["cl_client_type"] == "lighthouse":
199+
participant["validator_extra_params"].append("--builder-proposals")
200+
participant["beacon_extra_params"].append("--builder={0}".format(mev_url))
201+
if participant["cl_client_type"] == "lodestar":
202+
participant["validator_extra_params"].append("--builder")
203+
participant["beacon_extra_params"].append("--builder", "--builder.urls={0}".format(mev_url))
204+
if participant["cl_client_type"] == "nimbus":
205+
participant["validator_extra_params"].append("--payload-builder=true")
206+
participant["beacon_extra_params"].append("--payload-builder=true", "--payload-builder-urs={0}".format(mev_url))
207+
if participant["cl_client_type"] == "teku":
208+
participant["beacon_extra_params"].append("--validators-builder-registration-default-enabled=true", "--builder-endpoint=".format(mev_url))
209+
if participant["cl_client_type"] == "prysm":
210+
participant["validator_extra_params"].append("--enable-builder")
211+
participant["beacon_extra_params"].append("--http-mev-relay={0}".format(mev_url))
212+
return parsed_arguments_dict

0 commit comments

Comments
 (0)