Commit cb33648d authored by Barnabas Busa's avatar Barnabas Busa Committed by GitHub

feat: split nimbus CL-validator (#404)

parent 21eae3b5
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: []
...@@ -147,6 +147,11 @@ participants: ...@@ -147,6 +147,11 @@ participants:
# over a specific participant's logging # over a specific participant's logging
cl_client_log_level: "" 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 # 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 # 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: [] beacon_extra_params: []
......
...@@ -121,6 +121,7 @@ def launch( ...@@ -121,6 +121,7 @@ def launch(
extra_validator_params, extra_validator_params,
extra_beacon_labels, extra_beacon_labels,
extra_validator_labels, extra_validator_labels,
split_mode_enabled=False,
): ):
beacon_node_service_name = "{0}".format(service_name) beacon_node_service_name = "{0}".format(service_name)
validator_node_service_name = "{0}-{1}".format( validator_node_service_name = "{0}-{1}".format(
......
...@@ -97,6 +97,7 @@ def launch( ...@@ -97,6 +97,7 @@ def launch(
extra_validator_params, extra_validator_params,
extra_beacon_labels, extra_beacon_labels,
extra_validator_labels, extra_validator_labels,
split_mode_enabled=False,
): ):
beacon_node_service_name = "{0}".format(service_name) beacon_node_service_name = "{0}".format(service_name)
validator_node_service_name = "{0}-{1}".format( validator_node_service_name = "{0}-{1}".format(
......
# ---------------------------------- Library Imports ----------------------------------
shared_utils = import_module("../../shared_utils/shared_utils.star") shared_utils = import_module("../../shared_utils/shared_utils.star")
input_parser = import_module("../../package_io/input_parser.star") input_parser = import_module("../../package_io/input_parser.star")
cl_client_context = import_module("../../cl/cl_client_context.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") 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") constants = import_module("../../package_io/constants.star")
VALIDATOR_KEYS_MOUNTPOINT_ON_CLIENT = "/validator-keys" # ---------------------------------- Beacon client -------------------------------------
# Port IDs # Port IDs
TCP_DISCOVERY_PORT_ID = "tcp-discovery" BEACON_TCP_DISCOVERY_PORT_ID = "tcp-discovery"
UDP_DISCOVERY_PORT_ID = "udp-discovery" BEACON_UDP_DISCOVERY_PORT_ID = "udp-discovery"
HTTP_PORT_ID = "http" BEACON_HTTP_PORT_ID = "http"
METRICS_PORT_ID = "metrics" BEACON_METRICS_PORT_ID = "metrics"
# Port nums # Port nums
DISCOVERY_PORT_NUM = 9000 BEACON_DISCOVERY_PORT_NUM = 9000
HTTP_PORT_NUM = 4000 BEACON_HTTP_PORT_NUM = 4000
METRICS_PORT_NUM = 8008 BEACON_METRICS_PORT_NUM = 8008
# The min/max CPU/memory that the beacon node can use # The min/max CPU/memory that the beacon node can use
BEACON_MIN_CPU = 50 BEACON_MIN_CPU = 50
...@@ -25,6 +24,34 @@ BEACON_MAX_CPU = 1000 ...@@ -25,6 +24,34 @@ BEACON_MAX_CPU = 1000
BEACON_MIN_MEMORY = 128 BEACON_MIN_MEMORY = 128
BEACON_MAX_MEMORY = 1024 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 # Nimbus requires that its data directory already exists (because it expects you to bind-mount it), so we
# have to to create it # have to to create it
...@@ -32,31 +59,48 @@ CONSENSUS_DATA_DIRPATH_IN_SERVICE_CONTAINER = "$HOME/consensus-data" ...@@ -32,31 +59,48 @@ CONSENSUS_DATA_DIRPATH_IN_SERVICE_CONTAINER = "$HOME/consensus-data"
# Nimbus wants the data dir to have these perms # Nimbus wants the data dir to have these perms
CONSENSUS_DATA_DIR_PERMS_STR = "0700" 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 # 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 # 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 # 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 # 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 = { # ---------------------------------- Used Ports ----------------------------------
TCP_DISCOVERY_PORT_ID: shared_utils.new_port_spec( PRIVATE_IP_ADDRESS_PLACEHOLDER = "KURTOSIS_IP_ADDR_PLACEHOLDER"
DISCOVERY_PORT_NUM, shared_utils.TCP_PROTOCOL 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( BEACON_METRICS_PORT_ID: shared_utils.new_port_spec(
DISCOVERY_PORT_NUM, shared_utils.UDP_PROTOCOL 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), VALIDATOR_METRICS_PORT_ID: shared_utils.new_port_spec(
METRICS_PORT_ID: shared_utils.new_port_spec( VALIDATOR_METRICS_PORT_NUM,
METRICS_PORT_NUM, shared_utils.TCP_PROTOCOL shared_utils.TCP_PROTOCOL,
shared_utils.HTTP_APPLICATION_PROTOCOL,
), ),
} }
...@@ -97,29 +141,23 @@ def launch( ...@@ -97,29 +141,23 @@ def launch(
extra_validator_params, extra_validator_params,
extra_beacon_labels, extra_beacon_labels,
extra_validator_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( log_level = input_parser.get_client_log_level_or_default(
participant_log_level, global_log_level, NIMBUS_LOG_LEVELS 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_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_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_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 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 beacon_config = get_beacon_config(
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(
launcher.el_cl_genesis_data, launcher.el_cl_genesis_data,
image, image,
bootnode_contexts, bootnode_contexts,
...@@ -130,51 +168,99 @@ def launch( ...@@ -130,51 +168,99 @@ def launch(
bn_max_cpu, bn_max_cpu,
bn_min_mem, bn_min_mem,
bn_max_mem, bn_max_mem,
beacon_node_service_name,
snooper_enabled, snooper_enabled,
snooper_engine_context, snooper_engine_context,
extra_params, extra_beacon_params,
extra_labels, 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", endpoint="/eth/v1/node/identity",
port_id=HTTP_PORT_ID, port_id=BEACON_HTTP_PORT_ID,
extract={ extract={
"enr": ".data.enr", "enr": ".data.enr",
"multiaddr": ".data.discovery_addresses[0]", "multiaddr": ".data.discovery_addresses[0]",
"peer_id": ".data.peer_id", "peer_id": ".data.peer_id",
}, },
) )
response = plan.request(recipe=cl_node_identity_recipe, service_name=service_name) response = plan.request(
node_enr = response["extract.enr"] recipe=beacon_node_identity_recipe, service_name=service_name
multiaddr = response["extract.multiaddr"] )
peer_id = response["extract.peer_id"] beacon_node_enr = response["extract.enr"]
beacon_multiaddr = response["extract.multiaddr"]
metrics_port = nimbus_service.ports[METRICS_PORT_ID] beacon_peer_id = response["extract.peer_id"]
metrics_url = "{0}:{1}".format(nimbus_service.ip_address, metrics_port.number)
nimbus_node_metrics_info = node_metrics.new_node_metrics_info( 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] 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( return cl_client_context.new_cl_client_context(
"nimbus", "nimbus",
node_enr, beacon_node_enr,
nimbus_service.ip_address, beacon_service.ip_address,
HTTP_PORT_NUM, BEACON_HTTP_PORT_NUM,
nodes_metrics_info, nodes_metrics_info,
service_name, beacon_node_service_name,
multiaddr=multiaddr, validator_node_service_name,
peer_id=peer_id, beacon_multiaddr,
snooper_enabled=snooper_enabled, beacon_peer_id,
snooper_engine_context=snooper_engine_context, snooper_enabled,
snooper_engine_context,
) )
def get_config( def get_beacon_config(
el_cl_genesis_data, el_cl_genesis_data,
image, image,
bootnode_contexts, bootnode_contexts,
...@@ -185,11 +271,24 @@ def get_config( ...@@ -185,11 +271,24 @@ def get_config(
bn_max_cpu, bn_max_cpu,
bn_min_mem, bn_min_mem,
bn_max_mem, bn_max_mem,
beacon_node_service_name,
snooper_enabled, snooper_enabled,
snooper_engine_context, snooper_engine_context,
extra_params, extra_params,
extra_labels, 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 is enabled use the snooper engine context, otherwise use the execution client context
if snooper_enabled: if snooper_enabled:
EXECUTION_ENGINE_ENDPOINT = "http://{0}:{1}".format( EXECUTION_ENGINE_ENDPOINT = "http://{0}:{1}".format(
...@@ -202,60 +301,11 @@ def get_config( ...@@ -202,60 +301,11 @@ def get_config(
el_client_context.engine_rpc_port_num, el_client_context.engine_rpc_port_num,
) )
validator_keys_dirpath = "" cmd = [
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,
"--non-interactive=true", "--non-interactive=true",
"--log-level=" + log_level, "--log-level=" + log_level,
"--udp-port={0}".format(DISCOVERY_PORT_NUM), "--udp-port={0}".format(BEACON_DISCOVERY_PORT_NUM),
"--tcp-port={0}".format(DISCOVERY_PORT_NUM), "--tcp-port={0}".format(BEACON_DISCOVERY_PORT_NUM),
"--network=" + constants.GENESIS_CONFIG_MOUNT_PATH_ON_CONTAINER, "--network=" + constants.GENESIS_CONFIG_MOUNT_PATH_ON_CONTAINER,
"--data-dir=" + CONSENSUS_DATA_DIRPATH_IN_SERVICE_CONTAINER, "--data-dir=" + CONSENSUS_DATA_DIRPATH_IN_SERVICE_CONTAINER,
"--web3-url=" + EXECUTION_ENGINE_ENDPOINT, "--web3-url=" + EXECUTION_ENGINE_ENDPOINT,
...@@ -265,7 +315,7 @@ def get_config( ...@@ -265,7 +315,7 @@ def get_config(
"--rest", "--rest",
"--rest-address=0.0.0.0", "--rest-address=0.0.0.0",
"--rest-allow-origin=*", "--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: # 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://discord.com/channels/641364059387854899/674288681737256970/922890280120750170
# https://github.com/status-im/nimbus-eth2/issues/2451 # https://github.com/status-im/nimbus-eth2/issues/2451
...@@ -278,18 +328,19 @@ def get_config( ...@@ -278,18 +328,19 @@ def get_config(
# vvvvvvvvvvvvvvvvvvv METRICS CONFIG vvvvvvvvvvvvvvvvvvvvv # vvvvvvvvvvvvvvvvvvv METRICS CONFIG vvvvvvvvvvvvvvvvvvvvv
"--metrics", "--metrics",
"--metrics-address=0.0.0.0", "--metrics-address=0.0.0.0",
"--metrics-port={0}".format(METRICS_PORT_NUM), "--metrics-port={0}".format(BEACON_METRICS_PORT_NUM),
# ^^^^^^^^^^^^^^^^^^^ METRICS CONFIG ^^^^^^^^^^^^^^^^^^^^^ # ^^^^^^^^^^^^^^^^^^^ METRICS CONFIG ^^^^^^^^^^^^^^^^^^^^^
] ]
# Depending on whether we're using a node keystore, we'll need to add the validator flags validator_flags = [
cmd = [] "--validators-dir=" + validator_keys_dirpath,
if node_keystore_files != None: "--secrets-dir=" + validator_secrets_dirpath,
cmd.extend(validator_copy) "--suggested-fee-recipient=" + constants.VALIDATING_REWARDS_ACCOUNT,
cmd.extend(beacon_start) "--graffiti=" + beacon_node_service_name,
]
if node_keystore_files != None and not split_mode_enabled:
cmd.extend(validator_flags) cmd.extend(validator_flags)
else:
cmd.extend(beacon_start)
if bootnode_contexts == None: if bootnode_contexts == None:
# Copied from https://github.com/status-im/nimbus-eth2/blob/67ab477a27e358d605e99bffeb67f98d18218eca/scripts/launch_local_testnet.sh#L417 # Copied from https://github.com/status-im/nimbus-eth2/blob/67ab477a27e358d605e99bffeb67f98d18218eca/scripts/launch_local_testnet.sh#L417
...@@ -308,17 +359,18 @@ def get_config( ...@@ -308,17 +359,18 @@ def get_config(
} }
if node_keystore_files: if node_keystore_files:
files[ files[
VALIDATOR_KEYS_MOUNTPOINT_ON_CLIENT VALIDATOR_KEYS_MOUNTPOINT_ON_CLIENTS
] = node_keystore_files.files_artifact_uuid ] = node_keystore_files.files_artifact_uuid
cmd_str = " ".join(cmd)
return ServiceConfig( return ServiceConfig(
image=image, image=image,
ports=USED_PORTS, ports=BEACON_USED_PORTS,
cmd=[cmd_str], cmd=cmd,
entrypoint=ENTRYPOINT_ARGS,
files=files, files=files,
private_ip_address_placeholder=PRIVATE_IP_ADDRESS_PLACEHOLDER, 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, min_cpu=bn_min_cpu,
max_cpu=bn_max_cpu, max_cpu=bn_max_cpu,
min_memory=bn_min_mem, min_memory=bn_min_mem,
...@@ -333,6 +385,71 @@ def get_config( ...@@ -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): def new_nimbus_launcher(el_cl_genesis_data):
return struct( return struct(
el_cl_genesis_data=el_cl_genesis_data, el_cl_genesis_data=el_cl_genesis_data,
......
...@@ -109,6 +109,7 @@ def launch( ...@@ -109,6 +109,7 @@ def launch(
extra_validator_params, extra_validator_params,
extra_beacon_labels, extra_beacon_labels,
extra_validator_labels, extra_validator_labels,
split_mode_enabled=False,
): ):
split_images = images.split(IMAGE_SEPARATOR_DELIMITER) split_images = images.split(IMAGE_SEPARATOR_DELIMITER)
if len(split_images) != EXPECTED_NUM_IMAGES: if len(split_images) != EXPECTED_NUM_IMAGES:
......
...@@ -98,6 +98,7 @@ def launch( ...@@ -98,6 +98,7 @@ def launch(
extra_validator_params, extra_validator_params,
extra_beacon_labels, extra_beacon_labels,
extra_validator_labels, extra_validator_labels,
split_mode_enabled,
): ):
log_level = input_parser.get_client_log_level_or_default( log_level = input_parser.get_client_log_level_or_default(
participant_log_level, global_log_level, TEKU_LOG_LEVELS participant_log_level, global_log_level, TEKU_LOG_LEVELS
......
...@@ -16,7 +16,7 @@ DEFAULT_EL_IMAGES = { ...@@ -16,7 +16,7 @@ DEFAULT_EL_IMAGES = {
DEFAULT_CL_IMAGES = { DEFAULT_CL_IMAGES = {
"lighthouse": "sigp/lighthouse:latest", "lighthouse": "sigp/lighthouse:latest",
"teku": "consensys/teku: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", "prysm": "prysmaticlabs/prysm-beacon-chain:latest,prysmaticlabs/prysm-validator:latest",
"lodestar": "chainsafe/lodestar:latest", "lodestar": "chainsafe/lodestar:latest",
} }
...@@ -125,6 +125,7 @@ def input_parser(plan, input_args): ...@@ -125,6 +125,7 @@ def input_parser(plan, input_args):
cl_client_type=participant["cl_client_type"], cl_client_type=participant["cl_client_type"],
cl_client_image=participant["cl_client_image"], cl_client_image=participant["cl_client_image"],
cl_client_log_level=participant["cl_client_log_level"], 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_params=participant["beacon_extra_params"],
beacon_extra_labels=participant["beacon_extra_labels"], beacon_extra_labels=participant["beacon_extra_labels"],
validator_extra_params=participant["validator_extra_params"], validator_extra_params=participant["validator_extra_params"],
...@@ -252,6 +253,17 @@ def parse_network_params(input_args): ...@@ -252,6 +253,17 @@ def parse_network_params(input_args):
result["network_params"]["seconds_per_slot"] < 12 result["network_params"]["seconds_per_slot"] < 12
): ):
fail("nimbus can't be run with slot times below 12 seconds") 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"] el_image = participant["el_client_image"]
if el_image == "": if el_image == "":
default_image = DEFAULT_EL_IMAGES.get(el_client_type, "") default_image = DEFAULT_EL_IMAGES.get(el_client_type, "")
...@@ -421,6 +433,7 @@ def default_participant(): ...@@ -421,6 +433,7 @@ def default_participant():
"cl_client_type": "lighthouse", "cl_client_type": "lighthouse",
"cl_client_image": "", "cl_client_image": "",
"cl_client_log_level": "", "cl_client_log_level": "",
"cl_split_mode_enabled": False,
"beacon_extra_params": [], "beacon_extra_params": [],
"beacon_extra_labels": {}, "beacon_extra_labels": {},
"validator_extra_params": [], "validator_extra_params": [],
......
...@@ -340,6 +340,7 @@ def launch_participant_network( ...@@ -340,6 +340,7 @@ def launch_participant_network(
participant.validator_extra_params, participant.validator_extra_params,
participant.beacon_extra_labels, participant.beacon_extra_labels,
participant.validator_extra_labels, participant.validator_extra_labels,
participant.cl_split_mode_enabled,
) )
else: else:
boot_cl_client_ctx = all_cl_client_contexts boot_cl_client_ctx = all_cl_client_contexts
...@@ -369,6 +370,7 @@ def launch_participant_network( ...@@ -369,6 +370,7 @@ def launch_participant_network(
participant.validator_extra_params, participant.validator_extra_params,
participant.beacon_extra_labels, participant.beacon_extra_labels,
participant.validator_extra_labels, participant.validator_extra_labels,
participant.cl_split_mode_enabled,
) )
# Add participant cl additional prometheus labels # Add participant cl additional prometheus labels
......
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