Commit 5fd7e7bd authored by Gyanendra Mishra's avatar Gyanendra Mishra Committed by GitHub

ci: add a linter (#216)

parent 1752ed0a
...@@ -42,6 +42,14 @@ jobs: ...@@ -42,6 +42,14 @@ jobs:
- run: kurtosis run ${PWD} - run: kurtosis run ${PWD}
lint:
executor: ubuntu_vm
steps:
- <<: *setup_kurtosis
- checkout
- run: kurtosis lint ${PWD}
run_starlark_arm64: run_starlark_arm64:
executor: ubuntu_vm executor: ubuntu_vm
resource_class: arm.medium resource_class: arm.medium
...@@ -234,3 +242,11 @@ workflows: ...@@ -234,3 +242,11 @@ workflows:
branches: branches:
ignore: ignore:
- main - main
- lint:
context:
# This pulls in KurtosisBot's Github token, so that we can read from our private repos
- github-user
filters:
branches:
ignore:
- main
parse_input = import_module("github.com/kurtosis-tech/eth2-package/src/package_io/parse_input.star") parse_input = import_module(
"github.com/kurtosis-tech/eth2-package/src/package_io/parse_input.star"
static_files = import_module("github.com/kurtosis-tech/eth2-package/src/static_files/static_files.star") )
genesis_constants = import_module("github.com/kurtosis-tech/eth-network-package/src/prelaunch_data_generator/genesis_constants/genesis_constants.star")
static_files = import_module(
eth_network_module = import_module("github.com/kurtosis-tech/eth-network-package/main.star") "github.com/kurtosis-tech/eth2-package/src/static_files/static_files.star"
transaction_spammer = import_module("github.com/kurtosis-tech/eth2-package/src/transaction_spammer/transaction_spammer.star") )
blob_spammer = import_module("github.com/kurtosis-tech/eth2-package/src/blob_spammer/blob_spammer.star") genesis_constants = import_module(
cl_forkmon = import_module("github.com/kurtosis-tech/eth2-package/src/cl_forkmon/cl_forkmon_launcher.star") "github.com/kurtosis-tech/eth-network-package/src/prelaunch_data_generator/genesis_constants/genesis_constants.star"
el_forkmon = import_module("github.com/kurtosis-tech/eth2-package/src/el_forkmon/el_forkmon_launcher.star") )
beacon_metrics_gazer = import_module("github.com/kurtosis-tech/eth2-package/src/beacon_metrics_gazer/beacon_metrics_gazer_launcher.star")
light_beaconchain_explorer = import_module("github.com/kurtosis-tech/eth2-package/src/light_beaconchain/light_beaconchain_launcher.star") eth_network_module = import_module(
prometheus = import_module("github.com/kurtosis-tech/eth2-package/src/prometheus/prometheus_launcher.star") "github.com/kurtosis-tech/eth-network-package/main.star"
grafana =import_module("github.com/kurtosis-tech/eth2-package/src/grafana/grafana_launcher.star") )
mev_boost_launcher_module = import_module("github.com/kurtosis-tech/eth2-package/src/mev_boost/mev_boost_launcher.star") transaction_spammer = import_module(
mock_mev_launcher_module = import_module("github.com/kurtosis-tech/eth2-package/src/mock_mev/mock_mev_launcher.star") "github.com/kurtosis-tech/eth2-package/src/transaction_spammer/transaction_spammer.star"
mev_relay_launcher_module = import_module("github.com/kurtosis-tech/eth2-package/src/mev_relay/mev_relay_launcher.star") )
mev_flood_module = import_module("github.com/kurtosis-tech/eth2-package/src/mev_flood/mev_flood_launcher.star") blob_spammer = import_module(
mev_custom_flood_module = import_module("github.com/kurtosis-tech/eth2-package/src/mev_custom_flood/mev_custom_flood_launcher.star") "github.com/kurtosis-tech/eth2-package/src/blob_spammer/blob_spammer.star"
)
GRAFANA_USER = "admin" cl_forkmon = import_module(
GRAFANA_PASSWORD = "admin" "github.com/kurtosis-tech/eth2-package/src/cl_forkmon/cl_forkmon_launcher.star"
GRAFANA_DASHBOARD_PATH_URL = "/d/QdTOwy-nz/eth2-merge-kurtosis-module-dashboard?orgId=1" )
el_forkmon = import_module(
"github.com/kurtosis-tech/eth2-package/src/el_forkmon/el_forkmon_launcher.star"
)
beacon_metrics_gazer = import_module(
"github.com/kurtosis-tech/eth2-package/src/beacon_metrics_gazer/beacon_metrics_gazer_launcher.star"
)
light_beaconchain_explorer = import_module(
"github.com/kurtosis-tech/eth2-package/src/light_beaconchain/light_beaconchain_launcher.star"
)
prometheus = import_module(
"github.com/kurtosis-tech/eth2-package/src/prometheus/prometheus_launcher.star"
)
grafana = import_module(
"github.com/kurtosis-tech/eth2-package/src/grafana/grafana_launcher.star"
)
mev_boost_launcher_module = import_module(
"github.com/kurtosis-tech/eth2-package/src/mev_boost/mev_boost_launcher.star"
)
mock_mev_launcher_module = import_module(
"github.com/kurtosis-tech/eth2-package/src/mock_mev/mock_mev_launcher.star"
)
mev_relay_launcher_module = import_module(
"github.com/kurtosis-tech/eth2-package/src/mev_relay/mev_relay_launcher.star"
)
mev_flood_module = import_module(
"github.com/kurtosis-tech/eth2-package/src/mev_flood/mev_flood_launcher.star"
)
mev_custom_flood_module = import_module(
"github.com/kurtosis-tech/eth2-package/src/mev_custom_flood/mev_custom_flood_launcher.star"
)
GRAFANA_USER = "admin"
GRAFANA_PASSWORD = "admin"
GRAFANA_DASHBOARD_PATH_URL = "/d/QdTOwy-nz/eth2-merge-kurtosis-module-dashboard?orgId=1"
FIRST_NODE_FINALIZATION_FACT = "cl-boot-finalization-fact" FIRST_NODE_FINALIZATION_FACT = "cl-boot-finalization-fact"
HTTP_PORT_ID_FOR_FACT = "http" HTTP_PORT_ID_FOR_FACT = "http"
...@@ -30,149 +64,270 @@ MOCK_MEV_TYPE = "mock" ...@@ -30,149 +64,270 @@ MOCK_MEV_TYPE = "mock"
FULL_MEV_TYPE = "full" FULL_MEV_TYPE = "full"
PATH_TO_PARSED_BEACON_STATE = "/genesis/output/parsedBeaconState.json" PATH_TO_PARSED_BEACON_STATE = "/genesis/output/parsedBeaconState.json"
def run(plan, args = {}):
args_with_right_defaults, args_with_defaults_dict = parse_input.parse_input(plan, args) def run(plan, args={}):
args_with_right_defaults, args_with_defaults_dict = parse_input.parse_input(
num_participants = len(args_with_right_defaults.participants) plan, args
network_params = args_with_right_defaults.network_params )
mev_params = args_with_right_defaults.mev_params
num_participants = len(args_with_right_defaults.participants)
grafana_datasource_config_template = read_file(static_files.GRAFANA_DATASOURCE_CONFIG_TEMPLATE_FILEPATH) network_params = args_with_right_defaults.network_params
grafana_dashboards_config_template = read_file(static_files.GRAFANA_DASHBOARD_PROVIDERS_CONFIG_TEMPLATE_FILEPATH) mev_params = args_with_right_defaults.mev_params
prometheus_config_template = read_file(static_files.PROMETHEUS_CONFIG_TEMPLATE_FILEPATH)
grafana_datasource_config_template = read_file(
plan.print("Read the prometheus, grafana templates") static_files.GRAFANA_DATASOURCE_CONFIG_TEMPLATE_FILEPATH
)
plan.print("Launching participant network with {0} participants and the following network params {1}".format(num_participants, network_params)) grafana_dashboards_config_template = read_file(
all_participants, cl_genesis_timestamp, genesis_validators_root = eth_network_module.run(plan, args_with_defaults_dict) static_files.GRAFANA_DASHBOARD_PROVIDERS_CONFIG_TEMPLATE_FILEPATH
)
all_el_client_contexts = [] prometheus_config_template = read_file(
all_cl_client_contexts = [] static_files.PROMETHEUS_CONFIG_TEMPLATE_FILEPATH
for participant in all_participants: )
all_el_client_contexts.append(participant.el_client_context)
all_cl_client_contexts.append(participant.cl_client_context) plan.print("Read the prometheus, grafana templates")
plan.print(
mev_endpoints = [] "Launching participant network with {0} participants and the following network params {1}".format(
# passed external relays get priority num_participants, network_params
# perhaps add mev_type External or remove this )
if hasattr(participant, "builder_network_params") and participant.builder_network_params != None: )
mev_endpoints = participant.builder_network_params.relay_end_points (
# otherwise dummy relays spinup if chosen all_participants,
elif args_with_right_defaults.mev_type and args_with_right_defaults.mev_type == MOCK_MEV_TYPE: cl_genesis_timestamp,
el_uri = "{0}:{1}".format(all_el_client_contexts[0].ip_addr, all_el_client_contexts[0].engine_rpc_port_num) genesis_validators_root,
beacon_uri = "{0}:{1}".format(all_cl_client_contexts[0].ip_addr, all_cl_client_contexts[0].http_port_num) ) = eth_network_module.run(plan, args_with_defaults_dict)
jwt_secret = all_el_client_contexts[0].jwt_secret
endpoint = mock_mev_launcher_module.launch_mock_mev(plan, el_uri, beacon_uri, jwt_secret, args_with_right_defaults.global_client_log_level) all_el_client_contexts = []
mev_endpoints.append(endpoint) all_cl_client_contexts = []
elif args_with_right_defaults.mev_type and args_with_right_defaults.mev_type == FULL_MEV_TYPE: for participant in all_participants:
el_uri = "http://{0}:{1}".format(all_el_client_contexts[0].ip_addr, all_el_client_contexts[0].rpc_port_num) all_el_client_contexts.append(participant.el_client_context)
builder_uri = "http://{0}:{1}".format(all_el_client_contexts[-1].ip_addr, all_el_client_contexts[-1].rpc_port_num) all_cl_client_contexts.append(participant.cl_client_context)
beacon_uri = ["http://{0}:{1}".format(context.ip_addr, context.http_port_num) for context in all_cl_client_contexts][-1]
beacon_uris = beacon_uri mev_endpoints = []
first_cl_client = all_cl_client_contexts[0] # passed external relays get priority
first_client_beacon_name = first_cl_client.beacon_service_name # perhaps add mev_type External or remove this
mev_flood_module.launch_mev_flood(plan, mev_params.mev_flood_image, el_uri, genesis_constants.PRE_FUNDED_ACCOUNTS) if (
epoch_recipe = GetHttpRequestRecipe( hasattr(participant, "builder_network_params")
endpoint = "/eth/v2/beacon/blocks/head", and participant.builder_network_params != None
port_id = HTTP_PORT_ID_FOR_FACT, ):
extract = { mev_endpoints = participant.builder_network_params.relay_end_points
"epoch": ".data.message.body.attestations[0].data.target.epoch" # otherwise dummy relays spinup if chosen
} elif (
) args_with_right_defaults.mev_type
plan.wait(recipe = epoch_recipe, field = "extract.epoch", assertion = ">=", target_value = str(network_params.capella_fork_epoch), timeout = "20m", service_name = first_client_beacon_name) and args_with_right_defaults.mev_type == MOCK_MEV_TYPE
endpoint = mev_relay_launcher_module.launch_mev_relay(plan, mev_params, network_params.network_id, beacon_uris, genesis_validators_root, builder_uri, network_params.seconds_per_slot, network_params.slots_per_epoch) ):
mev_flood_module.spam_in_background(plan, el_uri, mev_params.mev_flood_extra_args, mev_params.mev_flood_seconds_per_bundle, genesis_constants.PRE_FUNDED_ACCOUNTS) el_uri = "{0}:{1}".format(
if args_with_right_defaults.mev_params.launch_custom_flood: all_el_client_contexts[0].ip_addr,
mev_custom_flood_module.spam_in_background(plan, genesis_constants.PRE_FUNDED_ACCOUNTS[-1].private_key, genesis_constants.PRE_FUNDED_ACCOUNTS[0].address, el_uri) all_el_client_contexts[0].engine_rpc_port_num,
mev_endpoints.append(endpoint) )
beacon_uri = "{0}:{1}".format(
# spin up the mev boost contexts if some endpoints for relays have been passed all_cl_client_contexts[0].ip_addr, all_cl_client_contexts[0].http_port_num
all_mevboost_contexts = [] )
if mev_endpoints: jwt_secret = all_el_client_contexts[0].jwt_secret
for index, participant in enumerate(all_participants): endpoint = mock_mev_launcher_module.launch_mock_mev(
mev_boost_launcher = mev_boost_launcher_module.new_mev_boost_launcher(MEV_BOOST_SHOULD_CHECK_RELAY, mev_endpoints) plan,
mev_boost_service_name = "{0}{1}".format(parse_input.MEV_BOOST_SERVICE_NAME_PREFIX, index) el_uri,
mev_boost_context = mev_boost_launcher_module.launch(plan, mev_boost_launcher, mev_boost_service_name, network_params.network_id, mev_params.mev_boost_image) beacon_uri,
all_mevboost_contexts.append(mev_boost_context) jwt_secret,
args_with_right_defaults.global_client_log_level,
if not args_with_right_defaults.launch_additional_services: )
return mev_endpoints.append(endpoint)
elif (
plan.print("Launching transaction spammer") args_with_right_defaults.mev_type
tx_spammer_params = args_with_right_defaults.tx_spammer_params and args_with_right_defaults.mev_type == FULL_MEV_TYPE
transaction_spammer.launch_transaction_spammer(plan, genesis_constants.PRE_FUNDED_ACCOUNTS, all_el_client_contexts[0], tx_spammer_params) ):
plan.print("Succesfully launched transaction spammer") el_uri = "http://{0}:{1}".format(
all_el_client_contexts[0].ip_addr, all_el_client_contexts[0].rpc_port_num
)
plan.print("Launching Blob spammer") builder_uri = "http://{0}:{1}".format(
blob_spammer.launch_blob_spammer( all_el_client_contexts[-1].ip_addr, all_el_client_contexts[-1].rpc_port_num
plan, )
genesis_constants.PRE_FUNDED_ACCOUNTS, beacon_uri = [
all_el_client_contexts[0], "http://{0}:{1}".format(context.ip_addr, context.http_port_num)
all_cl_client_contexts[0], for context in all_cl_client_contexts
network_params.deneb_fork_epoch, ][-1]
network_params.seconds_per_slot, beacon_uris = beacon_uri
network_params.slots_per_epoch, first_cl_client = all_cl_client_contexts[0]
network_params.genesis_delay first_client_beacon_name = first_cl_client.beacon_service_name
) mev_flood_module.launch_mev_flood(
plan.print("Succesfully launched blob spammer") plan,
mev_params.mev_flood_image,
# We need a way to do time.sleep el_uri,
# TODO add code that waits for CL genesis genesis_constants.PRE_FUNDED_ACCOUNTS,
)
plan.print("Launching cl forkmon") epoch_recipe = GetHttpRequestRecipe(
cl_forkmon_config_template = read_file(static_files.CL_FORKMON_CONFIG_TEMPLATE_FILEPATH) endpoint="/eth/v2/beacon/blocks/head",
cl_forkmon.launch_cl_forkmon(plan, cl_forkmon_config_template, all_cl_client_contexts, cl_genesis_timestamp, network_params.seconds_per_slot, network_params.slots_per_epoch) port_id=HTTP_PORT_ID_FOR_FACT,
plan.print("Succesfully launched consensus layer forkmon") extract={"epoch": ".data.message.body.attestations[0].data.target.epoch"},
)
plan.print("Launching el forkmon") plan.wait(
el_forkmon_config_template = read_file(static_files.EL_FORKMON_CONFIG_TEMPLATE_FILEPATH) recipe=epoch_recipe,
el_forkmon.launch_el_forkmon(plan, el_forkmon_config_template, all_el_client_contexts) field="extract.epoch",
plan.print("Succesfully launched execution layer forkmon") assertion=">=",
target_value=str(network_params.capella_fork_epoch),
plan.print("Launching beacon metrics gazer") timeout="20m",
beacon_metrics_gazer_config_template = read_file(static_files.BEACON_METRICS_GAZER_CONFIG_TEMPLATE_FILEPATH) service_name=first_client_beacon_name,
beacon_metrics_gazer.launch_beacon_metrics_gazer(plan, beacon_metrics_gazer_config_template, all_cl_client_contexts,network_params) )
plan.print("Succesfully launched beacon metrics gazer") endpoint = mev_relay_launcher_module.launch_mev_relay(
plan,
plan.print("Launching light-beaconchain-explorer") mev_params,
light_beaconchain_explorer_config_template = read_file(static_files.LIGHT_BEACONCHAIN_CONFIG_TEMPLATE_FILEPATH) network_params.network_id,
light_beaconchain_explorer.launch_light_beacon(plan, light_beaconchain_explorer_config_template, all_cl_client_contexts) beacon_uris,
plan.print("Succesfully light-beaconchain-explorer") genesis_validators_root,
builder_uri,
plan.print("Launching prometheus...") network_params.seconds_per_slot,
prometheus_private_url = prometheus.launch_prometheus( network_params.slots_per_epoch,
plan, )
prometheus_config_template, mev_flood_module.spam_in_background(
all_cl_client_contexts, plan,
all_el_client_contexts, el_uri,
) mev_params.mev_flood_extra_args,
plan.print("Successfully launched Prometheus") mev_params.mev_flood_seconds_per_bundle,
genesis_constants.PRE_FUNDED_ACCOUNTS,
plan.print("Launching grafana...") )
grafana.launch_grafana(plan, grafana_datasource_config_template, grafana_dashboards_config_template, prometheus_private_url) if args_with_right_defaults.mev_params.launch_custom_flood:
plan.print("Succesfully launched grafana") mev_custom_flood_module.spam_in_background(
plan,
if args_with_right_defaults.wait_for_finalization: genesis_constants.PRE_FUNDED_ACCOUNTS[-1].private_key,
plan.print("Waiting for the first finalized epoch") genesis_constants.PRE_FUNDED_ACCOUNTS[0].address,
first_cl_client = all_cl_client_contexts[0] el_uri,
first_client_beacon_name = first_cl_client.beacon_service_name )
epoch_recipe = GetHttpRequestRecipe( mev_endpoints.append(endpoint)
endpoint = "/eth/v1/beacon/states/head/finality_checkpoints",
port_id = HTTP_PORT_ID_FOR_FACT, # spin up the mev boost contexts if some endpoints for relays have been passed
extract = { all_mevboost_contexts = []
"finalized_epoch": ".data.finalized.epoch" if mev_endpoints:
} for index, participant in enumerate(all_participants):
) mev_boost_launcher = mev_boost_launcher_module.new_mev_boost_launcher(
plan.wait(recipe = epoch_recipe, field = "extract.finalized_epoch", assertion = "!=", target_value = "0", timeout = "40m", service_name = first_client_beacon_name) MEV_BOOST_SHOULD_CHECK_RELAY, mev_endpoints
plan.print("First finalized epoch occurred successfully") )
mev_boost_service_name = "{0}{1}".format(
grafana_info = struct( parse_input.MEV_BOOST_SERVICE_NAME_PREFIX, index
dashboard_path = GRAFANA_DASHBOARD_PATH_URL, )
user = GRAFANA_USER, mev_boost_context = mev_boost_launcher_module.launch(
password = GRAFANA_PASSWORD plan,
) mev_boost_launcher,
output = struct(grafana_info = grafana_info) mev_boost_service_name,
network_params.network_id,
return output mev_params.mev_boost_image,
)
all_mevboost_contexts.append(mev_boost_context)
if not args_with_right_defaults.launch_additional_services:
return
plan.print("Launching transaction spammer")
tx_spammer_params = args_with_right_defaults.tx_spammer_params
transaction_spammer.launch_transaction_spammer(
plan,
genesis_constants.PRE_FUNDED_ACCOUNTS,
all_el_client_contexts[0],
tx_spammer_params,
)
plan.print("Succesfully launched transaction spammer")
plan.print("Launching Blob spammer")
blob_spammer.launch_blob_spammer(
plan,
genesis_constants.PRE_FUNDED_ACCOUNTS,
all_el_client_contexts[0],
all_cl_client_contexts[0],
network_params.deneb_fork_epoch,
network_params.seconds_per_slot,
network_params.slots_per_epoch,
network_params.genesis_delay,
)
plan.print("Succesfully launched blob spammer")
# We need a way to do time.sleep
# TODO add code that waits for CL genesis
plan.print("Launching cl forkmon")
cl_forkmon_config_template = read_file(
static_files.CL_FORKMON_CONFIG_TEMPLATE_FILEPATH
)
cl_forkmon.launch_cl_forkmon(
plan,
cl_forkmon_config_template,
all_cl_client_contexts,
cl_genesis_timestamp,
network_params.seconds_per_slot,
network_params.slots_per_epoch,
)
plan.print("Succesfully launched consensus layer forkmon")
plan.print("Launching el forkmon")
el_forkmon_config_template = read_file(
static_files.EL_FORKMON_CONFIG_TEMPLATE_FILEPATH
)
el_forkmon.launch_el_forkmon(
plan, el_forkmon_config_template, all_el_client_contexts
)
plan.print("Succesfully launched execution layer forkmon")
plan.print("Launching beacon metrics gazer")
beacon_metrics_gazer_config_template = read_file(
static_files.BEACON_METRICS_GAZER_CONFIG_TEMPLATE_FILEPATH
)
beacon_metrics_gazer.launch_beacon_metrics_gazer(
plan,
beacon_metrics_gazer_config_template,
all_cl_client_contexts,
network_params,
)
plan.print("Succesfully launched beacon metrics gazer")
plan.print("Launching light-beaconchain-explorer")
light_beaconchain_explorer_config_template = read_file(
static_files.LIGHT_BEACONCHAIN_CONFIG_TEMPLATE_FILEPATH
)
light_beaconchain_explorer.launch_light_beacon(
plan, light_beaconchain_explorer_config_template, all_cl_client_contexts
)
plan.print("Succesfully light-beaconchain-explorer")
plan.print("Launching prometheus...")
prometheus_private_url = prometheus.launch_prometheus(
plan,
prometheus_config_template,
all_cl_client_contexts,
all_el_client_contexts,
)
plan.print("Successfully launched Prometheus")
plan.print("Launching grafana...")
grafana.launch_grafana(
plan,
grafana_datasource_config_template,
grafana_dashboards_config_template,
prometheus_private_url,
)
plan.print("Succesfully launched grafana")
if args_with_right_defaults.wait_for_finalization:
plan.print("Waiting for the first finalized epoch")
first_cl_client = all_cl_client_contexts[0]
first_client_beacon_name = first_cl_client.beacon_service_name
epoch_recipe = GetHttpRequestRecipe(
endpoint="/eth/v1/beacon/states/head/finality_checkpoints",
port_id=HTTP_PORT_ID_FOR_FACT,
extract={"finalized_epoch": ".data.finalized.epoch"},
)
plan.wait(
recipe=epoch_recipe,
field="extract.finalized_epoch",
assertion="!=",
target_value="0",
timeout="40m",
service_name=first_client_beacon_name,
)
plan.print("First finalized epoch occurred successfully")
grafana_info = struct(
dashboard_path=GRAFANA_DASHBOARD_PATH_URL,
user=GRAFANA_USER,
password=GRAFANA_PASSWORD,
)
output = struct(grafana_info=grafana_info)
return output
shared_utils = import_module("github.com/kurtosis-tech/eth2-package/src/shared_utils/shared_utils.star") shared_utils = import_module(
"github.com/kurtosis-tech/eth2-package/src/shared_utils/shared_utils.star"
)
SERVICE_NAME = "beacon-metrics-gazer" SERVICE_NAME = "beacon-metrics-gazer"
IMAGE_NAME = "ethpandaops/beacon-metrics-gazer:master" IMAGE_NAME = "ethpandaops/beacon-metrics-gazer:master"
HTTP_PORT_ID = "http" HTTP_PORT_ID = "http"
HTTP_PORT_NUMBER = 8080 HTTP_PORT_NUMBER = 8080
BEACON_METRICS_GAZER_CONFIG_FILENAME = "validator-ranges.yaml" BEACON_METRICS_GAZER_CONFIG_FILENAME = "validator-ranges.yaml"
...@@ -12,58 +14,68 @@ BEACON_METRICS_GAZER_CONFIG_FILENAME = "validator-ranges.yaml" ...@@ -12,58 +14,68 @@ BEACON_METRICS_GAZER_CONFIG_FILENAME = "validator-ranges.yaml"
BEACON_METRICS_GAZER_CONFIG_MOUNT_DIRPATH_ON_SERVICE = "/config" BEACON_METRICS_GAZER_CONFIG_MOUNT_DIRPATH_ON_SERVICE = "/config"
USED_PORTS = { USED_PORTS = {
HTTP_PORT_ID:shared_utils.new_port_spec(HTTP_PORT_NUMBER, shared_utils.TCP_PROTOCOL, shared_utils.HTTP_APPLICATION_PROTOCOL) HTTP_PORT_ID: shared_utils.new_port_spec(
HTTP_PORT_NUMBER,
shared_utils.TCP_PROTOCOL,
shared_utils.HTTP_APPLICATION_PROTOCOL,
)
} }
def launch_beacon_metrics_gazer( def launch_beacon_metrics_gazer(
plan, plan, config_template, cl_client_contexts, network_params
config_template, ):
cl_client_contexts, data = []
network_params for index, client in enumerate(cl_client_contexts):
): start_index = index * network_params.num_validator_keys_per_node
end_index = ((index + 1) * network_params.num_validator_keys_per_node) - 1
data = [] service_name = client.beacon_service_name
for index, client in enumerate(cl_client_contexts): data.append(
start_index = index*network_params.num_validator_keys_per_node {
end_index = ((index+1)*network_params.num_validator_keys_per_node)-1 "ClientName": service_name,
service_name = client.beacon_service_name "Range": "{0}-{1}".format(start_index, end_index),
data.append({"ClientName": service_name, "Range": "{0}-{1}".format(start_index, end_index)}) }
)
template_data = {"Data": data}
template_data = {"Data": data}
template_and_data_by_rel_dest_filepath = {}
template_and_data_by_rel_dest_filepath[BEACON_METRICS_GAZER_CONFIG_FILENAME] = shared_utils.new_template_and_data(config_template, template_data) template_and_data_by_rel_dest_filepath = {}
template_and_data_by_rel_dest_filepath[
config_files_artifact_name = plan.render_templates(template_and_data_by_rel_dest_filepath, "validator-ranges") BEACON_METRICS_GAZER_CONFIG_FILENAME
] = shared_utils.new_template_and_data(config_template, template_data)
config = get_config(
config_files_artifact_name, config_files_artifact_name = plan.render_templates(
cl_client_contexts[0].ip_addr, template_and_data_by_rel_dest_filepath, "validator-ranges"
cl_client_contexts[0].http_port_num) )
plan.add_service(SERVICE_NAME, config) config = get_config(
config_files_artifact_name,
cl_client_contexts[0].ip_addr,
def get_config( cl_client_contexts[0].http_port_num,
config_files_artifact_name, )
ip_addr,
http_port_num): plan.add_service(SERVICE_NAME, config)
config_file_path = shared_utils.path_join(BEACON_METRICS_GAZER_CONFIG_MOUNT_DIRPATH_ON_SERVICE, BEACON_METRICS_GAZER_CONFIG_FILENAME)
return ServiceConfig(
image = IMAGE_NAME, def get_config(config_files_artifact_name, ip_addr, http_port_num):
ports = USED_PORTS, config_file_path = shared_utils.path_join(
files = { BEACON_METRICS_GAZER_CONFIG_MOUNT_DIRPATH_ON_SERVICE,
BEACON_METRICS_GAZER_CONFIG_MOUNT_DIRPATH_ON_SERVICE: config_files_artifact_name, BEACON_METRICS_GAZER_CONFIG_FILENAME,
}, )
cmd = [ return ServiceConfig(
"http://{0}:{1}".format(ip_addr, http_port_num), image=IMAGE_NAME,
"--ranges-file", ports=USED_PORTS,
config_file_path, files={
"--port", BEACON_METRICS_GAZER_CONFIG_MOUNT_DIRPATH_ON_SERVICE: config_files_artifact_name,
"{0}".format(HTTP_PORT_NUMBER), },
"--address", cmd=[
"0.0.0.0", "http://{0}:{1}".format(ip_addr, http_port_num),
"-v" "--ranges-file",
] config_file_path,
) "--port",
"{0}".format(HTTP_PORT_NUMBER),
"--address",
"0.0.0.0",
"-v",
],
)
...@@ -3,44 +3,63 @@ SERVICE_NAME = "blob-spammer" ...@@ -3,44 +3,63 @@ SERVICE_NAME = "blob-spammer"
ENTRYPOINT_ARGS = ["/bin/sh", "-c"] ENTRYPOINT_ARGS = ["/bin/sh", "-c"]
def launch_blob_spammer( def launch_blob_spammer(
plan, plan,
prefunded_addresses, prefunded_addresses,
el_client_context, el_client_context,
cl_client_context, cl_client_context,
deneb_fork_epoch, deneb_fork_epoch,
seconds_per_slot, seconds_per_slot,
slots_per_epoch, slots_per_epoch,
genesis_delay): genesis_delay,
config = get_config( ):
prefunded_addresses, config = get_config(
el_client_context, prefunded_addresses,
cl_client_context, el_client_context,
deneb_fork_epoch, cl_client_context,
seconds_per_slot, deneb_fork_epoch,
slots_per_epoch, seconds_per_slot,
genesis_delay) slots_per_epoch,
plan.add_service(SERVICE_NAME, config) genesis_delay,
)
plan.add_service(SERVICE_NAME, config)
def get_config( def get_config(
prefunded_addresses, prefunded_addresses,
el_client_context, el_client_context,
cl_client_context, cl_client_context,
deneb_fork_epoch, deneb_fork_epoch,
seconds_per_slot, seconds_per_slot,
slots_per_epoch, slots_per_epoch,
genesis_delay): genesis_delay,
dencunTime = (deneb_fork_epoch * slots_per_epoch * seconds_per_slot) + genesis_delay ):
return ServiceConfig( dencunTime = (deneb_fork_epoch * slots_per_epoch * seconds_per_slot) + genesis_delay
image = IMAGE_NAME, return ServiceConfig(
entrypoint = ENTRYPOINT_ARGS, image=IMAGE_NAME,
cmd = [" && ".join([ entrypoint=ENTRYPOINT_ARGS,
'apk update', cmd=[
'apk add curl jq', " && ".join(
'current_epoch=$(curl -s http://{0}:{1}/eth/v2/beacon/blocks/head | jq -r ".version")'.format(cl_client_context.ip_addr, cl_client_context.http_port_num), [
'echo $current_epoch', "apk update",
'while [ $current_epoch != "deneb" ]; do echo "waiting for deneb, current epoch is $current_epoch"; current_epoch=$(curl -s http://{0}:{1}/eth/v2/beacon/blocks/head | jq -r ".version"); sleep {2}; done'.format(cl_client_context.ip_addr, cl_client_context.http_port_num, seconds_per_slot), "apk add curl jq",
'echo "sleep is over, starting to send blob transactions"', 'current_epoch=$(curl -s http://{0}:{1}/eth/v2/beacon/blocks/head | jq -r ".version")'.format(
'/tx-fuzz.bin blobs --rpc=http://{0}:{1} --sk={2}'.format(el_client_context.ip_addr, el_client_context.rpc_port_num, prefunded_addresses[1].private_key), cl_client_context.ip_addr, cl_client_context.http_port_num
])] ),
) "echo $current_epoch",
'while [ $current_epoch != "deneb" ]; do echo "waiting for deneb, current epoch is $current_epoch"; current_epoch=$(curl -s http://{0}:{1}/eth/v2/beacon/blocks/head | jq -r ".version"); sleep {2}; done'.format(
cl_client_context.ip_addr,
cl_client_context.http_port_num,
seconds_per_slot,
),
'echo "sleep is over, starting to send blob transactions"',
"/tx-fuzz.bin blobs --rpc=http://{0}:{1} --sk={2}".format(
el_client_context.ip_addr,
el_client_context.rpc_port_num,
prefunded_addresses[1].private_key,
),
]
)
],
)
shared_utils = import_module("github.com/kurtosis-tech/eth2-package/src/shared_utils/shared_utils.star") shared_utils = import_module(
"github.com/kurtosis-tech/eth2-package/src/shared_utils/shared_utils.star"
)
SERVICE_NAME = "cl-forkmon" SERVICE_NAME = "cl-forkmon"
IMAGE_NAME = "ethpandaops/consensus-monitor:main" IMAGE_NAME = "ethpandaops/consensus-monitor:main"
HTTP_PORT_ID = "http" HTTP_PORT_ID = "http"
HTTP_PORT_NUMBER = 80 HTTP_PORT_NUMBER = 80
CL_FORKMON_CONFIG_FILENAME = "cl-forkmon-config.toml" CL_FORKMON_CONFIG_FILENAME = "cl-forkmon-config.toml"
CL_FORKMON_CONFIG_MOUNT_DIRPATH_ON_SERVICE = "/config" CL_FORKMON_CONFIG_MOUNT_DIRPATH_ON_SERVICE = "/config"
USED_PORTS = { USED_PORTS = {
HTTP_PORT_ID:shared_utils.new_port_spec(HTTP_PORT_NUMBER, shared_utils.TCP_PROTOCOL, shared_utils.HTTP_APPLICATION_PROTOCOL) HTTP_PORT_ID: shared_utils.new_port_spec(
HTTP_PORT_NUMBER,
shared_utils.TCP_PROTOCOL,
shared_utils.HTTP_APPLICATION_PROTOCOL,
)
} }
def launch_cl_forkmon( def launch_cl_forkmon(
plan, plan,
config_template, config_template,
cl_client_contexts, cl_client_contexts,
genesis_unix_timestamp, genesis_unix_timestamp,
seconds_per_slot, seconds_per_slot,
slots_per_epoch slots_per_epoch,
): ):
all_cl_client_info = []
all_cl_client_info = [] for client in cl_client_contexts:
for client in cl_client_contexts: client_info = new_cl_client_info(client.ip_addr, client.http_port_num)
client_info = new_cl_client_info(client.ip_addr, client.http_port_num) all_cl_client_info.append(client_info)
all_cl_client_info.append(client_info)
template_data = new_config_template_data(
template_data = new_config_template_data(HTTP_PORT_NUMBER, all_cl_client_info, seconds_per_slot, slots_per_epoch, genesis_unix_timestamp) HTTP_PORT_NUMBER,
all_cl_client_info,
template_and_data = shared_utils.new_template_and_data(config_template, template_data) seconds_per_slot,
template_and_data_by_rel_dest_filepath = {} slots_per_epoch,
template_and_data_by_rel_dest_filepath[CL_FORKMON_CONFIG_FILENAME] = template_and_data genesis_unix_timestamp,
)
config_files_artifact_name = plan.render_templates(template_and_data_by_rel_dest_filepath, "cl-forkmon-config")
template_and_data = shared_utils.new_template_and_data(
config = get_config(config_files_artifact_name) config_template, template_data
)
plan.add_service(SERVICE_NAME, config) template_and_data_by_rel_dest_filepath = {}
template_and_data_by_rel_dest_filepath[
CL_FORKMON_CONFIG_FILENAME
] = template_and_data
config_files_artifact_name = plan.render_templates(
template_and_data_by_rel_dest_filepath, "cl-forkmon-config"
)
config = get_config(config_files_artifact_name)
plan.add_service(SERVICE_NAME, config)
def get_config(config_files_artifact_name): def get_config(config_files_artifact_name):
config_file_path = shared_utils.path_join(CL_FORKMON_CONFIG_MOUNT_DIRPATH_ON_SERVICE, CL_FORKMON_CONFIG_FILENAME) config_file_path = shared_utils.path_join(
return ServiceConfig( CL_FORKMON_CONFIG_MOUNT_DIRPATH_ON_SERVICE, CL_FORKMON_CONFIG_FILENAME
image = IMAGE_NAME, )
ports = USED_PORTS, return ServiceConfig(
files = { image=IMAGE_NAME,
CL_FORKMON_CONFIG_MOUNT_DIRPATH_ON_SERVICE: config_files_artifact_name, ports=USED_PORTS,
}, files={
cmd = ["--config-path", config_file_path] CL_FORKMON_CONFIG_MOUNT_DIRPATH_ON_SERVICE: config_files_artifact_name,
) },
cmd=["--config-path", config_file_path],
)
def new_config_template_data(listen_port_num, cl_client_info, seconds_per_slot, slots_per_epoch, genesis_unix_timestamp):
return {
"ListenPortNum": listen_port_num, def new_config_template_data(
"CLClientInfo": cl_client_info, listen_port_num,
"SecondsPerSlot": seconds_per_slot, cl_client_info,
"SlotsPerEpoch": slots_per_epoch, seconds_per_slot,
"GenesisUnixTimestamp": genesis_unix_timestamp, slots_per_epoch,
} genesis_unix_timestamp,
):
return {
"ListenPortNum": listen_port_num,
"CLClientInfo": cl_client_info,
"SecondsPerSlot": seconds_per_slot,
"SlotsPerEpoch": slots_per_epoch,
"GenesisUnixTimestamp": genesis_unix_timestamp,
}
def new_cl_client_info(ip_addr, port_num): def new_cl_client_info(ip_addr, port_num):
return { return {"IPAddr": ip_addr, "PortNum": port_num}
"IPAddr": ip_addr,
"PortNum": port_num
}
shared_utils = import_module("github.com/kurtosis-tech/eth2-package/src/shared_utils/shared_utils.star") shared_utils = import_module(
"github.com/kurtosis-tech/eth2-package/src/shared_utils/shared_utils.star"
)
SERVICE_NAME = "el-forkmon" SERVICE_NAME = "el-forkmon"
IMAGE_NAME = "ethpandaops/execution-monitor:master" IMAGE_NAME = "ethpandaops/execution-monitor:master"
HTTP_PORT_ID = "http" HTTP_PORT_ID = "http"
HTTP_PORT_NUMBER = 8080 HTTP_PORT_NUMBER = 8080
EL_FORKMON_CONFIG_FILENAME = "el-forkmon-config.toml" EL_FORKMON_CONFIG_FILENAME = "el-forkmon-config.toml"
...@@ -12,56 +14,65 @@ EL_FORKMON_CONFIG_FILENAME = "el-forkmon-config.toml" ...@@ -12,56 +14,65 @@ EL_FORKMON_CONFIG_FILENAME = "el-forkmon-config.toml"
EL_FORKMON_CONFIG_MOUNT_DIRPATH_ON_SERVICE = "/config" EL_FORKMON_CONFIG_MOUNT_DIRPATH_ON_SERVICE = "/config"
USED_PORTS = { USED_PORTS = {
HTTP_PORT_ID:shared_utils.new_port_spec(HTTP_PORT_NUMBER, shared_utils.TCP_PROTOCOL, shared_utils.HTTP_APPLICATION_PROTOCOL) HTTP_PORT_ID: shared_utils.new_port_spec(
HTTP_PORT_NUMBER,
shared_utils.TCP_PROTOCOL,
shared_utils.HTTP_APPLICATION_PROTOCOL,
)
} }
def launch_el_forkmon( def launch_el_forkmon(
plan, plan,
config_template, config_template,
el_client_contexts, el_client_contexts,
): ):
all_el_client_info = []
for client in el_client_contexts:
client_info = new_el_client_info(
client.ip_addr, client.rpc_port_num, client.service_name
)
all_el_client_info.append(client_info)
all_el_client_info = [] template_data = new_config_template_data(HTTP_PORT_NUMBER, all_el_client_info)
for client in el_client_contexts:
client_info = new_el_client_info(client.ip_addr, client.rpc_port_num, client.service_name)
all_el_client_info.append(client_info)
template_data = new_config_template_data(HTTP_PORT_NUMBER, all_el_client_info) template_and_data = shared_utils.new_template_and_data(
config_template, template_data
)
template_and_data_by_rel_dest_filepath = {}
template_and_data_by_rel_dest_filepath[
EL_FORKMON_CONFIG_FILENAME
] = template_and_data
template_and_data = shared_utils.new_template_and_data(config_template, template_data) config_files_artifact_name = plan.render_templates(
template_and_data_by_rel_dest_filepath = {} template_and_data_by_rel_dest_filepath, "el-forkmon-config"
template_and_data_by_rel_dest_filepath[EL_FORKMON_CONFIG_FILENAME] = template_and_data )
config_files_artifact_name = plan.render_templates(template_and_data_by_rel_dest_filepath, "el-forkmon-config") config = get_config(config_files_artifact_name)
config = get_config(config_files_artifact_name) plan.add_service(SERVICE_NAME, config)
plan.add_service(SERVICE_NAME, config)
def get_config(config_files_artifact_name): def get_config(config_files_artifact_name):
config_file_path = shared_utils.path_join(EL_FORKMON_CONFIG_MOUNT_DIRPATH_ON_SERVICE, EL_FORKMON_CONFIG_FILENAME) config_file_path = shared_utils.path_join(
return ServiceConfig( EL_FORKMON_CONFIG_MOUNT_DIRPATH_ON_SERVICE, EL_FORKMON_CONFIG_FILENAME
image = IMAGE_NAME, )
ports = USED_PORTS, return ServiceConfig(
files = { image=IMAGE_NAME,
EL_FORKMON_CONFIG_MOUNT_DIRPATH_ON_SERVICE: config_files_artifact_name, ports=USED_PORTS,
}, files={
cmd = [config_file_path] EL_FORKMON_CONFIG_MOUNT_DIRPATH_ON_SERVICE: config_files_artifact_name,
) },
cmd=[config_file_path],
)
def new_config_template_data(listen_port_num, el_client_info): def new_config_template_data(listen_port_num, el_client_info):
return { return {
"ListenPortNum": listen_port_num, "ListenPortNum": listen_port_num,
"ELClientInfo": el_client_info, "ELClientInfo": el_client_info,
} }
def new_el_client_info(ip_addr, port_num, service_name): def new_el_client_info(ip_addr, port_num, service_name):
return { return {"IPAddr": ip_addr, "PortNum": port_num, "Name": service_name}
"IPAddr": ip_addr,
"PortNum": port_num,
"Name": service_name
}
shared_utils = import_module("github.com/kurtosis-tech/eth2-package/src/shared_utils/shared_utils.star") shared_utils = import_module(
static_files = import_module("github.com/kurtosis-tech/eth2-package/src/static_files/static_files.star") "github.com/kurtosis-tech/eth2-package/src/shared_utils/shared_utils.star"
)
static_files = import_module(
"github.com/kurtosis-tech/eth2-package/src/static_files/static_files.star"
)
SERVICE_NAME = "grafana" SERVICE_NAME = "grafana"
...@@ -21,61 +25,95 @@ GRAFANA_DASHBOARDS_FILEPATH_ON_SERVICE = GRAFANA_DASHBOARDS_DIRPATH_ON_SERVICE ...@@ -21,61 +25,95 @@ GRAFANA_DASHBOARDS_FILEPATH_ON_SERVICE = GRAFANA_DASHBOARDS_DIRPATH_ON_SERVICE
USED_PORTS = { USED_PORTS = {
HTTP_PORT_ID: shared_utils.new_port_spec(HTTP_PORT_NUMBER_UINT16, shared_utils.TCP_PROTOCOL, shared_utils.HTTP_APPLICATION_PROTOCOL) HTTP_PORT_ID: shared_utils.new_port_spec(
HTTP_PORT_NUMBER_UINT16,
shared_utils.TCP_PROTOCOL,
shared_utils.HTTP_APPLICATION_PROTOCOL,
)
} }
def launch_grafana(plan, datasource_config_template, dashboard_providers_config_template, prometheus_private_url): def launch_grafana(
grafana_config_artifacts_uuid, grafana_dashboards_artifacts_uuid = get_grafana_config_dir_artifact_uuid(plan, datasource_config_template, dashboard_providers_config_template, prometheus_private_url) plan,
datasource_config_template,
config = get_config(grafana_config_artifacts_uuid, grafana_dashboards_artifacts_uuid) dashboard_providers_config_template,
prometheus_private_url,
plan.add_service(SERVICE_NAME, config) ):
(
grafana_config_artifacts_uuid,
def get_grafana_config_dir_artifact_uuid(plan, datasource_config_template, dashboard_providers_config_template, prometheus_private_url): grafana_dashboards_artifacts_uuid,
datasource_data = new_datasource_config_template_data(prometheus_private_url) ) = get_grafana_config_dir_artifact_uuid(
datasource_template_and_data = shared_utils.new_template_and_data(datasource_config_template, datasource_data) plan,
datasource_config_template,
dashboard_providers_data = new_dashboard_providers_config_template_data(GRAFANA_DASHBOARDS_FILEPATH_ON_SERVICE) dashboard_providers_config_template,
dashboard_providers_template_and_data = shared_utils.new_template_and_data(dashboard_providers_config_template, dashboard_providers_data) prometheus_private_url,
)
template_and_data_by_rel_dest_filepath = {}
template_and_data_by_rel_dest_filepath[DATASOURCE_CONFIG_REL_FILEPATH] = datasource_template_and_data config = get_config(
template_and_data_by_rel_dest_filepath[DASHBOARD_PROVIDERS_CONFIG_REL_FILEPATH] = dashboard_providers_template_and_data grafana_config_artifacts_uuid, grafana_dashboards_artifacts_uuid
)
grafana_config_artifacts_name = plan.render_templates(template_and_data_by_rel_dest_filepath, name="grafana-config")
plan.add_service(SERVICE_NAME, config)
grafana_dashboards_artifacts_name = plan.upload_files(static_files.GRAFANA_DASHBOARDS_CONFIG_DIRPATH, name="grafana-dashboards")
return grafana_config_artifacts_name, grafana_dashboards_artifacts_name def get_grafana_config_dir_artifact_uuid(
plan,
datasource_config_template,
dashboard_providers_config_template,
prometheus_private_url,
):
datasource_data = new_datasource_config_template_data(prometheus_private_url)
datasource_template_and_data = shared_utils.new_template_and_data(
datasource_config_template, datasource_data
)
dashboard_providers_data = new_dashboard_providers_config_template_data(
GRAFANA_DASHBOARDS_FILEPATH_ON_SERVICE
)
dashboard_providers_template_and_data = shared_utils.new_template_and_data(
dashboard_providers_config_template, dashboard_providers_data
)
template_and_data_by_rel_dest_filepath = {}
template_and_data_by_rel_dest_filepath[
DATASOURCE_CONFIG_REL_FILEPATH
] = datasource_template_and_data
template_and_data_by_rel_dest_filepath[
DASHBOARD_PROVIDERS_CONFIG_REL_FILEPATH
] = dashboard_providers_template_and_data
grafana_config_artifacts_name = plan.render_templates(
template_and_data_by_rel_dest_filepath, name="grafana-config"
)
grafana_dashboards_artifacts_name = plan.upload_files(
static_files.GRAFANA_DASHBOARDS_CONFIG_DIRPATH, name="grafana-dashboards"
)
return grafana_config_artifacts_name, grafana_dashboards_artifacts_name
def get_config(grafana_config_artifacts_name, grafana_dashboards_artifacts_name): def get_config(grafana_config_artifacts_name, grafana_dashboards_artifacts_name):
return ServiceConfig( return ServiceConfig(
image = IMAGE_NAME, image=IMAGE_NAME,
ports = USED_PORTS, ports=USED_PORTS,
env_vars = { env_vars={
CONFIG_DIRPATH_ENV_VAR: GRAFANA_CONFIG_DIRPATH_ON_SERVICE, CONFIG_DIRPATH_ENV_VAR: GRAFANA_CONFIG_DIRPATH_ON_SERVICE,
"GF_AUTH_ANONYMOUS_ENABLED": "true", "GF_AUTH_ANONYMOUS_ENABLED": "true",
"GF_AUTH_ANONYMOUS_ORG_ROLE": "Admin", "GF_AUTH_ANONYMOUS_ORG_ROLE": "Admin",
"GF_AUTH_ANONYMOUS_ORG_NAME": "Main Org.", "GF_AUTH_ANONYMOUS_ORG_NAME": "Main Org.",
"GF_DASHBOARDS_DEFAULT_HOME_DASHBOARD_PATH": "/dashboards/default.json", "GF_DASHBOARDS_DEFAULT_HOME_DASHBOARD_PATH": "/dashboards/default.json",
}, },
files = { files={
GRAFANA_CONFIG_DIRPATH_ON_SERVICE: grafana_config_artifacts_name, GRAFANA_CONFIG_DIRPATH_ON_SERVICE: grafana_config_artifacts_name,
GRAFANA_DASHBOARDS_DIRPATH_ON_SERVICE: grafana_dashboards_artifacts_name GRAFANA_DASHBOARDS_DIRPATH_ON_SERVICE: grafana_dashboards_artifacts_name,
} },
) )
def new_datasource_config_template_data(prometheus_url): def new_datasource_config_template_data(prometheus_url):
return { return {"PrometheusURL": prometheus_url}
"PrometheusURL": prometheus_url
}
def new_dashboard_providers_config_template_data(dashboards_dirpath): def new_dashboard_providers_config_template_data(dashboards_dirpath):
return { return {"DashboardsDirpath": dashboards_dirpath}
"DashboardsDirpath": dashboards_dirpath
}
shared_utils = import_module("github.com/kurtosis-tech/eth2-package/src/shared_utils/shared_utils.star") shared_utils = import_module(
"github.com/kurtosis-tech/eth2-package/src/shared_utils/shared_utils.star"
)
SERVICE_NAME = "light-beaconchain" SERVICE_NAME = "light-beaconchain"
IMAGE_NAME = "ethpandaops/dora-the-explorer:master" IMAGE_NAME = "ethpandaops/dora-the-explorer:master"
HTTP_PORT_ID = "http" HTTP_PORT_ID = "http"
HTTP_PORT_NUMBER = 8080 HTTP_PORT_NUMBER = 8080
LIGHT_BEACONCHAIN_CONFIG_FILENAME = "light-beaconchain-config.yaml" LIGHT_BEACONCHAIN_CONFIG_FILENAME = "light-beaconchain-config.yaml"
...@@ -19,60 +21,69 @@ CL_CONFIG_ARTIFACT_NAME = "cl-genesis-data" ...@@ -19,60 +21,69 @@ CL_CONFIG_ARTIFACT_NAME = "cl-genesis-data"
USED_PORTS = { USED_PORTS = {
HTTP_PORT_ID:shared_utils.new_port_spec(HTTP_PORT_NUMBER, shared_utils.TCP_PROTOCOL, shared_utils.HTTP_APPLICATION_PROTOCOL) HTTP_PORT_ID: shared_utils.new_port_spec(
HTTP_PORT_NUMBER,
shared_utils.TCP_PROTOCOL,
shared_utils.HTTP_APPLICATION_PROTOCOL,
)
} }
def launch_light_beacon( def launch_light_beacon(
plan, plan,
config_template, config_template,
cl_client_contexts, cl_client_contexts,
): ):
all_cl_client_info = []
for index, client in enumerate(cl_client_contexts):
all_cl_client_info.append(
new_cl_client_info(
client.ip_addr, client.http_port_num, client.beacon_service_name
)
)
all_cl_client_info = [] template_data = new_config_template_data(HTTP_PORT_NUMBER, all_cl_client_info)
for index, client in enumerate(cl_client_contexts):
all_cl_client_info.append(new_cl_client_info(client.ip_addr, client.http_port_num, client.beacon_service_name))
template_data = new_config_template_data(HTTP_PORT_NUMBER, all_cl_client_info) template_and_data = shared_utils.new_template_and_data(
config_template, template_data
)
template_and_data_by_rel_dest_filepath = {}
template_and_data_by_rel_dest_filepath[
LIGHT_BEACONCHAIN_CONFIG_FILENAME
] = template_and_data
template_and_data = shared_utils.new_template_and_data(config_template, template_data) config_files_artifact_name = plan.render_templates(
template_and_data_by_rel_dest_filepath = {} template_and_data_by_rel_dest_filepath, "light-beaconchain-config"
template_and_data_by_rel_dest_filepath[LIGHT_BEACONCHAIN_CONFIG_FILENAME] = template_and_data )
config_files_artifact_name = plan.render_templates(template_and_data_by_rel_dest_filepath, "light-beaconchain-config") config = get_config(config_files_artifact_name)
config = get_config(config_files_artifact_name) plan.add_service(SERVICE_NAME, config)
plan.add_service(SERVICE_NAME, config)
def get_config(config_files_artifact_name): def get_config(config_files_artifact_name):
config_file_path = shared_utils.path_join(LIGHT_BEACONCHAIN_CONFIG_MOUNT_DIRPATH_ON_SERVICE, LIGHT_BEACONCHAIN_CONFIG_FILENAME) config_file_path = shared_utils.path_join(
return ServiceConfig( LIGHT_BEACONCHAIN_CONFIG_MOUNT_DIRPATH_ON_SERVICE,
image = IMAGE_NAME, LIGHT_BEACONCHAIN_CONFIG_FILENAME,
ports = USED_PORTS, )
files = { return ServiceConfig(
LIGHT_BEACONCHAIN_CONFIG_MOUNT_DIRPATH_ON_SERVICE: config_files_artifact_name, image=IMAGE_NAME,
VALIDATOR_RANGES_MOUNT_DIRPATH_ON_SERVICE: VALIDATOR_RANGES_ARTIFACT_NAME, ports=USED_PORTS,
CL_CONFIG_MOUNT_DIRPATH_ON_SERVICE: CL_CONFIG_ARTIFACT_NAME files={
LIGHT_BEACONCHAIN_CONFIG_MOUNT_DIRPATH_ON_SERVICE: config_files_artifact_name,
}, VALIDATOR_RANGES_MOUNT_DIRPATH_ON_SERVICE: VALIDATOR_RANGES_ARTIFACT_NAME,
cmd = [ CL_CONFIG_MOUNT_DIRPATH_ON_SERVICE: CL_CONFIG_ARTIFACT_NAME,
"-config", },
config_file_path cmd=["-config", config_file_path],
] )
)
def new_config_template_data(listen_port_num, cl_client_info): def new_config_template_data(listen_port_num, cl_client_info):
return { return {
"ListenPortNum": listen_port_num, "ListenPortNum": listen_port_num,
"CLClientInfo": cl_client_info, "CLClientInfo": cl_client_info,
} }
def new_cl_client_info(ip_addr, port_num, service_name): def new_cl_client_info(ip_addr, port_num, service_name):
return { return {"IPAddr": ip_addr, "PortNum": port_num, "Name": service_name}
"IPAddr": ip_addr,
"PortNum": port_num,
"Name": service_name
}
def new_mev_boost_context(private_ip_address, port): def new_mev_boost_context(private_ip_address, port):
return struct( return struct(
private_ip_address = private_ip_address, private_ip_address=private_ip_address,
port = port, port=port,
) )
def mev_boost_endpoint(mev_boost_context): def mev_boost_endpoint(mev_boost_context):
return "http://{0}:{1}".format(mev_boost_context.private_ip_address, mev_boost_context.port) return "http://{0}:{1}".format(
mev_boost_context.private_ip_address, mev_boost_context.port
)
shared_utils = import_module("github.com/kurtosis-tech/eth2-package/src/shared_utils/shared_utils.star") shared_utils = import_module(
mev_boost_context_module = import_module("github.com/kurtosis-tech/eth2-package/src/mev_boost/mev_boost_context.star") "github.com/kurtosis-tech/eth2-package/src/shared_utils/shared_utils.star"
parse_input = import_module("github.com/kurtosis-tech/eth2-package/src/package_io/parse_input.star") )
mev_boost_context_module = import_module(
"github.com/kurtosis-tech/eth2-package/src/mev_boost/mev_boost_context.star"
)
parse_input = import_module(
"github.com/kurtosis-tech/eth2-package/src/package_io/parse_input.star"
)
FLASHBOTS_MEV_BOOST_PROTOCOL = "TCP" FLASHBOTS_MEV_BOOST_PROTOCOL = "TCP"
USED_PORTS = { USED_PORTS = {
"api": shared_utils.new_port_spec(parse_input.FLASHBOTS_MEV_BOOST_PORT, FLASHBOTS_MEV_BOOST_PROTOCOL, wait="5s") "api": shared_utils.new_port_spec(
parse_input.FLASHBOTS_MEV_BOOST_PORT, FLASHBOTS_MEV_BOOST_PROTOCOL, wait="5s"
)
} }
NETWORK_ID_TO_NAME = { NETWORK_ID_TO_NAME = {
"5": "goerli", "5": "goerli",
"11155111": "sepolia", "11155111": "sepolia",
"3": "ropsten", "3": "ropsten",
} }
def launch(plan, mev_boost_launcher, service_name, network_id, mev_boost_image): def launch(plan, mev_boost_launcher, service_name, network_id, mev_boost_image):
config = get_config(mev_boost_launcher, network_id, mev_boost_image) config = get_config(mev_boost_launcher, network_id, mev_boost_image)
mev_boost_service = plan.add_service(service_name, config) mev_boost_service = plan.add_service(service_name, config)
return mev_boost_context_module.new_mev_boost_context(mev_boost_service.ip_address, parse_input.FLASHBOTS_MEV_BOOST_PORT) return mev_boost_context_module.new_mev_boost_context(
mev_boost_service.ip_address, parse_input.FLASHBOTS_MEV_BOOST_PORT
)
def get_config(mev_boost_launcher, network_id, mev_boost_image): def get_config(mev_boost_launcher, network_id, mev_boost_image):
command = ["mev-boost"] command = ["mev-boost"]
if mev_boost_launcher.should_check_relay:
command.append("-relay-check")
return ServiceConfig(
image = mev_boost_image,
ports = USED_PORTS,
cmd = command,
env_vars = {
# TODO(maybe) remove the hardcoding
# This is set to match this file https://github.com/kurtosis-tech/eth-network-package/blob/main/static_files/genesis-generation-config/cl/config.yaml.tmpl#L11
# latest-notes
# does this need genesis time to be set as well
"GENESIS_FORK_VERSION": "0x10000038",
"BOOST_LISTEN_ADDR": "0.0.0.0:{0}".format(parse_input.FLASHBOTS_MEV_BOOST_PORT),
# maybe this is breaking; this isn't verifyign the bid and not sending it to the validator
"SKIP_RELAY_SIGNATURE_CHECK": "1",
"RELAYS": mev_boost_launcher.relay_end_points[0]
}
)
if mev_boost_launcher.should_check_relay:
command.append("-relay-check")
def new_mev_boost_launcher(should_check_relay, relay_end_points): return ServiceConfig(
return struct(should_check_relay=should_check_relay, relay_end_points=relay_end_points) image=mev_boost_image,
ports=USED_PORTS,
cmd=command,
env_vars={
# TODO(maybe) remove the hardcoding
# This is set to match this file https://github.com/kurtosis-tech/eth-network-package/blob/main/static_files/genesis-generation-config/cl/config.yaml.tmpl#L11
# latest-notes
# does this need genesis time to be set as well
"GENESIS_FORK_VERSION": "0x10000038",
"BOOST_LISTEN_ADDR": "0.0.0.0:{0}".format(
parse_input.FLASHBOTS_MEV_BOOST_PORT
),
# maybe this is breaking; this isn't verifyign the bid and not sending it to the validator
"SKIP_RELAY_SIGNATURE_CHECK": "1",
"RELAYS": mev_boost_launcher.relay_end_points[0],
},
)
def new_mev_boost_launcher(should_check_relay, relay_end_points):
return struct(
should_check_relay=should_check_relay, relay_end_points=relay_end_points
)
PYTHON_IMAGE = "python:3.11-alpine" PYTHON_IMAGE = "python:3.11-alpine"
CUSTOM_FLOOD_SREVICE_NAME = "mev-custom-flood" CUSTOM_FLOOD_SREVICE_NAME = "mev-custom-flood"
def spam_in_background(plan, sender_key, receiver_key, el_uri): def spam_in_background(plan, sender_key, receiver_key, el_uri):
sender_script = plan.upload_files("github.com/kurtosis-tech/eth2-package/src/mev_custom_flood/sender.py") sender_script = plan.upload_files(
"github.com/kurtosis-tech/eth2-package/src/mev_custom_flood/sender.py"
)
plan.add_service( plan.add_service(
name = CUSTOM_FLOOD_SREVICE_NAME, name=CUSTOM_FLOOD_SREVICE_NAME,
config = ServiceConfig( config=ServiceConfig(
image = PYTHON_IMAGE, image=PYTHON_IMAGE,
files = { files={"/tmp": sender_script},
"/tmp": sender_script cmd=["/bin/sh", "-c", "touch /tmp/sender.log && tail -f /tmp/sender.log"],
}, env_vars={
cmd = ["/bin/sh", "-c", "touch /tmp/sender.log && tail -f /tmp/sender.log"],
env_vars = {
"SENDER_PRIVATE_KEY": sender_key, "SENDER_PRIVATE_KEY": sender_key,
"RECEIVER_PUBLIC_KEY": receiver_key, "RECEIVER_PUBLIC_KEY": receiver_key,
"EL_RPC_URI": el_uri, "EL_RPC_URI": el_uri,
} },
) ),
) )
plan.exec( plan.exec(
service_name = CUSTOM_FLOOD_SREVICE_NAME, service_name=CUSTOM_FLOOD_SREVICE_NAME,
recipe = ExecRecipe(["pip", "install", "web3"]) recipe=ExecRecipe(["pip", "install", "web3"]),
) )
plan.exec( plan.exec(
service_name = CUSTOM_FLOOD_SREVICE_NAME, service_name=CUSTOM_FLOOD_SREVICE_NAME,
recipe = ExecRecipe(["/bin/sh", "-c", "nohup python /tmp/sender.py > /dev/null 2>&1 &"]) recipe=ExecRecipe(
["/bin/sh", "-c", "nohup python /tmp/sender.py > /dev/null 2>&1 &"]
),
) )
ADMIN_KEY_INDEX = 0 ADMIN_KEY_INDEX = 0
USER_KEY_INDEX = 2 USER_KEY_INDEX = 2
def prefixed_address(address): def prefixed_address(address):
return "0x" + address return "0x" + address
def launch_mev_flood(plan, image, el_uri, genesis_accounts): def launch_mev_flood(plan, image, el_uri, genesis_accounts):
plan.add_service( plan.add_service(
name = "mev-flood", name="mev-flood",
config = ServiceConfig( config=ServiceConfig(
image = image, image=image,
entrypoint = ["/bin/sh", "-c", "touch main.log && tail -F main.log"] entrypoint=["/bin/sh", "-c", "touch main.log && tail -F main.log"],
) ),
) )
plan.exec( plan.exec(
service_name = "mev-flood", service_name="mev-flood",
recipe = ExecRecipe( recipe=ExecRecipe(
command = ["/bin/sh", "-c", "./run init -r {0} -k {1} -u {2} -s deployment.json".format(el_uri, prefixed_address(genesis_accounts[0].private_key), prefixed_address(genesis_accounts[2].private_key))] command=[
) "/bin/sh",
"-c",
"./run init -r {0} -k {1} -u {2} -s deployment.json".format(
el_uri,
prefixed_address(genesis_accounts[0].private_key),
prefixed_address(genesis_accounts[2].private_key),
),
]
),
) )
def spam_in_background(plan, el_uri, mev_flood_extra_args, seconds_per_bundle, genesis_accounts):
admin_key, user_key = prefixed_address(genesis_accounts[0].private_key), prefixed_address(genesis_accounts[2].private_key) def spam_in_background(
command = ["/bin/sh", "-c", "nohup ./run spam -r {0} -k {1} -u {2} -l deployment.json --secondsPerBundle {3} >main.log 2>&1 &".format(el_uri, admin_key, user_key, seconds_per_bundle)] plan, el_uri, mev_flood_extra_args, seconds_per_bundle, genesis_accounts
):
admin_key, user_key = prefixed_address(
genesis_accounts[0].private_key
), prefixed_address(genesis_accounts[2].private_key)
command = [
"/bin/sh",
"-c",
"nohup ./run spam -r {0} -k {1} -u {2} -l deployment.json --secondsPerBundle {3} >main.log 2>&1 &".format(
el_uri, admin_key, user_key, seconds_per_bundle
),
]
if mev_flood_extra_args: if mev_flood_extra_args:
joined_extra_args = " ".join(mev_flood_extra_args) joined_extra_args = " ".join(mev_flood_extra_args)
command = ["/bin/sh", "-c", "nohup ./run spam -r {0} -k {1} -u {2} -l deployment.json --secondsPerBundle {3} {4} >main.log 2>&1 &".format(el_uri, admin_key, user_key, seconds_per_bundle, joined_extra_args)] command = [
plan.exec( "/bin/sh",
service_name = "mev-flood", "-c",
recipe = ExecRecipe( "nohup ./run spam -r {0} -k {1} -u {2} -l deployment.json --secondsPerBundle {3} {4} >main.log 2>&1 &".format(
command = command el_uri, admin_key, user_key, seconds_per_bundle, joined_extra_args
) ),
) ]
plan.exec(service_name="mev-flood", recipe=ExecRecipe(command=command))
...@@ -12,64 +12,128 @@ MEV_RELAY_ENDPOINT_PORT = 9062 ...@@ -12,64 +12,128 @@ MEV_RELAY_ENDPOINT_PORT = 9062
MEV_RELAY_WEBSITE_PORT = 9060 MEV_RELAY_WEBSITE_PORT = 9060
NETWORK_ID_TO_NAME = { NETWORK_ID_TO_NAME = {
"5": "goerli", "5": "goerli",
"11155111": "sepolia", "11155111": "sepolia",
"3": "ropsten", "3": "ropsten",
} }
def launch_mev_relay(plan, mev_params, network_id, beacon_uris, validator_root, builder_uri, seconds_per_slot, slots_per_epoch = 32):
def launch_mev_relay(
plan,
mev_params,
network_id,
beacon_uris,
validator_root,
builder_uri,
seconds_per_slot,
slots_per_epoch=32,
):
redis = redis_module.run(plan) redis = redis_module.run(plan)
# making the password postgres as the relay expects it to be postgres # making the password postgres as the relay expects it to be postgres
postgres = postgres_module.run(plan, password = "postgres", user = "postgres", database = "postgres", service_name = "postgres") postgres = postgres_module.run(
plan,
password="postgres",
user="postgres",
database="postgres",
service_name="postgres",
)
network_name = NETWORK_ID_TO_NAME.get(network_id, network_id) network_name = NETWORK_ID_TO_NAME.get(network_id, network_id)
image = mev_params.mev_relay_image image = mev_params.mev_relay_image
# TODO(maybe) remove hardocded values for the forks # TODO(maybe) remove hardocded values for the forks
env_vars= { env_vars = {
"GENESIS_FORK_VERSION": "0x10000038", "GENESIS_FORK_VERSION": "0x10000038",
"BELLATRIX_FORK_VERSION": "0x30000038", "BELLATRIX_FORK_VERSION": "0x30000038",
"CAPELLA_FORK_VERSION": "0x40000038", "CAPELLA_FORK_VERSION": "0x40000038",
"DENEB_FORK_VERSION": "0x50000038", "DENEB_FORK_VERSION": "0x50000038",
"GENESIS_VALIDATORS_ROOT": validator_root, "GENESIS_VALIDATORS_ROOT": validator_root,
"SEC_PER_SLOT": str(seconds_per_slot), "SEC_PER_SLOT": str(seconds_per_slot),
"SLOTS_PER_EPOCH": str(slots_per_epoch) "SLOTS_PER_EPOCH": str(slots_per_epoch),
} }
redis_url = "{}:{}".format(redis.hostname, redis.port_number) redis_url = "{}:{}".format(redis.hostname, redis.port_number)
postgres_url = postgres.url + "?sslmode=disable" postgres_url = postgres.url + "?sslmode=disable"
plan.add_service( plan.add_service(
name = MEV_RELAY_HOUSEKEEPER, name=MEV_RELAY_HOUSEKEEPER,
config = ServiceConfig( config=ServiceConfig(
image = image, image=image,
cmd = ["housekeeper", "--network", "custom", "--db", postgres_url, "--redis-uri", redis_url, "--beacon-uris", beacon_uris] + mev_params.mev_relay_housekeeper_extra_args, cmd=[
env_vars= env_vars "housekeeper",
) "--network",
"custom",
"--db",
postgres_url,
"--redis-uri",
redis_url,
"--beacon-uris",
beacon_uris,
]
+ mev_params.mev_relay_housekeeper_extra_args,
env_vars=env_vars,
),
) )
api = plan.add_service( api = plan.add_service(
name = MEV_RELAY_ENDPOINT, name=MEV_RELAY_ENDPOINT,
config = ServiceConfig( config=ServiceConfig(
image = image, image=image,
cmd = ["api", "--network", "custom", "--db", postgres_url, "--secret-key", DUMMY_SECRET_KEY, "--listen-addr", "0.0.0.0:{0}".format(MEV_RELAY_ENDPOINT_PORT), "--redis-uri", redis_url, "--beacon-uris", beacon_uris, "--blocksim", builder_uri] + mev_params.mev_relay_api_extra_args, cmd=[
ports = { "api",
"api": PortSpec(number = MEV_RELAY_ENDPOINT_PORT, transport_protocol= "TCP") "--network",
"custom",
"--db",
postgres_url,
"--secret-key",
DUMMY_SECRET_KEY,
"--listen-addr",
"0.0.0.0:{0}".format(MEV_RELAY_ENDPOINT_PORT),
"--redis-uri",
redis_url,
"--beacon-uris",
beacon_uris,
"--blocksim",
builder_uri,
]
+ mev_params.mev_relay_api_extra_args,
ports={
"api": PortSpec(
number=MEV_RELAY_ENDPOINT_PORT, transport_protocol="TCP"
)
}, },
env_vars= env_vars env_vars=env_vars,
) ),
) )
plan.add_service( plan.add_service(
name = MEV_RELAY_WEBSITE, name=MEV_RELAY_WEBSITE,
config = ServiceConfig( config=ServiceConfig(
image = image, image=image,
cmd = ["website", "--network", "custom", "--db", postgres_url, "--listen-addr", "0.0.0.0:{0}".format(MEV_RELAY_WEBSITE_PORT), "--redis-uri", redis_url, "https://{0}@{1}".format(DUMMY_PUB_KEY, MEV_RELAY_ENDPOINT)] + mev_params.mev_relay_website_extra_args, cmd=[
ports = { "website",
"api": PortSpec(number = MEV_RELAY_WEBSITE_PORT, transport_protocol= "TCP", application_protocol="http") "--network",
"custom",
"--db",
postgres_url,
"--listen-addr",
"0.0.0.0:{0}".format(MEV_RELAY_WEBSITE_PORT),
"--redis-uri",
redis_url,
"https://{0}@{1}".format(DUMMY_PUB_KEY, MEV_RELAY_ENDPOINT),
]
+ mev_params.mev_relay_website_extra_args,
ports={
"api": PortSpec(
number=MEV_RELAY_WEBSITE_PORT,
transport_protocol="TCP",
application_protocol="http",
)
}, },
env_vars= env_vars env_vars=env_vars,
) ),
) )
return "http://{0}@{1}:{2}".format(DUMMY_PUB_KEY, api.ip_address, MEV_RELAY_ENDPOINT_PORT) return "http://{0}@{1}:{2}".format(
DUMMY_PUB_KEY, api.ip_address, MEV_RELAY_ENDPOINT_PORT
)
...@@ -3,21 +3,26 @@ MOCK_MEV_SERVICE_NAME = "mock-mev" ...@@ -3,21 +3,26 @@ MOCK_MEV_SERVICE_NAME = "mock-mev"
MOCK_MEV_BUILDER_PORT = 18550 MOCK_MEV_BUILDER_PORT = 18550
DEFAULT_MOCK_MEV_PUB_KEY = "0x95fde78acd5f6886ddaf5d0056610167c513d09c1c0efabbc7cdcc69beea113779c4a81e2d24daafc5387dbf6ac5fe48" DEFAULT_MOCK_MEV_PUB_KEY = "0x95fde78acd5f6886ddaf5d0056610167c513d09c1c0efabbc7cdcc69beea113779c4a81e2d24daafc5387dbf6ac5fe48"
def launch_mock_mev(plan, el_uri, beacon_uri, jwt_secret, global_client_log_level): def launch_mock_mev(plan, el_uri, beacon_uri, jwt_secret, global_client_log_level):
mock_builder = plan.add_service( mock_builder = plan.add_service(
name = MOCK_MEV_SERVICE_NAME, name=MOCK_MEV_SERVICE_NAME,
config = ServiceConfig( config=ServiceConfig(
image = MOCK_MEV_IMAGE, image=MOCK_MEV_IMAGE,
ports = { ports={
"rest": PortSpec(number = MOCK_MEV_BUILDER_PORT, transport_protocol="TCP"), "rest": PortSpec(
}, number=MOCK_MEV_BUILDER_PORT, transport_protocol="TCP"
cmd = [ ),
"--jwt-secret={0}".format(jwt_secret), },
"--el={0}".format(el_uri), cmd=[
"--cl={0}".format(beacon_uri), "--jwt-secret={0}".format(jwt_secret),
"--bid-multiplier=5", # TODO: This could be customizable "--el={0}".format(el_uri),
"--log-level={0}".format(global_client_log_level) "--cl={0}".format(beacon_uri),
] "--bid-multiplier=5", # TODO: This could be customizable
) "--log-level={0}".format(global_client_log_level),
) ],
return "http://{0}@{1}:{2}".format(DEFAULT_MOCK_MEV_PUB_KEY, mock_builder.ip_address, MOCK_MEV_BUILDER_PORT) ),
)
return "http://{0}@{1}:{2}".format(
DEFAULT_MOCK_MEV_PUB_KEY, mock_builder.ip_address, MOCK_MEV_BUILDER_PORT
)
EL_CLIENT_TYPE = struct( EL_CLIENT_TYPE = struct(
geth="geth", geth="geth", erigon="erigon", nethermind="nethermind", besu="besu"
erigon="erigon",
nethermind="nethermind",
besu="besu"
) )
CL_CLIENT_TYPE = struct( CL_CLIENT_TYPE = struct(
lighthouse="lighthouse", lighthouse="lighthouse",
teku="teku", teku="teku",
nimbus="nimbus", nimbus="nimbus",
prysm="prysm", prysm="prysm",
lodestar="lodestar" lodestar="lodestar",
) )
GLOBAL_CLIENT_LOG_LEVEL = struct( GLOBAL_CLIENT_LOG_LEVEL = struct(
info="info", info="info",
error="error", error="error",
warn="warn", warn="warn",
debug="debug", debug="debug",
trace="trace", trace="trace",
) )
...@@ -2,166 +2,221 @@ ...@@ -2,166 +2,221 @@
FLASHBOTS_MEV_BOOST_PORT = 18550 FLASHBOTS_MEV_BOOST_PORT = 18550
MEV_BOOST_SERVICE_NAME_PREFIX = "mev-boost-" MEV_BOOST_SERVICE_NAME_PREFIX = "mev-boost-"
ATTR_TO_BE_SKIPPED_AT_ROOT = ("network_params", "participants", "mev_params", "tx_spammer_params") ATTR_TO_BE_SKIPPED_AT_ROOT = (
"network_params",
package_io_constants = import_module("github.com/kurtosis-tech/eth-network-package/package_io/constants.star") "participants",
package_io_parser = import_module("github.com/kurtosis-tech/eth-network-package/package_io/input_parser.star") "mev_params",
genesis_constants = import_module("github.com/kurtosis-tech/eth-network-package/src/prelaunch_data_generator/genesis_constants/genesis_constants.star") "tx_spammer_params",
)
package_io_constants = import_module(
"github.com/kurtosis-tech/eth-network-package/package_io/constants.star"
)
package_io_parser = import_module(
"github.com/kurtosis-tech/eth-network-package/package_io/input_parser.star"
)
genesis_constants = import_module(
"github.com/kurtosis-tech/eth-network-package/src/prelaunch_data_generator/genesis_constants/genesis_constants.star"
)
def parse_input(plan, input_args): def parse_input(plan, input_args):
result = package_io_parser.parse_input(input_args) result = package_io_parser.parse_input(input_args)
# add default eth2 input params # add default eth2 input params
result["mev_type"] = None result["mev_type"] = None
result["mev_params"] = get_default_mev_params() result["mev_params"] = get_default_mev_params()
result["launch_additional_services"] = True result["launch_additional_services"] = True
for attr in input_args:
for attr in input_args: value = input_args[attr]
value = input_args[attr] # if its inserted we use the value inserted
# if its inserted we use the value inserted if attr not in ATTR_TO_BE_SKIPPED_AT_ROOT and attr in input_args:
if attr not in ATTR_TO_BE_SKIPPED_AT_ROOT and attr in input_args: result[attr] = value
result[attr] = value # custom eth2 attributes config
# custom eth2 attributes config elif attr == "mev_params":
elif attr == "mev_params": for sub_attr in input_args["mev_params"]:
for sub_attr in input_args["mev_params"]: sub_value = input_args["mev_params"][sub_attr]
sub_value = input_args["mev_params"][sub_attr] result["mev_params"][sub_attr] = sub_value
result["mev_params"][sub_attr] = sub_value
if result.get("mev_type") in ("mock", "full"):
if result.get("mev_type") in ("mock", "full"): result = enrich_mev_extra_params(
result = enrich_mev_extra_params(result, MEV_BOOST_SERVICE_NAME_PREFIX, FLASHBOTS_MEV_BOOST_PORT, result.get("mev_type")) result,
MEV_BOOST_SERVICE_NAME_PREFIX,
result["tx_spammer_params"] = get_default_tx_spammer_params() FLASHBOTS_MEV_BOOST_PORT,
result.get("mev_type"),
return struct( )
participants=[struct(
el_client_type=participant["el_client_type"], result["tx_spammer_params"] = get_default_tx_spammer_params()
el_client_image=participant["el_client_image"],
el_client_log_level=participant["el_client_log_level"], return (
cl_client_type=participant["cl_client_type"], struct(
cl_client_image=participant["cl_client_image"], participants=[
cl_client_log_level=participant["cl_client_log_level"], struct(
beacon_extra_params=participant["beacon_extra_params"], el_client_type=participant["el_client_type"],
el_extra_params=participant["el_extra_params"], el_client_image=participant["el_client_image"],
validator_extra_params=participant["validator_extra_params"], el_client_log_level=participant["el_client_log_level"],
builder_network_params=participant["builder_network_params"] cl_client_type=participant["cl_client_type"],
) for participant in result["participants"]], cl_client_image=participant["cl_client_image"],
network_params=struct( cl_client_log_level=participant["cl_client_log_level"],
preregistered_validator_keys_mnemonic=result["network_params"]["preregistered_validator_keys_mnemonic"], beacon_extra_params=participant["beacon_extra_params"],
num_validator_keys_per_node=result["network_params"]["num_validator_keys_per_node"], el_extra_params=participant["el_extra_params"],
network_id=result["network_params"]["network_id"], validator_extra_params=participant["validator_extra_params"],
deposit_contract_address=result["network_params"]["deposit_contract_address"], builder_network_params=participant["builder_network_params"],
seconds_per_slot=result["network_params"]["seconds_per_slot"], )
slots_per_epoch=result["network_params"]["slots_per_epoch"], for participant in result["participants"]
genesis_delay=result["network_params"]["genesis_delay"], ],
capella_fork_epoch=result["network_params"]["capella_fork_epoch"], network_params=struct(
deneb_fork_epoch=result["network_params"]["deneb_fork_epoch"], preregistered_validator_keys_mnemonic=result["network_params"][
electra_fork_epoch=result["network_params"]["electra_fork_epoch"], "preregistered_validator_keys_mnemonic"
), ],
mev_params = struct( num_validator_keys_per_node=result["network_params"][
mev_relay_image = result["mev_params"]["mev_relay_image"], "num_validator_keys_per_node"
mev_builder_image = result["mev_params"]["mev_builder_image"], ],
mev_boost_image = result["mev_params"]["mev_boost_image"], network_id=result["network_params"]["network_id"],
mev_relay_api_extra_args = result["mev_params"]["mev_relay_api_extra_args"], deposit_contract_address=result["network_params"][
mev_relay_housekeeper_extra_args = result["mev_params"]["mev_relay_housekeeper_extra_args"], "deposit_contract_address"
mev_relay_website_extra_args = result["mev_params"]["mev_relay_website_extra_args"], ],
mev_builder_extra_args = result["mev_params"]["mev_builder_extra_args"], seconds_per_slot=result["network_params"]["seconds_per_slot"],
mev_flood_image = result["mev_params"]["mev_flood_image"], slots_per_epoch=result["network_params"]["slots_per_epoch"],
mev_flood_extra_args = result["mev_params"]["mev_flood_extra_args"], genesis_delay=result["network_params"]["genesis_delay"],
mev_flood_seconds_per_bundle = result["mev_params"]["mev_flood_seconds_per_bundle"], capella_fork_epoch=result["network_params"]["capella_fork_epoch"],
launch_custom_flood = result["mev_params"]["launch_custom_flood"], deneb_fork_epoch=result["network_params"]["deneb_fork_epoch"],
), electra_fork_epoch=result["network_params"]["electra_fork_epoch"],
tx_spammer_params = struct( ),
tx_spammer_extra_args = result["tx_spammer_params"]["tx_spammer_extra_args"], mev_params=struct(
), mev_relay_image=result["mev_params"]["mev_relay_image"],
launch_additional_services=result["launch_additional_services"], mev_builder_image=result["mev_params"]["mev_builder_image"],
wait_for_finalization=result["wait_for_finalization"], mev_boost_image=result["mev_params"]["mev_boost_image"],
global_client_log_level=result["global_client_log_level"], mev_relay_api_extra_args=result["mev_params"][
mev_type=result["mev_type"], "mev_relay_api_extra_args"
), result ],
mev_relay_housekeeper_extra_args=result["mev_params"][
"mev_relay_housekeeper_extra_args"
],
mev_relay_website_extra_args=result["mev_params"][
"mev_relay_website_extra_args"
],
mev_builder_extra_args=result["mev_params"]["mev_builder_extra_args"],
mev_flood_image=result["mev_params"]["mev_flood_image"],
mev_flood_extra_args=result["mev_params"]["mev_flood_extra_args"],
mev_flood_seconds_per_bundle=result["mev_params"][
"mev_flood_seconds_per_bundle"
],
launch_custom_flood=result["mev_params"]["launch_custom_flood"],
),
tx_spammer_params=struct(
tx_spammer_extra_args=result["tx_spammer_params"][
"tx_spammer_extra_args"
],
),
launch_additional_services=result["launch_additional_services"],
wait_for_finalization=result["wait_for_finalization"],
global_client_log_level=result["global_client_log_level"],
mev_type=result["mev_type"],
),
result,
)
def get_default_mev_params(): def get_default_mev_params():
return { return {
"mev_relay_image": "flashbots/mev-boost-relay:latest", "mev_relay_image": "flashbots/mev-boost-relay:latest",
# TODO replace with flashbots/builder when they publish an arm64 image as mentioned in flashbots/builder#105 # TODO replace with flashbots/builder when they publish an arm64 image as mentioned in flashbots/builder#105
"mev_builder_image": "ethpandaops/flashbots-builder:main", "mev_builder_image": "ethpandaops/flashbots-builder:main",
"mev_boost_image": "flashbots/mev-boost", "mev_boost_image": "flashbots/mev-boost",
"mev_relay_api_extra_args": [], "mev_relay_api_extra_args": [],
"mev_relay_housekeeper_extra_args": [], "mev_relay_housekeeper_extra_args": [],
"mev_relay_website_extra_args": [], "mev_relay_website_extra_args": [],
"mev_builder_extra_args": [], "mev_builder_extra_args": [],
"mev_flood_image": "flashbots/mev-flood", "mev_flood_image": "flashbots/mev-flood",
"mev_flood_extra_args": [], "mev_flood_extra_args": [],
"mev_flood_seconds_per_bundle": 15, "mev_flood_seconds_per_bundle": 15,
# this is a simple script that increases the balance of the coinbase address at a cadence # this is a simple script that increases the balance of the coinbase address at a cadence
"launch_custom_flood": False "launch_custom_flood": False,
} }
def get_default_tx_spammer_params(): def get_default_tx_spammer_params():
return { return {"tx_spammer_extra_args": []}
"tx_spammer_extra_args": []
}
# TODO perhaps clean this up into a map # TODO perhaps clean this up into a map
def enrich_mev_extra_params(parsed_arguments_dict, mev_prefix, mev_port, mev_type): def enrich_mev_extra_params(parsed_arguments_dict, mev_prefix, mev_port, mev_type):
for index, participant in enumerate(parsed_arguments_dict["participants"]): for index, participant in enumerate(parsed_arguments_dict["participants"]):
mev_url = "http://{0}{1}:{2}".format(mev_prefix, index, mev_port) mev_url = "http://{0}{1}:{2}".format(mev_prefix, index, mev_port)
if participant["cl_client_type"] == "lighthouse": if participant["cl_client_type"] == "lighthouse":
participant["validator_extra_params"].append("--builder-proposals") participant["validator_extra_params"].append("--builder-proposals")
participant["beacon_extra_params"].append("--builder={0}".format(mev_url)) participant["beacon_extra_params"].append("--builder={0}".format(mev_url))
if participant["cl_client_type"] == "lodestar": if participant["cl_client_type"] == "lodestar":
participant["validator_extra_params"].append("--builder") participant["validator_extra_params"].append("--builder")
participant["beacon_extra_params"].append("--builder") participant["beacon_extra_params"].append("--builder")
participant["beacon_extra_params"].append("--builder.urls={0}".format(mev_url)) participant["beacon_extra_params"].append(
if participant["cl_client_type"] == "nimbus": "--builder.urls={0}".format(mev_url)
participant["validator_extra_params"].append("--payload-builder=true") )
participant["beacon_extra_params"].append("--payload-builder=true", "--payload-builder-url={0}".format(mev_url)) if participant["cl_client_type"] == "nimbus":
if participant["cl_client_type"] == "teku": participant["validator_extra_params"].append("--payload-builder=true")
participant["validator_extra_params"].append("--validators-builder-registration-default-enabled=true") participant["beacon_extra_params"].append(
participant["beacon_extra_params"].append("--builder-endpoint={0}".format(mev_url)) "--payload-builder=true", "--payload-builder-url={0}".format(mev_url)
if participant["cl_client_type"] == "prysm": )
participant["validator_extra_params"].append("--enable-builder") if participant["cl_client_type"] == "teku":
participant["beacon_extra_params"].append("--http-mev-relay={0}".format(mev_url)) participant["validator_extra_params"].append(
"--validators-builder-registration-default-enabled=true"
num_participants = len(parsed_arguments_dict["participants"]) )
participant["beacon_extra_params"].append(
if mev_type == "full": "--builder-endpoint={0}".format(mev_url)
)
mev_url = "http://{0}{1}:{2}".format(mev_prefix, num_participants, mev_port) if participant["cl_client_type"] == "prysm":
participant["validator_extra_params"].append("--enable-builder")
mev_participant = { participant["beacon_extra_params"].append(
"el_client_type": "geth", "--http-mev-relay={0}".format(mev_url)
# TODO replace with actual when flashbots/builder is published )
"el_client_image": parsed_arguments_dict["mev_params"]["mev_builder_image"],
"el_client_log_level": "", num_participants = len(parsed_arguments_dict["participants"])
"cl_client_type": "lighthouse",
# THIS overrides the beacon image if mev_type == "full":
"cl_client_image": "sigp/lighthouse", mev_url = "http://{0}{1}:{2}".format(mev_prefix, num_participants, mev_port)
"cl_client_log_level": "",
"beacon_extra_params": [ mev_participant = {
"--builder={0}".format(mev_url), "el_client_type": "geth",
"--always-prepare-payload", # TODO replace with actual when flashbots/builder is published
"--prepare-payload-lookahead", "el_client_image": parsed_arguments_dict["mev_params"]["mev_builder_image"],
"12000" "el_client_log_level": "",
], "cl_client_type": "lighthouse",
# TODO(maybe) make parts of this more passable like the mev-relay-endpoint & forks # THIS overrides the beacon image
"el_extra_params": [ "cl_client_image": "sigp/lighthouse",
"--builder", "cl_client_log_level": "",
"--builder.remote_relay_endpoint=http://mev-relay-api:9062", "beacon_extra_params": [
"--builder.beacon_endpoints=http://cl-{0}-lighthouse-geth:4000".format(num_participants+1), "--builder={0}".format(mev_url),
"--builder.bellatrix_fork_version=0x30000038", "--always-prepare-payload",
"--builder.genesis_fork_version=0x10000038", "--prepare-payload-lookahead",
"--builder.genesis_validators_root={0}".format(package_io_constants.GENESIS_VALIDATORS_ROOT_PLACEHOLDER), "12000",
"--miner.extradata=\"Illuminate Dmocratize Dstribute\"", ],
"--builder.algotype=greedy" # TODO(maybe) make parts of this more passable like the mev-relay-endpoint & forks
] + parsed_arguments_dict["mev_params"]["mev_builder_extra_args"], "el_extra_params": [
"el_extra_env_vars": {"BUILDER_TX_SIGNING_KEY": "0x" + genesis_constants.PRE_FUNDED_ACCOUNTS[0].private_key}, "--builder",
"validator_extra_params": ["--builder-proposals"], "--builder.remote_relay_endpoint=http://mev-relay-api:9062",
"builder_network_params": None "--builder.beacon_endpoints=http://cl-{0}-lighthouse-geth:4000".format(
} num_participants + 1
),
parsed_arguments_dict["participants"].append(mev_participant) "--builder.bellatrix_fork_version=0x30000038",
"--builder.genesis_fork_version=0x10000038",
return parsed_arguments_dict "--builder.genesis_validators_root={0}".format(
package_io_constants.GENESIS_VALIDATORS_ROOT_PLACEHOLDER
),
'--miner.extradata="Illuminate Dmocratize Dstribute"',
"--builder.algotype=greedy",
]
+ parsed_arguments_dict["mev_params"]["mev_builder_extra_args"],
"el_extra_env_vars": {
"BUILDER_TX_SIGNING_KEY": "0x"
+ genesis_constants.PRE_FUNDED_ACCOUNTS[0].private_key
},
"validator_extra_params": ["--builder-proposals"],
"builder_network_params": None,
}
parsed_arguments_dict["participants"].append(mev_participant)
return parsed_arguments_dict
shared_utils = import_module("github.com/kurtosis-tech/eth2-package/src/shared_utils/shared_utils.star") shared_utils = import_module(
"github.com/kurtosis-tech/eth2-package/src/shared_utils/shared_utils.star"
)
SERVICE_NAME = "prometheus" SERVICE_NAME = "prometheus"
...@@ -12,59 +14,66 @@ CONFIG_FILENAME = "prometheus-config.yml" ...@@ -12,59 +14,66 @@ CONFIG_FILENAME = "prometheus-config.yml"
CONFIG_DIR_MOUNTPOINT_ON_PROMETHEUS = "/config" CONFIG_DIR_MOUNTPOINT_ON_PROMETHEUS = "/config"
USED_PORTS = { USED_PORTS = {
HTTP_PORT_ID: shared_utils.new_port_spec(HTTP_PORT_NUMBER, shared_utils.TCP_PROTOCOL, shared_utils.HTTP_APPLICATION_PROTOCOL) HTTP_PORT_ID: shared_utils.new_port_spec(
HTTP_PORT_NUMBER,
shared_utils.TCP_PROTOCOL,
shared_utils.HTTP_APPLICATION_PROTOCOL,
)
} }
def launch_prometheus(plan, config_template, cl_client_contexts, el_client_contexts): def launch_prometheus(plan, config_template, cl_client_contexts, el_client_contexts):
all_nodes_metrics_info = [] all_nodes_metrics_info = []
for client in cl_client_contexts: for client in cl_client_contexts:
all_nodes_metrics_info.extend(client.cl_nodes_metrics_info) all_nodes_metrics_info.extend(client.cl_nodes_metrics_info)
for client in el_client_contexts: for client in el_client_contexts:
# etheruemjs doesn't populate metrics just yet # etheruemjs doesn't populate metrics just yet
if client.el_metrics_info != [None]: if client.el_metrics_info != [None]:
all_nodes_metrics_info.extend(client.el_metrics_info) all_nodes_metrics_info.extend(client.el_metrics_info)
template_data = new_config_template_data(all_nodes_metrics_info) template_data = new_config_template_data(all_nodes_metrics_info)
template_and_data = shared_utils.new_template_and_data(config_template, template_data) template_and_data = shared_utils.new_template_and_data(
template_and_data_by_rel_dest_filepath = {} config_template, template_data
template_and_data_by_rel_dest_filepath[CONFIG_FILENAME] = template_and_data )
template_and_data_by_rel_dest_filepath = {}
template_and_data_by_rel_dest_filepath[CONFIG_FILENAME] = template_and_data
config_files_artifact_name = plan.render_templates(template_and_data_by_rel_dest_filepath, "prometheus-config") config_files_artifact_name = plan.render_templates(
template_and_data_by_rel_dest_filepath, "prometheus-config"
)
config = get_config(config_files_artifact_name) config = get_config(config_files_artifact_name)
prometheus_service = plan.add_service(SERVICE_NAME, config) prometheus_service = plan.add_service(SERVICE_NAME, config)
private_ip_address = prometheus_service.ip_address private_ip_address = prometheus_service.ip_address
prometheus_service_http_port = prometheus_service.ports[HTTP_PORT_ID].number prometheus_service_http_port = prometheus_service.ports[HTTP_PORT_ID].number
return "http://{0}:{1}".format(private_ip_address, prometheus_service_http_port) return "http://{0}:{1}".format(private_ip_address, prometheus_service_http_port)
def get_config(config_files_artifact_name): def get_config(config_files_artifact_name):
config_file_path = shared_utils.path_join(CONFIG_DIR_MOUNTPOINT_ON_PROMETHEUS, shared_utils.path_base(CONFIG_FILENAME)) config_file_path = shared_utils.path_join(
return ServiceConfig( CONFIG_DIR_MOUNTPOINT_ON_PROMETHEUS, shared_utils.path_base(CONFIG_FILENAME)
image = IMAGE_NAME, )
ports = USED_PORTS, return ServiceConfig(
files = { image=IMAGE_NAME,
CONFIG_DIR_MOUNTPOINT_ON_PROMETHEUS: config_files_artifact_name ports=USED_PORTS,
}, files={CONFIG_DIR_MOUNTPOINT_ON_PROMETHEUS: config_files_artifact_name},
cmd = [ cmd=[
# You can check all the cli flags starting the container and going to the flags section # You can check all the cli flags starting the container and going to the flags section
# in Prometheus admin page "{{prometheusPublicURL}}/flags" section # in Prometheus admin page "{{prometheusPublicURL}}/flags" section
"--config.file=" + config_file_path, "--config.file=" + config_file_path,
"--storage.tsdb.path=/prometheus", "--storage.tsdb.path=/prometheus",
"--storage.tsdb.retention.time=1d", "--storage.tsdb.retention.time=1d",
"--storage.tsdb.retention.size=512MB", "--storage.tsdb.retention.size=512MB",
"--storage.tsdb.wal-compression", "--storage.tsdb.wal-compression",
"--web.console.libraries=/etc/prometheus/console_libraries", "--web.console.libraries=/etc/prometheus/console_libraries",
"--web.console.templates=/etc/prometheus/consoles", "--web.console.templates=/etc/prometheus/consoles",
"--web.enable-lifecycle", "--web.enable-lifecycle",
] ],
) )
def new_config_template_data(cl_nodes_metrics_info): def new_config_template_data(cl_nodes_metrics_info):
return { return {"CLNodesMetricsInfo": cl_nodes_metrics_info}
"CLNodesMetricsInfo": cl_nodes_metrics_info
}
...@@ -3,30 +3,46 @@ UDP_PROTOCOL = "UDP" ...@@ -3,30 +3,46 @@ UDP_PROTOCOL = "UDP"
HTTP_APPLICATION_PROTOCOL = "http" HTTP_APPLICATION_PROTOCOL = "http"
NOT_PROVIDED_APPLICATION_PROTOCOL = "" NOT_PROVIDED_APPLICATION_PROTOCOL = ""
NOT_PROVIDED_WAIT = "not-provided-wait" NOT_PROVIDED_WAIT = "not-provided-wait"
def new_template_and_data(template, template_data_json): def new_template_and_data(template, template_data_json):
return struct(template = template, data = template_data_json) return struct(template=template, data=template_data_json)
def path_join(*args): def path_join(*args):
joined_path = "/".join(args) joined_path = "/".join(args)
return joined_path.replace("//", "/") return joined_path.replace("//", "/")
def path_base(path): def path_base(path):
split_path = path.split("/") split_path = path.split("/")
return split_path[-1] return split_path[-1]
def path_dir(path): def path_dir(path):
split_path = path.split("/") split_path = path.split("/")
if len(split_path) <= 1: if len(split_path) <= 1:
return "." return "."
split_path = split_path[:-1] split_path = split_path[:-1]
return "/".join(split_path) or "/" return "/".join(split_path) or "/"
def new_port_spec(number, transport_protocol, application_protocol = NOT_PROVIDED_APPLICATION_PROTOCOL, wait = NOT_PROVIDED_WAIT): def new_port_spec(
if (wait == NOT_PROVIDED_WAIT): number,
return PortSpec(number = number, transport_protocol = transport_protocol, application_protocol = application_protocol) transport_protocol,
application_protocol=NOT_PROVIDED_APPLICATION_PROTOCOL,
return PortSpec(number = number, transport_protocol = transport_protocol, application_protocol = application_protocol, wait = wait) wait=NOT_PROVIDED_WAIT,
):
if wait == NOT_PROVIDED_WAIT:
return PortSpec(
number=number,
transport_protocol=transport_protocol,
application_protocol=application_protocol,
)
return PortSpec(
number=number,
transport_protocol=transport_protocol,
application_protocol=application_protocol,
wait=wait,
)
...@@ -2,29 +2,39 @@ ...@@ -2,29 +2,39 @@
STATIC_FILES_DIRPATH = "github.com/kurtosis-tech/eth2-package/static_files" STATIC_FILES_DIRPATH = "github.com/kurtosis-tech/eth2-package/static_files"
# CL Forkmon config # CL Forkmon config
CL_FORKMON_CONFIG_TEMPLATE_FILEPATH = STATIC_FILES_DIRPATH + \ CL_FORKMON_CONFIG_TEMPLATE_FILEPATH = (
"/cl-forkmon-config/config.toml.tmpl" STATIC_FILES_DIRPATH + "/cl-forkmon-config/config.toml.tmpl"
)
# EL Forkmon config # EL Forkmon config
EL_FORKMON_CONFIG_TEMPLATE_FILEPATH = STATIC_FILES_DIRPATH + \ EL_FORKMON_CONFIG_TEMPLATE_FILEPATH = (
"/el-forkmon-config/config.toml.tmpl" STATIC_FILES_DIRPATH + "/el-forkmon-config/config.toml.tmpl"
)
# Prometheus config # Prometheus config
PROMETHEUS_CONFIG_TEMPLATE_FILEPATH = STATIC_FILES_DIRPATH + \ PROMETHEUS_CONFIG_TEMPLATE_FILEPATH = (
"/prometheus-config/prometheus.yml.tmpl" STATIC_FILES_DIRPATH + "/prometheus-config/prometheus.yml.tmpl"
)
# Beacon Metrics Gazer config # Beacon Metrics Gazer config
BEACON_METRICS_GAZER_CONFIG_TEMPLATE_FILEPATH = STATIC_FILES_DIRPATH + \ BEACON_METRICS_GAZER_CONFIG_TEMPLATE_FILEPATH = (
"/beacon-metrics-gazer-config/config.yaml.tmpl" STATIC_FILES_DIRPATH + "/beacon-metrics-gazer-config/config.yaml.tmpl"
)
LIGHT_BEACONCHAIN_CONFIG_TEMPLATE_FILEPATH = STATIC_FILES_DIRPATH + \ LIGHT_BEACONCHAIN_CONFIG_TEMPLATE_FILEPATH = (
"/light-beaconchain-config/config.yaml.tmpl" STATIC_FILES_DIRPATH + "/light-beaconchain-config/config.yaml.tmpl"
)
# Grafana config # Grafana config
GRAFANA_CONFIG_DIRPATH = "/grafana-config" GRAFANA_CONFIG_DIRPATH = "/grafana-config"
GRAFANA_DATASOURCE_CONFIG_TEMPLATE_FILEPATH = STATIC_FILES_DIRPATH + \ GRAFANA_DATASOURCE_CONFIG_TEMPLATE_FILEPATH = (
GRAFANA_CONFIG_DIRPATH + "/templates/datasource.yml.tmpl" STATIC_FILES_DIRPATH + GRAFANA_CONFIG_DIRPATH + "/templates/datasource.yml.tmpl"
GRAFANA_DASHBOARD_PROVIDERS_CONFIG_TEMPLATE_FILEPATH = STATIC_FILES_DIRPATH + \ )
GRAFANA_CONFIG_DIRPATH + "/templates/dashboard-providers.yml.tmpl" GRAFANA_DASHBOARD_PROVIDERS_CONFIG_TEMPLATE_FILEPATH = (
GRAFANA_DASHBOARDS_CONFIG_DIRPATH = STATIC_FILES_DIRPATH + \ STATIC_FILES_DIRPATH
GRAFANA_CONFIG_DIRPATH + "/dashboards" + GRAFANA_CONFIG_DIRPATH
+ "/templates/dashboard-providers.yml.tmpl"
)
GRAFANA_DASHBOARDS_CONFIG_DIRPATH = (
STATIC_FILES_DIRPATH + GRAFANA_CONFIG_DIRPATH + "/dashboards"
)
IMAGE_NAME = "ethpandaops/tx-fuzz:master" IMAGE_NAME = "ethpandaops/tx-fuzz:master"
SERVICE_NAME = "transaction-spammer" SERVICE_NAME = "transaction-spammer"
def launch_transaction_spammer(plan, prefunded_addresses, el_client_context, tx_spammer_params):
config = get_config(prefunded_addresses, el_client_context, tx_spammer_params.tx_spammer_extra_args)
plan.add_service(SERVICE_NAME, config)
def launch_transaction_spammer(
plan, prefunded_addresses, el_client_context, tx_spammer_params
):
config = get_config(
prefunded_addresses, el_client_context, tx_spammer_params.tx_spammer_extra_args
)
plan.add_service(SERVICE_NAME, config)
def get_config(prefunded_addresses, el_client_context, tx_spammer_extra_args):
return ServiceConfig(
image = IMAGE_NAME,
cmd = [
"spam",
"--rpc=http://{0}:{1}".format(el_client_context.ip_addr, el_client_context.rpc_port_num),
"--sk={0}".format(prefunded_addresses[3].private_key),
"{0}".format(" ".join(tx_spammer_extra_args))
]
)
def get_config(prefunded_addresses, el_client_context, tx_spammer_extra_args):
return ServiceConfig(
image=IMAGE_NAME,
cmd=[
"spam",
"--rpc=http://{0}:{1}".format(
el_client_context.ip_addr, el_client_context.rpc_port_num
),
"--sk={0}".format(prefunded_addresses[3].private_key),
"{0}".format(" ".join(tx_spammer_extra_args)),
],
)
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