Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions .github/tests/skip.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
participants:
- cl_type: prysm

- cl_type: lighthouse
checkpoint_sync_enabled: true
skip_start: true
validator_count: 1

- cl_type: teku
checkpoint_sync_enabled: true
skip_start: true
validator_count: 1

- cl_type: lodestar
checkpoint_sync_enabled: true
skip_start: true
validator_count: 1

- cl_type: grandine
checkpoint_sync_enabled: true
skip_start: true
validator_count: 1

network_params:
seconds_per_slot: 4
preset: minimal
additional_services:
- dora
- checkpointz

7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -518,6 +518,13 @@ participants:
# Defaults to null (uses global checkpoint_sync_enabled setting)
checkpoint_sync_enabled: null

# If set to true, the beacon node will be created and then immediately stopped.
# No health checks are performed during creation (ready_conditions are disabled).
# The service can be started later using: kurtosis service start <enclave> <service-name>
# This is useful for testing or when you want to manually control when the beacon node starts.
# Defaults to false
skip_start: false

# Participants matrix creates a participant for each combination of EL, CL and VC clients
# Each EL/CL/VC item can provide the same parameters as a standard participant
participants_matrix: {}
Expand Down
9 changes: 8 additions & 1 deletion src/cl/cl_launcher.star
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,14 @@ def launch(
checkpoint_sync_enabled = participant.checkpoint_sync_enabled
if checkpoint_sync_enabled:
if args_with_right_defaults.checkpoint_sync_url == "":
if (
if network_params.network == constants.NETWORK_NAME.kurtosis:
if "checkpointz" in args_with_right_defaults.additional_services:
checkpoint_sync_url = "http://checkpointz:5555"
else:
fail(
"Checkpoint sync URL is required if you enabled checkpoint_sync for kurtosis network. Please enable checkpointz additional service."
)
elif (
network_params.network in constants.PUBLIC_NETWORKS
or network_params.network == constants.NETWORK_NAME.ephemery
):
Expand Down
51 changes: 32 additions & 19 deletions src/cl/grandine/grandine_launcher.star
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,11 @@ def get_beacon_config(
constants.HTTP_PORT_ID: BEACON_HTTP_PORT_NUM,
constants.METRICS_PORT_ID: BEACON_METRICS_PORT_NUM,
}
used_ports = shared_utils.get_port_specs(used_port_assignments)
# Disable port checks if skip_start is enabled
if participant.skip_start:
used_ports = shared_utils.get_port_specs(used_port_assignments, wait=None)
else:
used_ports = shared_utils.get_port_specs(used_port_assignments)

cmd = [
GRANDINE_ENTRYPOINT_COMMAND,
Expand Down Expand Up @@ -343,9 +347,6 @@ def get_beacon_config(
"files": files,
"env_vars": participant.cl_extra_env_vars,
"private_ip_address_placeholder": constants.PRIVATE_IP_ADDRESS_PLACEHOLDER,
"ready_conditions": cl_node_ready_conditions.get_ready_conditions(
constants.HTTP_PORT_ID
),
"labels": shared_utils.label_maker(
client=constants.CL_TYPE.grandine,
client_type=constants.CLIENT_TYPES.cl,
Expand All @@ -360,6 +361,12 @@ def get_beacon_config(
"user": User(uid=0, gid=0),
}

# Only add ready_conditions if not skipping start
if not participant.skip_start:
config_args["ready_conditions"] = cl_node_ready_conditions.get_ready_conditions(
constants.HTTP_PORT_ID
)

if int(participant.cl_min_cpu) > 0:
config_args["min_cpu"] = int(participant.cl_min_cpu)
if int(participant.cl_max_cpu) > 0:
Expand All @@ -386,21 +393,27 @@ def get_cl_context(
beacon_metrics_port = service.ports[constants.METRICS_PORT_ID]
beacon_metrics_url = "{0}:{1}".format(service.name, beacon_metrics_port.number)

beacon_node_identity_recipe = GetHttpRequestRecipe(
endpoint="/eth/v1/node/identity",
port_id=constants.HTTP_PORT_ID,
extract={
"enr": ".data.enr",
"multiaddr": ".data.p2p_addresses[0]",
"peer_id": ".data.peer_id",
},
)
response = plan.request(
recipe=beacon_node_identity_recipe, service_name=service_name
)
beacon_node_enr = response["extract.enr"]
beacon_multiaddr = response["extract.multiaddr"]
beacon_peer_id = response["extract.peer_id"]
# Skip HTTP requests if skip_start is enabled (service won't be running)
if participant.skip_start:
beacon_node_enr = ""
beacon_multiaddr = ""
beacon_peer_id = ""
else:
beacon_node_identity_recipe = GetHttpRequestRecipe(
endpoint="/eth/v1/node/identity",
port_id=constants.HTTP_PORT_ID,
extract={
"enr": ".data.enr",
"multiaddr": ".data.p2p_addresses[0]",
"peer_id": ".data.peer_id",
},
)
response = plan.request(
recipe=beacon_node_identity_recipe, service_name=service_name
)
beacon_node_enr = response["extract.enr"]
beacon_multiaddr = response["extract.multiaddr"]
beacon_peer_id = response["extract.peer_id"]

beacon_node_metrics_info = node_metrics.new_node_metrics_info(
service_name, BEACON_METRICS_PATH, beacon_metrics_url
Expand Down
54 changes: 34 additions & 20 deletions src/cl/lighthouse/lighthouse_launcher.star
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,11 @@ def get_beacon_config(
constants.HTTP_PORT_ID: BEACON_HTTP_PORT_NUM,
constants.METRICS_PORT_ID: BEACON_METRICS_PORT_NUM,
}
used_ports = shared_utils.get_port_specs(used_port_assignments)
# Disable port checks if skip_start is enabled
if participant.skip_start:
used_ports = shared_utils.get_port_specs(used_port_assignments, wait=None)
else:
used_ports = shared_utils.get_port_specs(used_port_assignments)
cmd = [
LIGHTHOUSE_ENTRYPOINT_COMMAND,
"beacon_node",
Expand Down Expand Up @@ -307,6 +311,7 @@ def get_beacon_config(

env_vars = {RUST_BACKTRACE_ENVVAR_NAME: RUST_FULL_BACKTRACE_KEYWORD}
env_vars.update(participant.cl_extra_env_vars)

config_args = {
"image": participant.cl_image,
"ports": used_ports,
Expand All @@ -316,9 +321,6 @@ def get_beacon_config(
"files": files,
"env_vars": env_vars,
"private_ip_address_placeholder": constants.PRIVATE_IP_ADDRESS_PLACEHOLDER,
"ready_conditions": cl_node_ready_conditions.get_ready_conditions(
constants.HTTP_PORT_ID
),
"labels": shared_utils.label_maker(
client=constants.CL_TYPE.lighthouse,
client_type=constants.CLIENT_TYPES.cl,
Expand All @@ -332,6 +334,12 @@ def get_beacon_config(
"node_selectors": node_selectors,
}

# Only add ready_conditions if not skipping start
if not participant.skip_start:
config_args["ready_conditions"] = cl_node_ready_conditions.get_ready_conditions(
constants.HTTP_PORT_ID
)

if int(participant.cl_min_cpu) > 0:
config_args["min_cpu"] = int(participant.cl_min_cpu)
if int(participant.cl_max_cpu) > 0:
Expand All @@ -355,22 +363,28 @@ def get_cl_context(
beacon_http_port = service.ports[constants.HTTP_PORT_ID]
beacon_http_url = "http://{0}:{1}".format(service.name, beacon_http_port.number)

# TODO(old) add validator availability using the validator API: https://ethereum.github.io/beacon-APIs/?urls.primaryName=v1#/ValidatorRequiredApi | from eth2-merge-kurtosis-module
beacon_node_identity_recipe = GetHttpRequestRecipe(
endpoint="/eth/v1/node/identity",
port_id=constants.HTTP_PORT_ID,
extract={
"enr": ".data.enr",
"multiaddr": ".data.p2p_addresses[0]",
"peer_id": ".data.peer_id",
},
)
response = plan.request(
recipe=beacon_node_identity_recipe, service_name=service_name
)
beacon_node_enr = response["extract.enr"]
beacon_multiaddr = response["extract.multiaddr"]
beacon_peer_id = response["extract.peer_id"]
# Skip HTTP requests if skip_start is enabled (service won't be running)
if participant.skip_start:
beacon_node_enr = ""
beacon_multiaddr = ""
beacon_peer_id = ""
else:
# TODO(old) add validator availability using the validator API: https://ethereum.github.io/beacon-APIs/?urls.primaryName=v1#/ValidatorRequiredApi | from eth2-merge-kurtosis-module
beacon_node_identity_recipe = GetHttpRequestRecipe(
endpoint="/eth/v1/node/identity",
port_id=constants.HTTP_PORT_ID,
extract={
"enr": ".data.enr",
"multiaddr": ".data.p2p_addresses[0]",
"peer_id": ".data.peer_id",
},
)
response = plan.request(
recipe=beacon_node_identity_recipe, service_name=service_name
)
beacon_node_enr = response["extract.enr"]
beacon_multiaddr = response["extract.multiaddr"]
beacon_peer_id = response["extract.peer_id"]

beacon_metrics_port = service.ports[constants.METRICS_PORT_ID]
beacon_metrics_url = "{0}:{1}".format(service.name, beacon_metrics_port.number)
Expand Down
54 changes: 33 additions & 21 deletions src/cl/lodestar/lodestar_launcher.star
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,11 @@ def get_beacon_config(
constants.HTTP_PORT_ID: BEACON_HTTP_PORT_NUM,
constants.METRICS_PORT_ID: BEACON_METRICS_PORT_NUM,
}
used_ports = shared_utils.get_port_specs(used_port_assignments)
# Disable port checks if skip_start is enabled
if participant.skip_start:
used_ports = shared_utils.get_port_specs(used_port_assignments, wait=None)
else:
used_ports = shared_utils.get_port_specs(used_port_assignments)

cmd = [
LODESTAR_ENTRYPOINT_COMMAND,
Expand Down Expand Up @@ -296,9 +300,6 @@ def get_beacon_config(
"files": files,
"env_vars": env_vars,
"private_ip_address_placeholder": constants.PRIVATE_IP_ADDRESS_PLACEHOLDER,
"ready_conditions": cl_node_ready_conditions.get_ready_conditions(
constants.HTTP_PORT_ID
),
"labels": shared_utils.label_maker(
client=constants.CL_TYPE.lodestar,
client_type=constants.CLIENT_TYPES.cl,
Expand All @@ -312,6 +313,12 @@ def get_beacon_config(
"node_selectors": node_selectors,
}

# Only add ready_conditions if not skipping start
if not participant.skip_start:
config_args["ready_conditions"] = cl_node_ready_conditions.get_ready_conditions(
constants.HTTP_PORT_ID
)

if int(participant.cl_min_cpu) > 0:
config_args["min_cpu"] = int(participant.cl_min_cpu)
if int(participant.cl_max_cpu) > 0:
Expand All @@ -336,23 +343,28 @@ def get_cl_context(

beacon_http_url = "http://{0}:{1}".format(service.name, beacon_http_port.number)

# TODO(old) add validator availability using the validator API: https://ethereum.github.io/beacon-APIs/?urls.primaryName=v1#/ValidatorRequiredApi | from eth2-merge-kurtosis-module

beacon_node_identity_recipe = GetHttpRequestRecipe(
endpoint="/eth/v1/node/identity",
port_id=constants.HTTP_PORT_ID,
extract={
"enr": ".data.enr",
"multiaddr": ".data.p2p_addresses[-1]",
"peer_id": ".data.peer_id",
},
)
response = plan.request(
recipe=beacon_node_identity_recipe, service_name=service_name
)
beacon_node_enr = response["extract.enr"]
beacon_multiaddr = response["extract.multiaddr"]
beacon_peer_id = response["extract.peer_id"]
# Skip HTTP requests if skip_start is enabled (service won't be running)
if participant.skip_start:
beacon_node_enr = ""
beacon_multiaddr = ""
beacon_peer_id = ""
else:
# TODO(old) add validator availability using the validator API: https://ethereum.github.io/beacon-APIs/?urls.primaryName=v1#/ValidatorRequiredApi | from eth2-merge-kurtosis-module
beacon_node_identity_recipe = GetHttpRequestRecipe(
endpoint="/eth/v1/node/identity",
port_id=constants.HTTP_PORT_ID,
extract={
"enr": ".data.enr",
"multiaddr": ".data.p2p_addresses[-1]",
"peer_id": ".data.peer_id",
},
)
response = plan.request(
recipe=beacon_node_identity_recipe, service_name=service_name
)
beacon_node_enr = response["extract.enr"]
beacon_multiaddr = response["extract.multiaddr"]
beacon_peer_id = response["extract.peer_id"]

beacon_metrics_port = service.ports[constants.METRICS_PORT_ID]
beacon_metrics_url = "{0}:{1}".format(service.name, beacon_metrics_port.number)
Expand Down
51 changes: 32 additions & 19 deletions src/cl/nimbus/nimbus_launcher.star
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,11 @@ def get_beacon_config(
constants.HTTP_PORT_ID: BEACON_HTTP_PORT_NUM,
constants.METRICS_PORT_ID: BEACON_METRICS_PORT_NUM,
}
used_ports = shared_utils.get_port_specs(used_port_assignments)
# Disable port checks if skip_start is enabled
if participant.skip_start:
used_ports = shared_utils.get_port_specs(used_port_assignments, wait=None)
else:
used_ports = shared_utils.get_port_specs(used_port_assignments)

nimbus_checkpoint_sync_subtask_str = "{0} trustedNodeSync --data-dir={1} --trusted-node-url={2} --network={3} --backfill=false".format(
BEACON_NODE_ENTRYPOINT,
Expand Down Expand Up @@ -353,9 +357,6 @@ def get_beacon_config(
"files": files,
"env_vars": participant.cl_extra_env_vars,
"private_ip_address_placeholder": constants.PRIVATE_IP_ADDRESS_PLACEHOLDER,
"ready_conditions": cl_node_ready_conditions.get_ready_conditions(
constants.HTTP_PORT_ID
),
"labels": shared_utils.label_maker(
client=constants.CL_TYPE.nimbus,
client_type=constants.CLIENT_TYPES.cl,
Expand All @@ -370,6 +371,12 @@ def get_beacon_config(
"user": User(uid=0, gid=0),
}

# Only add ready_conditions if not skipping start
if not participant.skip_start:
config_args["ready_conditions"] = cl_node_ready_conditions.get_ready_conditions(
constants.HTTP_PORT_ID
)

if int(participant.cl_min_cpu) > 0:
config_args["min_cpu"] = int(participant.cl_min_cpu)
if int(participant.cl_max_cpu) > 0:
Expand All @@ -395,21 +402,27 @@ def get_cl_context(
beacon_http_url = "http://{0}:{1}".format(service.name, beacon_http_port.number)
beacon_metrics_url = "{0}:{1}".format(service.name, beacon_metrics_port.number)

beacon_node_identity_recipe = GetHttpRequestRecipe(
endpoint="/eth/v1/node/identity",
port_id=constants.HTTP_PORT_ID,
extract={
"enr": ".data.enr",
"multiaddr": ".data.p2p_addresses[0]",
"peer_id": ".data.peer_id",
},
)
response = plan.request(
recipe=beacon_node_identity_recipe, service_name=service_name
)
beacon_node_enr = response["extract.enr"]
beacon_multiaddr = response["extract.multiaddr"]
beacon_peer_id = response["extract.peer_id"]
# Skip HTTP requests if skip_start is enabled (service won't be running)
if participant.skip_start:
beacon_node_enr = ""
beacon_multiaddr = ""
beacon_peer_id = ""
else:
beacon_node_identity_recipe = GetHttpRequestRecipe(
endpoint="/eth/v1/node/identity",
port_id=constants.HTTP_PORT_ID,
extract={
"enr": ".data.enr",
"multiaddr": ".data.p2p_addresses[0]",
"peer_id": ".data.peer_id",
},
)
response = plan.request(
recipe=beacon_node_identity_recipe, service_name=service_name
)
beacon_node_enr = response["extract.enr"]
beacon_multiaddr = response["extract.multiaddr"]
beacon_peer_id = response["extract.peer_id"]

nimbus_node_metrics_info = node_metrics.new_node_metrics_info(
service_name, BEACON_METRICS_PATH, beacon_metrics_url
Expand Down
Loading