From 3cc825d9136eb74c261ad0c3e1e77e4e0a47b0e4 Mon Sep 17 00:00:00 2001 From: Barnabas Busa Date: Thu, 23 May 2024 10:44:35 +0200 Subject: [PATCH 1/8] fix: default config --- src/package_io/input_parser.star | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/package_io/input_parser.star b/src/package_io/input_parser.star index e8972c5c0..847d23ea5 100644 --- a/src/package_io/input_parser.star +++ b/src/package_io/input_parser.star @@ -378,7 +378,7 @@ def input_parser(plan, input_args): def parse_network_params(plan, input_args): - result = default_input_args() + result = default_input_args(input_args) if input_args.get("network_params", {}).get("preset") == "minimal": result["network_params"] = default_minimal_network_params() @@ -397,8 +397,6 @@ def parse_network_params(plan, input_args): if "vc" in input_args["participants_matrix"]: vc_matrix = input_args["participants_matrix"]["vc"] - participants = [] - for el in el_matrix: for cl in cl_matrix: participant = {k: v for k, v in el.items()} @@ -708,9 +706,13 @@ def get_client_node_selectors(participant_node_selectors, global_node_selectors) return node_selectors -def default_input_args(): +def default_input_args(input_args): network_params = default_network_params() - participants = [] + if "participants_matrix" not in input_args: + participants = [default_participant()] + else: + participants = [] + participants_matrix = [] return { "participants": participants, From bf5787a738c91901ff128ea49bbf8757201ef4a4 Mon Sep 17 00:00:00 2001 From: Barnabas Busa Date: Thu, 23 May 2024 11:27:24 +0200 Subject: [PATCH 2/8] fix ci jobs --- .github/tests/mix-assert.yaml | 2 +- .github/tests/mix-with-tools.yaml | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/tests/mix-assert.yaml b/.github/tests/mix-assert.yaml index d1be13155..84fe05660 100644 --- a/.github/tests/mix-assert.yaml +++ b/.github/tests/mix-assert.yaml @@ -9,7 +9,7 @@ participants: cl_type: lighthouse - el_type: reth cl_type: lodestar - - el_type: nimbus + - el_type: geth # temp remove nimbus-eth1 till they fix their bugs cl_type: grandine additional_services: - assertoor diff --git a/.github/tests/mix-with-tools.yaml b/.github/tests/mix-with-tools.yaml index 82a740da8..4a1120dc5 100644 --- a/.github/tests/mix-with-tools.yaml +++ b/.github/tests/mix-with-tools.yaml @@ -3,6 +3,7 @@ participants: cl_type: teku - el_type: nethermind cl_type: prysm + cl_image: ethpandaops/prysm-beacon-chain:webfix - el_type: erigon cl_type: nimbus - el_type: besu From 211cc2802abed7f470d4dea6f44aaee316cf14b3 Mon Sep 17 00:00:00 2001 From: Barnabas Busa Date: Thu, 23 May 2024 13:47:45 +0200 Subject: [PATCH 3/8] feat: add vc_count to increase the number of validators per participant --- README.md | 4 + network_params.yaml | 1 + src/package_io/input_parser.star | 20 ++ src/participant_network.star | 266 ++++++++++-------- .../validator_keystore_generator.star | 125 +++++--- 5 files changed, 250 insertions(+), 166 deletions(-) diff --git a/README.md b/README.md index 4fb5e90aa..9cb805c54 100644 --- a/README.md +++ b/README.md @@ -344,6 +344,10 @@ participants: # - teku: consensys/teku:latest vc_image: "" + # The number of validator clients to run for this participant + # Defaults to 1 + vc_count: 1 + # The log level string that this participant's CL client should log at # If this is emptystring then the global `logLevel` parameter's value will be translated into a string appropriate for the client (e.g. if # global `logLevel` = `info` then Teku would receive `INFO`, Prysm would receive `info`, etc.) diff --git a/network_params.yaml b/network_params.yaml index 355737430..a5470f3d0 100644 --- a/network_params.yaml +++ b/network_params.yaml @@ -30,6 +30,7 @@ participants: vc_type: lighthouse vc_image: sigp/lighthouse:latest vc_log_level: "" + vc_count: 1 vc_extra_env_vars: {} vc_extra_labels: {} vc_extra_params: [] diff --git a/src/package_io/input_parser.star b/src/package_io/input_parser.star index 847d23ea5..0892f54b0 100644 --- a/src/package_io/input_parser.star +++ b/src/package_io/input_parser.star @@ -214,6 +214,7 @@ def input_parser(plan, input_args): vc_type=participant["vc_type"], vc_image=participant["vc_image"], vc_log_level=participant["vc_log_level"], + vc_count=participant["vc_count"], vc_tolerations=participant["vc_tolerations"], cl_extra_params=participant["cl_extra_params"], cl_extra_labels=participant["cl_extra_labels"], @@ -537,6 +538,24 @@ def parse_network_params(plan, input_args): ) participant["vc_image"] = default_image + # If the num validator keys per node is not divisible by vc_count of a participant, fail + if ( + result["network_params"]["num_validator_keys_per_node"] + % participant["vc_count"] + != 0 + ): + fail( + "num_validator_keys_per_node: {0} is not divisible by vc_count: {1} for participant: {2}".format( + result["network_params"]["num_validator_keys_per_node"], + participant["vc_count"], + str(index + 1) + + "-" + + participant["el_type"] + + "-" + + participant["cl_type"], + ) + ) + snooper_enabled = participant["snooper_enabled"] if snooper_enabled == None: participant["snooper_enabled"] = result["snooper_enabled"] @@ -826,6 +845,7 @@ def default_participant(): "vc_type": "", "vc_image": "", "vc_log_level": "", + "vc_count": 1, "vc_extra_env_vars": {}, "vc_extra_labels": {}, "vc_extra_params": [], diff --git a/src/participant_network.star b/src/participant_network.star index 1ff6fe49a..4bd0cced9 100644 --- a/src/participant_network.star +++ b/src/participant_network.star @@ -210,150 +210,172 @@ def launch_participant_network( cl_type = participant.cl_type vc_type = participant.vc_type index_str = shared_utils.zfill_custom(index + 1, len(str(len(participants)))) - el_context = all_el_contexts[index] - cl_context = all_cl_contexts[index] - - node_selectors = input_parser.get_client_node_selectors( - participant.node_selectors, - global_node_selectors, - ) - if participant.ethereum_metrics_exporter_enabled: - pair_name = "{0}-{1}-{2}".format(index_str, cl_type, el_type) + for sub_index in range(participant.vc_count): + el_context = all_el_contexts[index] + cl_context = all_cl_contexts[index] - ethereum_metrics_exporter_service_name = ( - "ethereum-metrics-exporter-{0}".format(pair_name) + node_selectors = input_parser.get_client_node_selectors( + participant.node_selectors, + global_node_selectors, ) + if participant.ethereum_metrics_exporter_enabled: + pair_name = "{0}-{1}-{2}".format(index_str, cl_type, el_type) - ethereum_metrics_exporter_context = ethereum_metrics_exporter.launch( - plan, - pair_name, - ethereum_metrics_exporter_service_name, - el_context, - cl_context, - node_selectors, - ) - plan.print( - "Successfully added {0} ethereum metrics exporter participants".format( - ethereum_metrics_exporter_context + ethereum_metrics_exporter_service_name = ( + "ethereum-metrics-exporter-{0}".format(pair_name) ) - ) - - all_ethereum_metrics_exporter_contexts.append(ethereum_metrics_exporter_context) - xatu_sentry_context = None + ethereum_metrics_exporter_context = ethereum_metrics_exporter.launch( + plan, + pair_name, + ethereum_metrics_exporter_service_name, + el_context, + cl_context, + node_selectors, + ) + plan.print( + "Successfully added {0} ethereum metrics exporter participants".format( + ethereum_metrics_exporter_context + ) + ) - if participant.xatu_sentry_enabled: - pair_name = "{0}-{1}-{2}".format(index_str, cl_type, el_type) + all_ethereum_metrics_exporter_contexts.append( + ethereum_metrics_exporter_context + ) - xatu_sentry_service_name = "xatu-sentry-{0}".format(pair_name) + xatu_sentry_context = None - xatu_sentry_context = xatu_sentry.launch( - plan, - xatu_sentry_service_name, - cl_context, - xatu_sentry_params, - network_params, - pair_name, - node_selectors, - ) - plan.print( - "Successfully added {0} xatu sentry participants".format( - xatu_sentry_context - ) - ) + if participant.xatu_sentry_enabled: + pair_name = "{0}-{1}-{2}".format(index_str, cl_type, el_type) - all_xatu_sentry_contexts.append(xatu_sentry_context) + xatu_sentry_service_name = "xatu-sentry-{0}".format(pair_name) - plan.print("Successfully added {0} CL participants".format(num_participants)) + xatu_sentry_context = xatu_sentry.launch( + plan, + xatu_sentry_service_name, + cl_context, + xatu_sentry_params, + network_params, + pair_name, + node_selectors, + ) + plan.print( + "Successfully added {0} xatu sentry participants".format( + xatu_sentry_context + ) + ) - plan.print("Start adding validators for participant #{0}".format(index_str)) - if participant.use_separate_vc == None: - # This should only be the case for the MEV participant, - # the regular participants default to False/True - all_vc_contexts.append(None) - all_snooper_beacon_contexts.append(None) - continue + all_xatu_sentry_contexts.append(xatu_sentry_context) - if cl_type in _cls_that_need_separate_vc and not participant.use_separate_vc: - fail("{0} needs a separate validator client!".format(cl_type)) + plan.print( + "Successfully added {0} CL participants".format(num_participants) + ) - if not participant.use_separate_vc: - all_vc_contexts.append(None) - all_snooper_beacon_contexts.append(None) - continue + plan.print("Start adding validators for participant #{0}".format(index_str)) + if participant.use_separate_vc == None: + # This should only be the case for the MEV participant, + # the regular participants default to False/True + all_vc_contexts.append(None) + all_snooper_beacon_contexts.append(None) + continue + + if ( + cl_type in _cls_that_need_separate_vc + and not participant.use_separate_vc + ): + fail("{0} needs a separate validator client!".format(cl_type)) + + if not participant.use_separate_vc: + all_vc_contexts.append(None) + all_snooper_beacon_contexts.append(None) + continue - plan.print( - "Using separate validator client for participant #{0}".format(index_str) - ) + plan.print( + "Using separate validator client for participant #{0}".format(index_str) + ) - vc_keystores = None - if participant.validator_count != 0: - vc_keystores = preregistered_validator_keys_for_nodes[index] + vc_keystores = None + if participant.validator_count != 0: + vc_keystores = preregistered_validator_keys_for_nodes[index] - vc_context = None - snooper_beacon_context = None + vc_context = None + snooper_beacon_context = None - if participant.snooper_enabled: - snooper_service_name = "snooper-beacon-{0}-{1}-{2}".format( - index_str, cl_type, vc_type - ) - snooper_beacon_context = beacon_snooper.launch( - plan, - snooper_service_name, - cl_context, - node_selectors, - ) - plan.print( - "Successfully added {0} snooper participants".format( - snooper_beacon_context + if participant.snooper_enabled: + snooper_service_name = "snooper-beacon-{0}-{1}-{2}{3}".format( + index_str, + cl_type, + vc_type, + "-" + sub_index if participant.vc_count != 1 else "", + ) + snooper_beacon_context = beacon_snooper.launch( + plan, + snooper_service_name, + cl_context, + node_selectors, + ) + plan.print( + "Successfully added {0} snooper participants".format( + snooper_beacon_context + ) + ) + all_snooper_beacon_contexts.append(snooper_beacon_context) + full_name = ( + "{0}-{1}-{2}-{3}{4}".format( + index_str, + el_type, + cl_type, + vc_type, + "-" + str(sub_index) if participant.vc_count != 1 else "", + ) + if participant.cl_type != participant.vc_type + else "{0}-{1}-{2}{3}".format( + index_str, + el_type, + cl_type, + "-" + str(sub_index) if participant.vc_count != 1 else "", ) ) - all_snooper_beacon_contexts.append(snooper_beacon_context) - full_name = ( - "{0}-{1}-{2}-{3}".format(index_str, el_type, cl_type, vc_type) - if participant.cl_type != participant.vc_type - else "{0}-{1}-{2}".format(index_str, el_type, cl_type) - ) - vc_context = vc.launch( - plan=plan, - launcher=vc.new_vc_launcher(el_cl_genesis_data=el_cl_data), - keymanager_file=keymanager_file, - service_name="vc-{0}".format(full_name), - vc_type=vc_type, - image=participant.vc_image, - participant_log_level=participant.vc_log_level, - global_log_level=global_log_level, - cl_context=cl_context, - el_context=el_context, - full_name=full_name, - snooper_enabled=participant.snooper_enabled, - snooper_beacon_context=snooper_beacon_context, - node_keystore_files=vc_keystores, - vc_min_cpu=participant.vc_min_cpu, - vc_max_cpu=participant.vc_max_cpu, - vc_min_mem=participant.vc_min_mem, - vc_max_mem=participant.vc_max_mem, - extra_params=participant.vc_extra_params, - extra_env_vars=participant.vc_extra_env_vars, - extra_labels=participant.vc_extra_labels, - prysm_password_relative_filepath=prysm_password_relative_filepath, - prysm_password_artifact_uuid=prysm_password_artifact_uuid, - vc_tolerations=participant.vc_tolerations, - participant_tolerations=participant.tolerations, - 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, - ) - all_vc_contexts.append(vc_context) + vc_context = vc.launch( + plan=plan, + launcher=vc.new_vc_launcher(el_cl_genesis_data=el_cl_data), + keymanager_file=keymanager_file, + service_name="vc-{0}".format(full_name), + vc_type=vc_type, + image=participant.vc_image, + participant_log_level=participant.vc_log_level, + global_log_level=global_log_level, + cl_context=cl_context, + el_context=el_context, + full_name=full_name, + snooper_enabled=participant.snooper_enabled, + snooper_beacon_context=snooper_beacon_context, + node_keystore_files=vc_keystores, + vc_min_cpu=participant.vc_min_cpu, + vc_max_cpu=participant.vc_max_cpu, + vc_min_mem=participant.vc_min_mem, + vc_max_mem=participant.vc_max_mem, + extra_params=participant.vc_extra_params, + extra_env_vars=participant.vc_extra_env_vars, + extra_labels=participant.vc_extra_labels, + prysm_password_relative_filepath=prysm_password_relative_filepath, + prysm_password_artifact_uuid=prysm_password_artifact_uuid, + vc_tolerations=participant.vc_tolerations, + participant_tolerations=participant.tolerations, + 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, + ) + all_vc_contexts.append(vc_context) - if vc_context and vc_context.metrics_info: - vc_context.metrics_info["config"] = participant.prometheus_config + if vc_context and vc_context.metrics_info: + vc_context.metrics_info["config"] = participant.prometheus_config - all_participants = [] + all_participants = [] for index, participant in enumerate(participants): el_type = participant.el_type diff --git a/src/prelaunch_data_generator/validator_keystores/validator_keystore_generator.star b/src/prelaunch_data_generator/validator_keystores/validator_keystore_generator.star index 12f260875..6f52b182b 100644 --- a/src/prelaunch_data_generator/validator_keystores/validator_keystore_generator.star +++ b/src/prelaunch_data_generator/validator_keystores/validator_keystore_generator.star @@ -2,7 +2,7 @@ shared_utils = import_module("../../shared_utils/shared_utils.star") keystore_files_module = import_module("./keystore_files.star") keystores_result = import_module("./generate_keystores_result.star") -NODE_KEYSTORES_OUTPUT_DIRPATH_FORMAT_STR = "/node-{0}-keystores/" +NODE_KEYSTORES_OUTPUT_DIRPATH_FORMAT_STR = "/node-{0}-keystores{1}/" # Prysm keystores are encrypted with a password PRYSM_PASSWORD = "password" @@ -85,31 +85,52 @@ def generate_validator_keystores(plan, mnemonic, participants): all_output_dirpaths = [] all_sub_command_strs = [] running_total_validator_count = 0 + for idx, participant in enumerate(participants): - output_dirpath = NODE_KEYSTORES_OUTPUT_DIRPATH_FORMAT_STR.format(idx) if participant.validator_count == 0: + output_dirpath = NODE_KEYSTORES_OUTPUT_DIRPATH_FORMAT_STR.format(idx, "") all_output_dirpaths.append(output_dirpath) continue - start_index = running_total_validator_count + + for i in range(participant.vc_count): + output_dirpath = ( + NODE_KEYSTORES_OUTPUT_DIRPATH_FORMAT_STR.format(idx, "-" + str(i)) + if participant.vc_count != 1 + else NODE_KEYSTORES_OUTPUT_DIRPATH_FORMAT_STR.format(idx, "") + ) + + start_index = running_total_validator_count + i * ( + participant.validator_count // participant.vc_count + ) + stop_index = start_index + ( + participant.validator_count // participant.vc_count + ) + + # Adjust stop_index for the last partition to include all remaining validators + if i == participant.vc_count - 1: + stop_index = running_total_validator_count + participant.validator_count + + generate_keystores_cmd = '{0} keystores --insecure --prysm-pass {1} --out-loc {2} --source-mnemonic "{3}" --source-min {4} --source-max {5}'.format( + KEYSTORES_GENERATION_TOOL_NAME, + PRYSM_PASSWORD, + output_dirpath, + mnemonic, + start_index, + stop_index, + ) + all_output_dirpaths.append(output_dirpath) + all_sub_command_strs.append(generate_keystores_cmd) + running_total_validator_count += participant.validator_count - stop_index = start_index + participant.validator_count - generate_keystores_cmd = '{0} keystores --insecure --prysm-pass {1} --out-loc {2} --source-mnemonic "{3}" --source-min {4} --source-max {5}'.format( - KEYSTORES_GENERATION_TOOL_NAME, - PRYSM_PASSWORD, - output_dirpath, - mnemonic, - start_index, - stop_index, - ) + # Append permissions commands for each output directory + for output_dirpath in all_output_dirpaths: teku_permissions_cmd = "chmod 0777 -R " + output_dirpath + TEKU_KEYS_DIRNAME raw_secret_permissions_cmd = ( "chmod 0600 -R " + output_dirpath + RAW_SECRETS_DIRNAME ) - all_sub_command_strs.append(generate_keystores_cmd) all_sub_command_strs.append(teku_permissions_cmd) all_sub_command_strs.append(raw_secret_permissions_cmd) - all_output_dirpaths.append(output_dirpath) command_str = " && ".join(all_sub_command_strs) @@ -124,39 +145,57 @@ def generate_validator_keystores(plan, mnemonic, participants): keystore_files = [] running_total_validator_count = 0 for idx, participant in enumerate(participants): - output_dirpath = all_output_dirpaths[idx] if participant.validator_count == 0: keystore_files.append(None) continue - padded_idx = shared_utils.zfill_custom(idx + 1, len(str(len(participants)))) - keystore_start_index = running_total_validator_count - running_total_validator_count += participant.validator_count - keystore_stop_index = (keystore_start_index + participant.validator_count) - 1 - artifact_name = "{0}-{1}-{2}-{3}-{4}".format( - padded_idx, - participant.cl_type, - participant.el_type, - keystore_start_index, - keystore_stop_index, - ) - artifact_name = plan.store_service_files( - service_name, output_dirpath, name=artifact_name - ) - # This is necessary because the way Kurtosis currently implements artifact-storing is - base_dirname_in_artifact = shared_utils.path_base(output_dirpath) - to_add = keystore_files_module.new_keystore_files( - artifact_name, - shared_utils.path_join(base_dirname_in_artifact), - shared_utils.path_join(base_dirname_in_artifact, RAW_KEYS_DIRNAME), - shared_utils.path_join(base_dirname_in_artifact, RAW_SECRETS_DIRNAME), - shared_utils.path_join(base_dirname_in_artifact, NIMBUS_KEYS_DIRNAME), - shared_utils.path_join(base_dirname_in_artifact, PRYSM_DIRNAME), - shared_utils.path_join(base_dirname_in_artifact, TEKU_KEYS_DIRNAME), - shared_utils.path_join(base_dirname_in_artifact, TEKU_SECRETS_DIRNAME), - ) + for i in range(participant.vc_count): + output_dirpath = ( + NODE_KEYSTORES_OUTPUT_DIRPATH_FORMAT_STR.format(idx, "-" + str(i)) + if participant.vc_count != 1 + else NODE_KEYSTORES_OUTPUT_DIRPATH_FORMAT_STR.format(idx, "") + ) + padded_idx = shared_utils.zfill_custom(idx + 1, len(str(len(participants)))) + + keystore_start_index = running_total_validator_count + i * ( + participant.validator_count // participant.vc_count + ) + keystore_stop_index = keystore_start_index + ( + participant.validator_count // participant.vc_count + ) + + if i == participant.vc_count - 1: + keystore_stop_index = ( + running_total_validator_count + participant.validator_count + ) + + artifact_name = "{0}-{1}-{2}-{3}-{4}-{5}".format( + padded_idx, + participant.cl_type, + participant.el_type, + keystore_start_index, + keystore_stop_index - 1, + i, + ) + artifact_name = plan.store_service_files( + service_name, output_dirpath, name=artifact_name + ) + + base_dirname_in_artifact = shared_utils.path_base(output_dirpath) + to_add = keystore_files_module.new_keystore_files( + artifact_name, + shared_utils.path_join(base_dirname_in_artifact), + shared_utils.path_join(base_dirname_in_artifact, RAW_KEYS_DIRNAME), + shared_utils.path_join(base_dirname_in_artifact, RAW_SECRETS_DIRNAME), + shared_utils.path_join(base_dirname_in_artifact, NIMBUS_KEYS_DIRNAME), + shared_utils.path_join(base_dirname_in_artifact, PRYSM_DIRNAME), + shared_utils.path_join(base_dirname_in_artifact, TEKU_KEYS_DIRNAME), + shared_utils.path_join(base_dirname_in_artifact, TEKU_SECRETS_DIRNAME), + ) + + keystore_files.append(to_add) - keystore_files.append(to_add) + running_total_validator_count += participant.validator_count write_prysm_password_file_cmd = [ "sh", @@ -187,8 +226,6 @@ def generate_validator_keystores(plan, mnemonic, participants): keystore_files, ) - # TODO replace this with a task so that we can get the container removed - # we are removing a call to remove_service for idempotency return result From 2556da303c3b166dd0c2b5945135392819802944 Mon Sep 17 00:00:00 2001 From: Barnabas Busa Date: Thu, 23 May 2024 14:08:58 +0200 Subject: [PATCH 4/8] fix vc count --- src/participant_network.star | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/participant_network.star b/src/participant_network.star index 4bd0cced9..1e00abe3e 100644 --- a/src/participant_network.star +++ b/src/participant_network.star @@ -296,7 +296,12 @@ def launch_participant_network( vc_keystores = None if participant.validator_count != 0: - vc_keystores = preregistered_validator_keys_for_nodes[index] + if participant.vc_count == 1: + vc_keystores = preregistered_validator_keys_for_nodes[index] + else: + vc_keystores = preregistered_validator_keys_for_nodes[ + index + sub_index + ] vc_context = None snooper_beacon_context = None From bfcdd75d7327d35446159a224fc20c10b35f863b Mon Sep 17 00:00:00 2001 From: Barnabas Busa Date: Thu, 23 May 2024 14:15:48 +0200 Subject: [PATCH 5/8] fix snooper --- src/participant_network.star | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/participant_network.star b/src/participant_network.star index 1e00abe3e..fb1b5f82a 100644 --- a/src/participant_network.star +++ b/src/participant_network.star @@ -311,7 +311,7 @@ def launch_participant_network( index_str, cl_type, vc_type, - "-" + sub_index if participant.vc_count != 1 else "", + "-" + str(sub_index) if participant.vc_count != 1 else "", ) snooper_beacon_context = beacon_snooper.launch( plan, From 82daba74db7dab02e4838839a56a72ca82d3fbda Mon Sep 17 00:00:00 2001 From: Barnabas Busa Date: Thu, 23 May 2024 14:42:12 +0200 Subject: [PATCH 6/8] fix bad index --- .../validator_keystore_generator.star | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/src/prelaunch_data_generator/validator_keystores/validator_keystore_generator.star b/src/prelaunch_data_generator/validator_keystores/validator_keystore_generator.star index 6f52b182b..d413b96cf 100644 --- a/src/prelaunch_data_generator/validator_keystores/validator_keystore_generator.star +++ b/src/prelaunch_data_generator/validator_keystores/validator_keystore_generator.star @@ -87,8 +87,8 @@ def generate_validator_keystores(plan, mnemonic, participants): running_total_validator_count = 0 for idx, participant in enumerate(participants): + output_dirpath = NODE_KEYSTORES_OUTPUT_DIRPATH_FORMAT_STR.format(idx, "") if participant.validator_count == 0: - output_dirpath = NODE_KEYSTORES_OUTPUT_DIRPATH_FORMAT_STR.format(idx, "") all_output_dirpaths.append(output_dirpath) continue @@ -121,16 +121,14 @@ def generate_validator_keystores(plan, mnemonic, participants): all_output_dirpaths.append(output_dirpath) all_sub_command_strs.append(generate_keystores_cmd) - running_total_validator_count += participant.validator_count + teku_permissions_cmd = "chmod 0777 -R " + output_dirpath + TEKU_KEYS_DIRNAME + raw_secret_permissions_cmd = ( + "chmod 0600 -R " + output_dirpath + RAW_SECRETS_DIRNAME + ) + all_sub_command_strs.append(teku_permissions_cmd) + all_sub_command_strs.append(raw_secret_permissions_cmd) - # Append permissions commands for each output directory - for output_dirpath in all_output_dirpaths: - teku_permissions_cmd = "chmod 0777 -R " + output_dirpath + TEKU_KEYS_DIRNAME - raw_secret_permissions_cmd = ( - "chmod 0600 -R " + output_dirpath + RAW_SECRETS_DIRNAME - ) - all_sub_command_strs.append(teku_permissions_cmd) - all_sub_command_strs.append(raw_secret_permissions_cmd) + running_total_validator_count += participant.validator_count command_str = " && ".join(all_sub_command_strs) From f8049f7dee85ee8c0197b928db431e2a6f7fcc6d Mon Sep 17 00:00:00 2001 From: Barnabas Busa Date: Thu, 23 May 2024 15:13:41 +0200 Subject: [PATCH 7/8] fix prysm image, add guard for parallel keygen --- .github/tests/mix-with-tools-minimal.yaml | 9 +-------- src/package_io/input_parser.star | 5 +++++ .../validator_keystore_generator.star | 2 +- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/.github/tests/mix-with-tools-minimal.yaml b/.github/tests/mix-with-tools-minimal.yaml index 79314bce5..32d36900e 100644 --- a/.github/tests/mix-with-tools-minimal.yaml +++ b/.github/tests/mix-with-tools-minimal.yaml @@ -3,24 +3,17 @@ participants: cl_type: teku - el_type: geth cl_type: prysm - cl_extra_params: [--minimal-config=true] - cl_image: ethpandaops/prysm-beacon-chain:develop-minimal + cl_image: ethpandaops/prysm-beacon-chain:webfix-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 additional_services: - tx_spammer - blob_spammer diff --git a/src/package_io/input_parser.star b/src/package_io/input_parser.star index 4e3c1fcd0..9bb927cfa 100644 --- a/src/package_io/input_parser.star +++ b/src/package_io/input_parser.star @@ -538,6 +538,11 @@ def parse_network_params(plan, input_args): ) participant["vc_image"] = default_image + if result["parallel_keystore_generation"] and participant["vc_count"] != 1: + fail( + "parallel_keystore_generation is only supported for 1 validator client per participant (for now)" + ) + # If the num validator keys per node is not divisible by vc_count of a participant, fail if ( result["network_params"]["num_validator_keys_per_node"] diff --git a/src/prelaunch_data_generator/validator_keystores/validator_keystore_generator.star b/src/prelaunch_data_generator/validator_keystores/validator_keystore_generator.star index d413b96cf..603cfdb2d 100644 --- a/src/prelaunch_data_generator/validator_keystores/validator_keystore_generator.star +++ b/src/prelaunch_data_generator/validator_keystores/validator_keystore_generator.star @@ -239,7 +239,7 @@ def generate_valdiator_keystores_in_parallel(plan, mnemonic, participants): finished_files_to_verify = [] running_total_validator_count = 0 for idx, participant in enumerate(participants): - output_dirpath = NODE_KEYSTORES_OUTPUT_DIRPATH_FORMAT_STR.format(idx) + output_dirpath = NODE_KEYSTORES_OUTPUT_DIRPATH_FORMAT_STR.format(idx, "") if participant.validator_count == 0: all_generation_commands.append(None) all_output_dirpaths.append(None) From d31ed99d1dd9979ffb788b527715baa1cd4ef529 Mon Sep 17 00:00:00 2001 From: Tyler <122291810+0xTylerHolmes@users.noreply.github.com> Date: Tue, 28 May 2024 05:14:18 -0400 Subject: [PATCH 8/8] fix: Vc count logic (#640) I ran into a few index out of bounds and divide by zero issues. I fixed those with what I expect is the right method. One thing I would like you to check is my change on the [participant_network.star](https://github.com/0xTylerHolmes/ethereum-package/blob/061dbec8694e78dfeb2cf9c48d351202866fd6e6/src/participant_network.star#L397) I added a check on the `vc_context` assignment for the case where `vc_count == 0`. We would get an index out of bounds panic so I just set it to `None`. I'm unsure if there are downstream consequences but everything appears to be working on my end with that. --------- Co-authored-by: Barnabas Busa --- src/cl/cl_launcher.star | 2 +- src/package_io/input_parser.star | 3 ++- src/participant_network.star | 5 ++++- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/cl/cl_launcher.star b/src/cl/cl_launcher.star index 87324d3de..a4e9b6ca8 100644 --- a/src/cl/cl_launcher.star +++ b/src/cl/cl_launcher.star @@ -119,7 +119,7 @@ def launch( cl_service_name = "cl-{0}-{1}-{2}".format(index_str, cl_type, el_type) new_cl_node_validator_keystores = None - if participant.validator_count != 0: + if participant.validator_count != 0 and participant.vc_count != 0: new_cl_node_validator_keystores = preregistered_validator_keys_for_nodes[ index ] diff --git a/src/package_io/input_parser.star b/src/package_io/input_parser.star index 9bb927cfa..ac54c8d98 100644 --- a/src/package_io/input_parser.star +++ b/src/package_io/input_parser.star @@ -545,7 +545,8 @@ def parse_network_params(plan, input_args): # If the num validator keys per node is not divisible by vc_count of a participant, fail if ( - result["network_params"]["num_validator_keys_per_node"] + participant["vc_count"] > 0 + and result["network_params"]["num_validator_keys_per_node"] % participant["vc_count"] != 0 ): diff --git a/src/participant_network.star b/src/participant_network.star index fb1b5f82a..a3ce56365 100644 --- a/src/participant_network.star +++ b/src/participant_network.star @@ -391,7 +391,10 @@ def launch_participant_network( el_context = all_el_contexts[index] cl_context = all_cl_contexts[index] - vc_context = all_vc_contexts[index] + if participant.vc_count != 0: + vc_context = all_vc_contexts[index] + else: + vc_context = None if participant.snooper_enabled: snooper_engine_context = all_snooper_engine_contexts[index]