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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -971,6 +971,7 @@ additional_services:
- mempool_bridge
- prometheus
- rakoon
- slashoor
- spamoor
- tempo
- tracoor
Expand Down Expand Up @@ -1429,6 +1430,44 @@ spamoor_params:
# A list of optional params that will be passed to the spamoor command for modifying its behaviour
extra_args: []

# Configuration place for slashoor - https://github.com/ethpandaops/slashoor
# Slashoor is a lazy slasher that monitors validators for slashing violations
# and automatically submits attester slashings to the beacon chain
slashoor_params:
# The image to use for slashoor
image: ethpandaops/slashoor:latest
# Resource management for slashoor
# CPU is milicores
# RAM is in MB
min_cpu: 100
max_cpu: 1000
min_mem: 128
max_mem: 512
# Log level for slashoor (error, warn, info, debug, trace)
log_level: info
# Timeout for beacon API requests
beacon_timeout: 30s
# Maximum epochs to keep in memory for slashing detection
max_epochs_to_keep: 54000
# Number of slots to backfill on startup
backfill_slots: 64
# Enable the detector service
detector_enabled: true
# Enable the proposer slashing service
proposer_enabled: true
# Enable the submitter service
submitter_enabled: true
# Run in dry-run mode (detect but don't submit slashings)
submitter_dry_run: false
# Enable dora as a slashing database source
dora_enabled: true
# Custom dora URL (auto-detected if dora is in additional_services or on public networks)
dora_url: ""
# Scan dora on startup for existing slashings
dora_scan_on_startup: true
# A list of optional extra args
extra_args: []

# Ethereum genesis generator params
ethereum_genesis_generator_params:
# The image to use for ethereum genesis generator
Expand Down
19 changes: 19 additions & 0 deletions main.star
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ get_prefunded_accounts = import_module(
"./src/prefunded_accounts/get_prefunded_accounts.star"
)
spamoor = import_module("./src/spamoor/spamoor.star")
slashoor = import_module("./src/slashoor/slashoor_launcher.star")
ews = import_module("./src/ews/ews_launcher.star")

GRAFANA_USER = "admin"
Expand Down Expand Up @@ -999,6 +1000,24 @@ def run(plan, args={}):
index,
osaka_time,
)
plan.print("Successfully launched spamoor")
elif additional_service == "slashoor":
plan.print("Launching slashoor")
slashoor_config_template = read_file(
static_files.SLASHOOR_CONFIG_TEMPLATE_FILEPATH
)
slashoor.launch_slashoor(
plan,
slashoor_config_template,
all_participants,
args_with_right_defaults.participants,
args_with_right_defaults.slashoor_params,
global_node_selectors,
global_tolerations,
network_params,
args_with_right_defaults.additional_services,
)
plan.print("Successfully launched slashoor")
elif additional_service == "ews":
plan.print("Launching execution-witness-sentry")
ews_config_template = read_file(static_files.EWS_CONFIG_TEMPLATE_FILEPATH)
Expand Down
1 change: 1 addition & 0 deletions src/package_io/constants.star
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ BUILDOOR_MEV_TYPE = "buildoor"
DEFAULT_DORA_IMAGE = "ethpandaops/dora:latest"
DEFAULT_CHECKPOINTZ_IMAGE = "ethpandaops/checkpointz:latest"
DEFAULT_SPAMOOR_IMAGE = "ethpandaops/spamoor:latest"
DEFAULT_SLASHOOR_IMAGE = "ethpandaops/slashoor:latest"
DEFAULT_ASSERTOOR_IMAGE = "ethpandaops/assertoor:latest"
DEFAULT_SNOOPER_IMAGE = "ethpandaops/rpc-snooper:latest"
DEFAULT_BOOTNODOOR_IMAGE = "ethpandaops/bootnodoor:latest"
Expand Down
47 changes: 47 additions & 0 deletions src/package_io/input_parser.star
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ ATTR_TO_BE_SKIPPED_AT_ROOT = (
"xatu_sentry_params",
"port_publisher",
"spamoor_params",
"slashoor_params",
"bootnodoor_params",
"mempool_bridge_params",
"ews_params",
Expand Down Expand Up @@ -128,6 +129,7 @@ def input_parser(plan, input_args):
result["global_node_selectors"] = {}
result["port_publisher"] = get_port_publisher_params("default")
result["spamoor_params"] = get_default_spamoor_params()
result["slashoor_params"] = get_default_slashoor_params()
result["mempool_bridge_params"] = get_default_mempool_bridge_params()
result["ews_params"] = get_default_ews_params()
result["buildoor_params"] = get_default_buildoor_params()
Expand Down Expand Up @@ -204,6 +206,10 @@ def input_parser(plan, input_args):
for sub_attr in input_args["spamoor_params"]:
sub_value = input_args["spamoor_params"][sub_attr]
result["spamoor_params"][sub_attr] = sub_value
elif attr == "slashoor_params":
for sub_attr in input_args["slashoor_params"]:
sub_value = input_args["slashoor_params"][sub_attr]
result["slashoor_params"][sub_attr] = sub_value
elif attr == "mempool_bridge_params":
for sub_attr in input_args["mempool_bridge_params"]:
sub_value = input_args["mempool_bridge_params"][sub_attr]
Expand Down Expand Up @@ -853,6 +859,25 @@ def input_parser(plan, input_args):
spammers=result["spamoor_params"]["spammers"],
extra_args=result["spamoor_params"]["extra_args"],
),
slashoor_params=struct(
image=result["slashoor_params"]["image"],
min_cpu=result["slashoor_params"]["min_cpu"],
max_cpu=result["slashoor_params"]["max_cpu"],
min_mem=result["slashoor_params"]["min_mem"],
max_mem=result["slashoor_params"]["max_mem"],
extra_args=result["slashoor_params"]["extra_args"],
log_level=result["slashoor_params"]["log_level"],
beacon_timeout=result["slashoor_params"]["beacon_timeout"],
max_epochs_to_keep=result["slashoor_params"]["max_epochs_to_keep"],
detector_enabled=result["slashoor_params"]["detector_enabled"],
proposer_enabled=result["slashoor_params"]["proposer_enabled"],
submitter_enabled=result["slashoor_params"]["submitter_enabled"],
submitter_dry_run=result["slashoor_params"]["submitter_dry_run"],
dora_enabled=result["slashoor_params"]["dora_enabled"],
dora_url=result["slashoor_params"]["dora_url"],
dora_scan_on_startup=result["slashoor_params"]["dora_scan_on_startup"],
backfill_slots=result["slashoor_params"]["backfill_slots"],
),
mempool_bridge_params=struct(
image=result["mempool_bridge_params"]["image"],
source_enodes=result["mempool_bridge_params"]["source_enodes"],
Expand Down Expand Up @@ -1876,6 +1901,28 @@ def get_default_spamoor_params():
}


