diff --git a/.github/tests/split-nimbus.yaml b/.github/tests/split-nimbus.yaml new file mode 100644 index 000000000..b7c14a4c0 --- /dev/null +++ b/.github/tests/split-nimbus.yaml @@ -0,0 +1,21 @@ +participants: + - el_client_type: geth + cl_client_type: nimbus + cl_split_mode_enabled: true + validator_count: 0 + - el_client_type: nethermind + cl_client_type: nimbus + cl_split_mode_enabled: true + - el_client_type: erigon + cl_client_type: nimbus + cl_split_mode_enabled: true + - el_client_type: besu + cl_client_type: nimbus + cl_split_mode_enabled: true + - el_client_type: reth + cl_client_type: nimbus + cl_split_mode_enabled: true + - el_client_type: ethereumjs + cl_client_type: nimbus + cl_split_mode_enabled: true +additional_services: [] diff --git a/README.md b/README.md index c74315eea..220a334b1 100644 --- a/README.md +++ b/README.md @@ -147,6 +147,11 @@ participants: # over a specific participant's logging cl_client_log_level: "" + # A list of optional extra params that will be passed to the CL to run separate Beacon and validator nodes + # Only possible for nimbus or teku (coming soon) + # Defaults to false + cl_split_mode_enabled: false + # A list of optional extra params that will be passed to the CL client Beacon container for modifying its behaviour # If the client combines the Beacon & validator nodes (e.g. Teku, Nimbus), then this list will be passed to the combined Beacon-validator node beacon_extra_params: [] diff --git a/src/cl/lighthouse/lighthouse_launcher.star b/src/cl/lighthouse/lighthouse_launcher.star index 1ed6fdfb9..8730a8ca1 100644 --- a/src/cl/lighthouse/lighthouse_launcher.star +++ b/src/cl/lighthouse/lighthouse_launcher.star @@ -121,6 +121,7 @@ def launch( extra_validator_params, extra_beacon_labels, extra_validator_labels, + split_mode_enabled=False, ): beacon_node_service_name = "{0}".format(service_name) validator_node_service_name = "{0}-{1}".format( diff --git a/src/cl/lodestar/lodestar_launcher.star b/src/cl/lodestar/lodestar_launcher.star index 934c934ad..bf0dd096d 100644 --- a/src/cl/lodestar/lodestar_launcher.star +++ b/src/cl/lodestar/lodestar_launcher.star @@ -97,6 +97,7 @@ def launch( extra_validator_params, extra_beacon_labels, extra_validator_labels, + split_mode_enabled=False, ): beacon_node_service_name = "{0}".format(service_name) validator_node_service_name = "{0}-{1}".format( diff --git a/src/cl/nimbus/nimbus_launcher.star b/src/cl/nimbus/nimbus_launcher.star index 0a110ff88..9e6220b0a 100644 --- a/src/cl/nimbus/nimbus_launcher.star +++ b/src/cl/nimbus/nimbus_launcher.star @@ -1,23 +1,22 @@ +# ---------------------------------- Library Imports ---------------------------------- shared_utils = import_module("../../shared_utils/shared_utils.star") input_parser = import_module("../../package_io/input_parser.star") cl_client_context = import_module("../../cl/cl_client_context.star") -node_metrics = import_module("../../node_metrics_info.star") cl_node_ready_conditions = import_module("../../cl/cl_node_ready_conditions.star") - +node_metrics = import_module("../../node_metrics_info.star") constants = import_module("../../package_io/constants.star") -VALIDATOR_KEYS_MOUNTPOINT_ON_CLIENT = "/validator-keys" - +# ---------------------------------- Beacon client ------------------------------------- # Port IDs -TCP_DISCOVERY_PORT_ID = "tcp-discovery" -UDP_DISCOVERY_PORT_ID = "udp-discovery" -HTTP_PORT_ID = "http" -METRICS_PORT_ID = "metrics" +BEACON_TCP_DISCOVERY_PORT_ID = "tcp-discovery" +BEACON_UDP_DISCOVERY_PORT_ID = "udp-discovery" +BEACON_HTTP_PORT_ID = "http" +BEACON_METRICS_PORT_ID = "metrics" # Port nums -DISCOVERY_PORT_NUM = 9000 -HTTP_PORT_NUM = 4000 -METRICS_PORT_NUM = 8008 +BEACON_DISCOVERY_PORT_NUM = 9000 +BEACON_HTTP_PORT_NUM = 4000 +BEACON_METRICS_PORT_NUM = 8008 # The min/max CPU/memory that the beacon node can use BEACON_MIN_CPU = 50 @@ -25,6 +24,34 @@ BEACON_MAX_CPU = 1000 BEACON_MIN_MEMORY = 128 BEACON_MAX_MEMORY = 1024 +DEFAULT_BEACON_IMAGE_ENTRYPOINT = ["nimbus_beacon_node"] + +BEACON_METRICS_PATH = "/metrics" + +# ---------------------------------- Validator client ------------------------------------- +VALIDATOR_KEYS_MOUNTPOINT_ON_CLIENTS = "/validator-keys" +VALIDATOR_HTTP_PORT_ID = "http" +VALIDATOR_METRICS_PORT_ID = "metrics" +VALIDATOR_HTTP_PORT_NUM = 5042 +VALIDATOR_METRICS_PORT_NUM = 5064 +VALIDATOR_HTTP_PORT_WAIT_DISABLED = None + +VALIDATOR_SUFFIX_SERVICE_NAME = "validator" + +# The min/max CPU/memory that the validator node can use +VALIDATOR_MIN_CPU = 50 +VALIDATOR_MAX_CPU = 300 +VALIDATOR_MIN_MEMORY = 128 +VALIDATOR_MAX_MEMORY = 512 + +DEFAULT_VALIDATOR_IMAGE_ENTRYPOINT = ["nimbus_validator_client"] + +VALIDATOR_METRICS_PATH = "/metrics" + +VALIDATOR_KEYS_DIRPATH_ON_SERVICE_CONTAINER = "$HOME/validator-keys" +VALIDATOR_SECRETS_DIRPATH_ON_SERVICE_CONTAINER = "$HOME/validator-secrets" + +# ---------------------------------- Genesis Files ---------------------------------- # Nimbus requires that its data directory already exists (because it expects you to bind-mount it), so we # have to to create it @@ -32,31 +59,48 @@ CONSENSUS_DATA_DIRPATH_IN_SERVICE_CONTAINER = "$HOME/consensus-data" # Nimbus wants the data dir to have these perms CONSENSUS_DATA_DIR_PERMS_STR = "0700" -# The entrypoint the image normally starts with (we need to override the entrypoint to create the -# consensus data directory on the image before it starts) -DEFAULT_IMAGE_ENTRYPOINT = "/home/user/nimbus-eth2/build/nimbus_beacon_node" # Nimbus needs write access to the validator keys/secrets directories, and b/c the module container runs as root # while the Nimbus container does not, we can't just point the Nimbus binary to the paths in the shared dir because # it won't be able to open them. To get around this, we copy the validator keys/secrets to a path inside the Nimbus # container that is owned by the container's user -VALIDATOR_KEYS_DIRPATH_ON_SERVICE_CONTAINER = "$HOME/validator-keys" -VALIDATOR_SECRETS_DIRPATH_ON_SERVICE_CONTAINER = "$HOME/validator-secrets" -METRICS_PATH = "/metrics" +# ---------------------------------- Metrics ---------------------------------- -PRIVATE_IP_ADDRESS_PLACEHOLDER = "KURTOSIS_IP_ADDR_PLACEHOLDER" -USED_PORTS = { - TCP_DISCOVERY_PORT_ID: shared_utils.new_port_spec( - DISCOVERY_PORT_NUM, shared_utils.TCP_PROTOCOL +# ---------------------------------- Used Ports ---------------------------------- +PRIVATE_IP_ADDRESS_PLACEHOLDER = "KURTOSIS_IP_ADDR_PLACEHOLDER" +BEACON_USED_PORTS = { + BEACON_TCP_DISCOVERY_PORT_ID: shared_utils.new_port_spec( + BEACON_DISCOVERY_PORT_NUM, shared_utils.TCP_PROTOCOL + ), + BEACON_UDP_DISCOVERY_PORT_ID: shared_utils.new_port_spec( + BEACON_DISCOVERY_PORT_NUM, shared_utils.UDP_PROTOCOL + ), + BEACON_HTTP_PORT_ID: shared_utils.new_port_spec( + BEACON_HTTP_PORT_NUM, + shared_utils.TCP_PROTOCOL, + shared_utils.HTTP_APPLICATION_PROTOCOL, ), - UDP_DISCOVERY_PORT_ID: shared_utils.new_port_spec( - DISCOVERY_PORT_NUM, shared_utils.UDP_PROTOCOL + BEACON_METRICS_PORT_ID: shared_utils.new_port_spec( + BEACON_METRICS_PORT_NUM, + shared_utils.TCP_PROTOCOL, + shared_utils.HTTP_APPLICATION_PROTOCOL, + ), +} + + +VALIDATOR_USED_PORTS = { + VALIDATOR_HTTP_PORT_ID: shared_utils.new_port_spec( + VALIDATOR_HTTP_PORT_NUM, + shared_utils.TCP_PROTOCOL, + shared_utils.NOT_PROVIDED_APPLICATION_PROTOCOL, + VALIDATOR_HTTP_PORT_WAIT_DISABLED, ), - HTTP_PORT_ID: shared_utils.new_port_spec(HTTP_PORT_NUM, shared_utils.TCP_PROTOCOL), - METRICS_PORT_ID: shared_utils.new_port_spec( - METRICS_PORT_NUM, shared_utils.TCP_PROTOCOL + VALIDATOR_METRICS_PORT_ID: shared_utils.new_port_spec( + VALIDATOR_METRICS_PORT_NUM, + shared_utils.TCP_PROTOCOL, + shared_utils.HTTP_APPLICATION_PROTOCOL, ), } @@ -97,29 +141,23 @@ def launch( extra_validator_params, extra_beacon_labels, extra_validator_labels, + split_mode_enabled, ): + beacon_node_service_name = "{0}".format(service_name) + validator_node_service_name = "{0}-{1}".format( + service_name, VALIDATOR_SUFFIX_SERVICE_NAME + ) + log_level = input_parser.get_client_log_level_or_default( participant_log_level, global_log_level, NIMBUS_LOG_LEVELS ) - extra_params = [param for param in extra_beacon_params] + [ - param for param in extra_validator_params - ] - bn_min_cpu = int(bn_min_cpu) if int(bn_min_cpu) > 0 else BEACON_MIN_CPU bn_max_cpu = int(bn_max_cpu) if int(bn_max_cpu) > 0 else BEACON_MAX_CPU bn_min_mem = int(bn_min_mem) if int(bn_min_mem) > 0 else BEACON_MIN_MEMORY bn_max_mem = int(bn_max_mem) if int(bn_max_mem) > 0 else BEACON_MAX_MEMORY - # Set the min/max CPU/memory for the beacon node to be the max of the beacon node and validator node values, unless this is defined, it will use the default beacon values - bn_min_cpu = int(v_min_cpu) if (int(v_min_cpu) > bn_min_cpu) else bn_min_cpu - bn_max_cpu = int(v_max_cpu) if (int(v_max_cpu) > bn_max_cpu) else bn_max_cpu - bn_min_mem = int(v_min_mem) if (int(v_min_mem) > bn_min_mem) else bn_min_mem - bn_max_mem = int(v_max_mem) if (int(v_max_mem) > bn_max_mem) else bn_max_mem - - extra_labels = extra_beacon_labels | extra_validator_labels - - config = get_config( + beacon_config = get_beacon_config( launcher.el_cl_genesis_data, image, bootnode_contexts, @@ -130,51 +168,99 @@ def launch( bn_max_cpu, bn_min_mem, bn_max_mem, + beacon_node_service_name, snooper_enabled, snooper_engine_context, - extra_params, - extra_labels, + extra_beacon_params, + extra_beacon_labels, + split_mode_enabled, ) - nimbus_service = plan.add_service(service_name, config) + beacon_service = plan.add_service(beacon_node_service_name, beacon_config) + beacon_http_port = beacon_service.ports[BEACON_HTTP_PORT_ID] + beacon_metrics_port = beacon_service.ports[BEACON_METRICS_PORT_ID] + beacon_http_url = "http://{0}:{1}".format( + beacon_service.ip_address, beacon_http_port.number + ) + beacon_metrics_url = "{0}:{1}".format( + beacon_service.ip_address, beacon_metrics_port.number + ) - cl_node_identity_recipe = GetHttpRequestRecipe( + beacon_node_identity_recipe = GetHttpRequestRecipe( endpoint="/eth/v1/node/identity", - port_id=HTTP_PORT_ID, + port_id=BEACON_HTTP_PORT_ID, extract={ "enr": ".data.enr", "multiaddr": ".data.discovery_addresses[0]", "peer_id": ".data.peer_id", }, ) - response = plan.request(recipe=cl_node_identity_recipe, service_name=service_name) - node_enr = response["extract.enr"] - multiaddr = response["extract.multiaddr"] - peer_id = response["extract.peer_id"] - - metrics_port = nimbus_service.ports[METRICS_PORT_ID] - metrics_url = "{0}:{1}".format(nimbus_service.ip_address, metrics_port.number) + 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, METRICS_PATH, metrics_url + service_name, BEACON_METRICS_PATH, beacon_metrics_url ) nodes_metrics_info = [nimbus_node_metrics_info] + # Launch validator node if we have a keystore + validator_service = None + if node_keystore_files != None and split_mode_enabled: + v_min_cpu = int(v_min_cpu) if int(v_min_cpu) > 0 else VALIDATOR_MIN_CPU + v_max_cpu = int(v_max_cpu) if int(v_max_cpu) > 0 else VALIDATOR_MAX_CPU + v_min_mem = int(v_min_mem) if int(v_min_mem) > 0 else VALIDATOR_MIN_MEMORY + v_max_mem = int(v_max_mem) if int(v_max_mem) > 0 else VALIDATOR_MAX_MEMORY + + validator_config = get_validator_config( + launcher.el_cl_genesis_data, + image, + log_level, + beacon_http_url, + el_client_context, + node_keystore_files, + v_min_cpu, + v_max_cpu, + v_min_mem, + v_max_mem, + validator_node_service_name, + extra_validator_params, + extra_validator_labels, + ) + + validator_service = plan.add_service( + validator_node_service_name, validator_config + ) + + if validator_service: + validator_metrics_port = validator_service.ports[VALIDATOR_METRICS_PORT_ID] + validator_metrics_url = "{0}:{1}".format( + validator_service.ip_address, validator_metrics_port.number + ) + validator_node_metrics_info = node_metrics.new_node_metrics_info( + validator_node_service_name, VALIDATOR_METRICS_PATH, validator_metrics_url + ) + nodes_metrics_info.append(validator_node_metrics_info) + return cl_client_context.new_cl_client_context( "nimbus", - node_enr, - nimbus_service.ip_address, - HTTP_PORT_NUM, + beacon_node_enr, + beacon_service.ip_address, + BEACON_HTTP_PORT_NUM, nodes_metrics_info, - service_name, - multiaddr=multiaddr, - peer_id=peer_id, - snooper_enabled=snooper_enabled, - snooper_engine_context=snooper_engine_context, + beacon_node_service_name, + validator_node_service_name, + beacon_multiaddr, + beacon_peer_id, + snooper_enabled, + snooper_engine_context, ) -def get_config( +def get_beacon_config( el_cl_genesis_data, image, bootnode_contexts, @@ -185,11 +271,24 @@ def get_config( bn_max_cpu, bn_min_mem, bn_max_mem, + beacon_node_service_name, snooper_enabled, snooper_engine_context, extra_params, extra_labels, + split_mode_enabled, ): + validator_keys_dirpath = "" + validator_secrets_dirpath = "" + if node_keystore_files != None: + validator_keys_dirpath = shared_utils.path_join( + VALIDATOR_KEYS_MOUNTPOINT_ON_CLIENTS, + node_keystore_files.nimbus_keys_relative_dirpath, + ) + validator_secrets_dirpath = shared_utils.path_join( + VALIDATOR_KEYS_MOUNTPOINT_ON_CLIENTS, + node_keystore_files.raw_secrets_relative_dirpath, + ) # If snooper is enabled use the snooper engine context, otherwise use the execution client context if snooper_enabled: EXECUTION_ENGINE_ENDPOINT = "http://{0}:{1}".format( @@ -202,60 +301,11 @@ def get_config( el_client_context.engine_rpc_port_num, ) - validator_keys_dirpath = "" - validator_secrets_dirpath = "" - if node_keystore_files != None: - validator_keys_dirpath = shared_utils.path_join( - VALIDATOR_KEYS_MOUNTPOINT_ON_CLIENT, - node_keystore_files.nimbus_keys_relative_dirpath, - ) - validator_secrets_dirpath = shared_utils.path_join( - VALIDATOR_KEYS_MOUNTPOINT_ON_CLIENT, - node_keystore_files.raw_secrets_relative_dirpath, - ) - - # Sources for these flags: - # 1) https://github.com/status-im/nimbus-eth2/blob/stable/scripts/launch_local_testnet.sh - # 2) https://github.com/status-im/nimbus-eth2/blob/67ab477a27e358d605e99bffeb67f98d18218eca/scripts/launch_local_testnet.sh#L417 - # WARNING: Do NOT set the --max-peers flag here, as doing so to the exact number of nodes seems to mess things up! - # See: https://github.com/kurtosis-tech/eth2-merge-kurtosis-module/issues/26 - validator_copy = [ - "mkdir", - CONSENSUS_DATA_DIRPATH_IN_SERVICE_CONTAINER, - "-m", - CONSENSUS_DATA_DIR_PERMS_STR, - "&&", - # TODO(old) COMMENT THIS OUT? - "cp", - "-R", - validator_keys_dirpath, - VALIDATOR_KEYS_DIRPATH_ON_SERVICE_CONTAINER, - "&&", - "cp", - "-R", - validator_secrets_dirpath, - VALIDATOR_SECRETS_DIRPATH_ON_SERVICE_CONTAINER, - "&&", - # If we don't do this chmod, Nimbus will spend a crazy amount of time manually correcting them - # before it starts - "chmod", - "600", - VALIDATOR_SECRETS_DIRPATH_ON_SERVICE_CONTAINER + "/*", - "&&", - ] - - validator_flags = [ - "--validators-dir=" + VALIDATOR_KEYS_DIRPATH_ON_SERVICE_CONTAINER, - "--secrets-dir=" + VALIDATOR_SECRETS_DIRPATH_ON_SERVICE_CONTAINER, - "--suggested-fee-recipient=" + constants.VALIDATING_REWARDS_ACCOUNT, - ] - - beacon_start = [ - DEFAULT_IMAGE_ENTRYPOINT, + cmd = [ "--non-interactive=true", "--log-level=" + log_level, - "--udp-port={0}".format(DISCOVERY_PORT_NUM), - "--tcp-port={0}".format(DISCOVERY_PORT_NUM), + "--udp-port={0}".format(BEACON_DISCOVERY_PORT_NUM), + "--tcp-port={0}".format(BEACON_DISCOVERY_PORT_NUM), "--network=" + constants.GENESIS_CONFIG_MOUNT_PATH_ON_CONTAINER, "--data-dir=" + CONSENSUS_DATA_DIRPATH_IN_SERVICE_CONTAINER, "--web3-url=" + EXECUTION_ENGINE_ENDPOINT, @@ -265,7 +315,7 @@ def get_config( "--rest", "--rest-address=0.0.0.0", "--rest-allow-origin=*", - "--rest-port={0}".format(HTTP_PORT_NUM), + "--rest-port={0}".format(BEACON_HTTP_PORT_NUM), # There's a bug where if we don't set this flag, the Nimbus nodes won't work: # https://discord.com/channels/641364059387854899/674288681737256970/922890280120750170 # https://github.com/status-im/nimbus-eth2/issues/2451 @@ -278,18 +328,19 @@ def get_config( # vvvvvvvvvvvvvvvvvvv METRICS CONFIG vvvvvvvvvvvvvvvvvvvvv "--metrics", "--metrics-address=0.0.0.0", - "--metrics-port={0}".format(METRICS_PORT_NUM), + "--metrics-port={0}".format(BEACON_METRICS_PORT_NUM), # ^^^^^^^^^^^^^^^^^^^ METRICS CONFIG ^^^^^^^^^^^^^^^^^^^^^ ] - # Depending on whether we're using a node keystore, we'll need to add the validator flags - cmd = [] - if node_keystore_files != None: - cmd.extend(validator_copy) - cmd.extend(beacon_start) + validator_flags = [ + "--validators-dir=" + validator_keys_dirpath, + "--secrets-dir=" + validator_secrets_dirpath, + "--suggested-fee-recipient=" + constants.VALIDATING_REWARDS_ACCOUNT, + "--graffiti=" + beacon_node_service_name, + ] + + if node_keystore_files != None and not split_mode_enabled: cmd.extend(validator_flags) - else: - cmd.extend(beacon_start) if bootnode_contexts == None: # Copied from https://github.com/status-im/nimbus-eth2/blob/67ab477a27e358d605e99bffeb67f98d18218eca/scripts/launch_local_testnet.sh#L417 @@ -308,17 +359,18 @@ def get_config( } if node_keystore_files: files[ - VALIDATOR_KEYS_MOUNTPOINT_ON_CLIENT + VALIDATOR_KEYS_MOUNTPOINT_ON_CLIENTS ] = node_keystore_files.files_artifact_uuid - cmd_str = " ".join(cmd) + return ServiceConfig( image=image, - ports=USED_PORTS, - cmd=[cmd_str], - entrypoint=ENTRYPOINT_ARGS, + ports=BEACON_USED_PORTS, + cmd=cmd, files=files, private_ip_address_placeholder=PRIVATE_IP_ADDRESS_PLACEHOLDER, - ready_conditions=cl_node_ready_conditions.get_ready_conditions(HTTP_PORT_ID), + ready_conditions=cl_node_ready_conditions.get_ready_conditions( + BEACON_HTTP_PORT_ID + ), min_cpu=bn_min_cpu, max_cpu=bn_max_cpu, min_memory=bn_min_mem, @@ -333,6 +385,71 @@ def get_config( ) +def get_validator_config( + el_cl_genesis_data, + image, + log_level, + beacon_http_url, + el_client_context, + node_keystore_files, + v_min_cpu, + v_max_cpu, + v_min_mem, + v_max_mem, + validator_node_service_name, + extra_params, + extra_labels, +): + validator_keys_dirpath = "" + validator_secrets_dirpath = "" + if node_keystore_files != None: + validator_keys_dirpath = shared_utils.path_join( + VALIDATOR_KEYS_MOUNTPOINT_ON_CLIENTS, + node_keystore_files.nimbus_keys_relative_dirpath, + ) + validator_secrets_dirpath = shared_utils.path_join( + VALIDATOR_KEYS_MOUNTPOINT_ON_CLIENTS, + node_keystore_files.raw_secrets_relative_dirpath, + ) + + cmd = [ + "--beacon-node=" + beacon_http_url, + "--validators-dir=" + validator_keys_dirpath, + "--secrets-dir=" + validator_secrets_dirpath, + "--suggested-fee-recipient=" + constants.VALIDATING_REWARDS_ACCOUNT, + # vvvvvvvvvvvvvvvvvvv METRICS CONFIG vvvvvvvvvvvvvvvvvvvvv + "--metrics", + "--metrics-address=0.0.0.0", + "--metrics-port={0}".format(VALIDATOR_METRICS_PORT_NUM), + "--graffiti=" + validator_node_service_name, + ] + + if len(extra_params) > 0: + cmd.extend([param for param in extra_params if param != "--split=true"]) + + return ServiceConfig( + image=image, + ports=VALIDATOR_USED_PORTS, + cmd=cmd, + entrypoint=DEFAULT_VALIDATOR_IMAGE_ENTRYPOINT, + files={ + VALIDATOR_KEYS_MOUNTPOINT_ON_CLIENTS: node_keystore_files.files_artifact_uuid + }, + private_ip_address_placeholder=PRIVATE_IP_ADDRESS_PLACEHOLDER, + min_cpu=v_min_cpu, + max_cpu=v_max_cpu, + min_memory=v_min_mem, + max_memory=v_max_mem, + labels=shared_utils.label_maker( + constants.CL_CLIENT_TYPE.nimbus, + constants.CLIENT_TYPES.validator, + image, + el_client_context.client_name, + extra_labels, + ), + ) + + def new_nimbus_launcher(el_cl_genesis_data): return struct( el_cl_genesis_data=el_cl_genesis_data, diff --git a/src/cl/prysm/prysm_launcher.star b/src/cl/prysm/prysm_launcher.star index 191256246..d60965e7e 100644 --- a/src/cl/prysm/prysm_launcher.star +++ b/src/cl/prysm/prysm_launcher.star @@ -109,6 +109,7 @@ def launch( extra_validator_params, extra_beacon_labels, extra_validator_labels, + split_mode_enabled=False, ): split_images = images.split(IMAGE_SEPARATOR_DELIMITER) if len(split_images) != EXPECTED_NUM_IMAGES: diff --git a/src/cl/teku/teku_launcher.star b/src/cl/teku/teku_launcher.star index d3a2e5e15..ce1cd4e09 100644 --- a/src/cl/teku/teku_launcher.star +++ b/src/cl/teku/teku_launcher.star @@ -98,6 +98,7 @@ def launch( extra_validator_params, extra_beacon_labels, extra_validator_labels, + split_mode_enabled, ): log_level = input_parser.get_client_log_level_or_default( participant_log_level, global_log_level, TEKU_LOG_LEVELS diff --git a/src/package_io/input_parser.star b/src/package_io/input_parser.star index 92992b580..8b13e9d50 100644 --- a/src/package_io/input_parser.star +++ b/src/package_io/input_parser.star @@ -16,7 +16,7 @@ DEFAULT_EL_IMAGES = { DEFAULT_CL_IMAGES = { "lighthouse": "sigp/lighthouse:latest", "teku": "consensys/teku:latest", - "nimbus": "statusim/nimbus-eth2:multiarch-latest", + "nimbus": "ethpandaops/nimbus:unstable", "prysm": "prysmaticlabs/prysm-beacon-chain:latest,prysmaticlabs/prysm-validator:latest", "lodestar": "chainsafe/lodestar:latest", } @@ -125,6 +125,7 @@ def input_parser(plan, input_args): cl_client_type=participant["cl_client_type"], cl_client_image=participant["cl_client_image"], cl_client_log_level=participant["cl_client_log_level"], + cl_split_mode_enabled=participant["cl_split_mode_enabled"], beacon_extra_params=participant["beacon_extra_params"], beacon_extra_labels=participant["beacon_extra_labels"], validator_extra_params=participant["validator_extra_params"], @@ -252,6 +253,17 @@ def parse_network_params(input_args): result["network_params"]["seconds_per_slot"] < 12 ): fail("nimbus can't be run with slot times below 12 seconds") + + if participant["cl_split_mode_enabled"] and cl_client_type not in ( + "nimbus", + "teku", + ): + fail( + "split mode is only supported for nimbus and teku clients, but you specified {0}".format( + cl_client_type + ) + ) + el_image = participant["el_client_image"] if el_image == "": default_image = DEFAULT_EL_IMAGES.get(el_client_type, "") @@ -421,6 +433,7 @@ def default_participant(): "cl_client_type": "lighthouse", "cl_client_image": "", "cl_client_log_level": "", + "cl_split_mode_enabled": False, "beacon_extra_params": [], "beacon_extra_labels": {}, "validator_extra_params": [], diff --git a/src/participant_network.star b/src/participant_network.star index 0905c4308..e1af33661 100644 --- a/src/participant_network.star +++ b/src/participant_network.star @@ -340,6 +340,7 @@ def launch_participant_network( participant.validator_extra_params, participant.beacon_extra_labels, participant.validator_extra_labels, + participant.cl_split_mode_enabled, ) else: boot_cl_client_ctx = all_cl_client_contexts @@ -369,6 +370,7 @@ def launch_participant_network( participant.validator_extra_params, participant.beacon_extra_labels, participant.validator_extra_labels, + participant.cl_split_mode_enabled, ) # Add participant cl additional prometheus labels