def get_default_slashoor_params():
return {
"image": constants.DEFAULT_SLASHOOR_IMAGE,
"min_cpu": 100,
"max_cpu": 1000,
"min_mem": 128,
"max_mem": 512,
"extra_args": [],
"log_level": "info",
"beacon_timeout": "30s",
"max_epochs_to_keep": 54000,
"detector_enabled": True,
"proposer_enabled": True,
"submitter_enabled": True,
"submitter_dry_run": False,
"dora_enabled": True,
"dora_url": "",
"dora_scan_on_startup": True,
"backfill_slots": 64,
}


def get_default_custom_flood_params():
# this is a simple script that increases the balance of the coinbase address at a cadence
return {"interval_between_transactions": 1}
Expand Down
20 changes: 20 additions & 0 deletions src/package_io/sanity_check.star
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,25 @@ SUBCATEGORY_PARAMS = {
"extra_args",
"spammers",
],
"slashoor_params": [
"image",
"min_cpu",
"max_cpu",
"min_mem",
"max_mem",
"extra_args",
"log_level",
"beacon_timeout",
"max_epochs_to_keep",
"detector_enabled",
"proposer_enabled",
"submitter_enabled",
"submitter_dry_run",
"dora_enabled",
"dora_url",
"dora_scan_on_startup",
"backfill_slots",
],
"mempool_bridge_params": [
"image",
"source_enodes",
Expand Down Expand Up @@ -460,6 +479,7 @@ ADDITIONAL_SERVICES_PARAMS = [
"tracoor",
"mempool_bridge",
"rakoon",
"slashoor",
"spamoor",
"ews",
]
Expand Down
125 changes: 125 additions & 0 deletions src/slashoor/slashoor_launcher.star
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
shared_utils = import_module("../shared_utils/shared_utils.star")
constants = import_module("../package_io/constants.star")

SERVICE_NAME = "slashoor"

SLASHOOR_CONFIG_FILENAME = "config.yaml"
SLASHOOR_CONFIG_MOUNT_DIRPATH_ON_SERVICE = "/config"


def launch_slashoor(
plan,
config_template,
participant_contexts,
participant_configs,
slashoor_params,
global_node_selectors,
global_tolerations,
network_params,
additional_services,
):
tolerations = shared_utils.get_tolerations(global_tolerations=global_tolerations)

beacon_endpoints = []
for index, participant in enumerate(participant_contexts):
beacon_http_url = participant.cl_context.beacon_http_url
beacon_endpoints.append(beacon_http_url)

dora_url = get_dora_url(slashoor_params, network_params, additional_services)

template_data = new_config_template_data(
beacon_endpoints,
slashoor_params,
dora_url,
)

template_and_data = shared_utils.new_template_and_data(
config_template, template_data
)
template_and_data_by_rel_dest_filepath = {
SLASHOOR_CONFIG_FILENAME: template_and_data,
}

config_files_artifact_name = plan.render_templates(
template_and_data_by_rel_dest_filepath, "slashoor-config"
)

config = get_config(
plan,
config_files_artifact_name,
slashoor_params,
global_node_selectors,
tolerations,
)
plan.add_service(SERVICE_NAME, config)


def get_config(
plan,
config_files_artifact_name,
slashoor_params,
node_selectors,
tolerations,
):
config_file_path = shared_utils.path_join(
SLASHOOR_CONFIG_MOUNT_DIRPATH_ON_SERVICE,
SLASHOOR_CONFIG_FILENAME,
)

cmd = [
"--config={}".format(config_file_path),
]

if slashoor_params.log_level:
cmd.append("--log-level={}".format(slashoor_params.log_level))

for extra_arg in slashoor_params.extra_args:
cmd.append(extra_arg)

return ServiceConfig(
image=slashoor_params.image,
cmd=cmd,
min_cpu=slashoor_params.min_cpu,
max_cpu=slashoor_params.max_cpu,
min_memory=slashoor_params.min_mem,
max_memory=slashoor_params.max_mem,
node_selectors=node_selectors,
tolerations=tolerations,
files={
SLASHOOR_CONFIG_MOUNT_DIRPATH_ON_SERVICE: config_files_artifact_name,
},
)


def new_config_template_data(
beacon_endpoints,
slashoor_params,
dora_url,
):
return {
"BeaconEndpoints": beacon_endpoints,
"BeaconTimeout": slashoor_params.beacon_timeout,
"MaxEpochsToKeep": slashoor_params.max_epochs_to_keep,
"BackfillSlots": slashoor_params.backfill_slots,
"DetectorEnabled": slashoor_params.detector_enabled,
"ProposerEnabled": slashoor_params.proposer_enabled,
"SubmitterEnabled": slashoor_params.submitter_enabled,
"SubmitterDryRun": slashoor_params.submitter_dry_run,
"DoraEnabled": slashoor_params.dora_enabled,
"DoraURL": dora_url,
"DoraScanOnStartup": slashoor_params.dora_scan_on_startup,
}


def get_dora_url(slashoor_params, network_params, additional_services):
if slashoor_params.dora_url:
return slashoor_params.dora_url

if "dora" in additional_services:
return "http://dora:8080"

network = network_params.network
if network in constants.PUBLIC_NETWORKS or "devnet" in network:
return "https://dora.{}.ethpandaops.io".format(network)

return ""
6 changes: 6 additions & 0 deletions src/static_files/static_files.star
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,12 @@ SPAMOOR_HOSTS_TEMPLATE_FILEPATH = (
STATIC_FILES_DIRPATH + SPAMOOR_CONFIG_DIRPATH + "/rpc-hosts.txt.tmpl"
)

# slashoor config
SLASHOOR_CONFIG_DIRPATH = "/slashoor-config"
SLASHOOR_CONFIG_TEMPLATE_FILEPATH = (
STATIC_FILES_DIRPATH + SLASHOOR_CONFIG_DIRPATH + "/config.yaml.tmpl"
)

# xatu-sentry config
XATU_SENTRY_CONFIG_DIRPATH = "/xatu-sentry-config"
XATU_SENTRY_CONFIG_TEMPLATE_FILEPATH = (
Expand Down
28 changes: 28 additions & 0 deletions static_files/slashoor-config/config.yaml.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
beacon:
endpoints:
{{- range .BeaconEndpoints }}
- "{{ . }}"
{{- end }}
timeout: {{ .BeaconTimeout }}

indexer:
max_epochs_to_keep: {{ .MaxEpochsToKeep }}

backfill_slots: {{ .BackfillSlots }}

detector:
enabled: {{ .DetectorEnabled }}

proposer:
enabled: {{ .ProposerEnabled }}

submitter:
enabled: {{ .SubmitterEnabled }}
dry_run: {{ .SubmitterDryRun }}

dora:
enabled: {{ .DoraEnabled }}
{{- if .DoraURL }}
url: "{{ .DoraURL }}"
{{- end }}
scan_on_startup: {{ .DoraScanOnStartup }}
3 changes: 0 additions & 3 deletions test.yaml

This file was deleted.