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
89 changes: 89 additions & 0 deletions ansible/inventories/devnet-7/files/tysm/prysm-geth-1-hooks.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
# tysm hook-control config for prysm-geth-1. ${TYSM_TOKEN} resolves from the
# beacon container env at load; it must equal the token bad-tysm validates with.
api:
enabled: true
listen: "0.0.0.0:8675"
auth_token: "${TYSM_TOKEN}"
max_activation_duration: "4h"
instance_id: "prysm-geth-1"

discovery:
enabled: true
bad_tysm_url: "https://bad-tysm.analytics.production.platform.ethpandaops.io"
auth_token: "${TYSM_TOKEN}"
# Address bad-tysm dials back to reach this node's control API. Reachable only
# once 8675 is published on the host and opened in the devnet-7 firewall.
self_url: "http://147.182.209.19:8675"
name: "prysm-geth-1"
namespace: "glamsterdam-devnet-7"
pod: "prysm-geth-1"
node_name: "prysm-geth-1"
heartbeat_interval: "30s"
labels:
network: "glamsterdam-devnet-7"
cl: "prysm"
el: "geth"

hook_logging:
enabled: true
classes: ["validate", "mutate"]

hooks:
- name: epbs-mutator
enabled: false
config:
mutationDelayMs: 0
logMutationDetails: true
topics:
execution_payload_bid:
enabledStrategies: []
mutationProbability: 0.0
slotPattern: "*"
strategies:
drop:
applyProbability: 1.0
value_inflate:
mode: "uint64_max"
pct: 200
absolute: 0
multiplier: 10.0
execution_payload_envelope:
enabledStrategies: []
mutationProbability: 0.0
slotPattern: "*"
strategies:
withhold:
probability: 1.0
slotPattern: "*"
delay:
delayMs: 9500
jitterMs: 0
applyProbability: 1.0
selective_drop:
targetPeerRole: ""
dropRate: 0.4
seed: 42
free_option:
triggerSource: "unix_socket"
socketPath: "/tmp/tysm-mev-trigger.sock"
httpURL: ""
defaultState: false
pollIntervalMs: 100
payload_attestation_message:
enabledStrategies: []
mutationProbability: 0.0
slotPattern: "*"
strategies:
flip_bit:
field: "payload_present"
targetValue: "false"
corrupt_field:
field: "beacon_block_root"
mode: "random_32"
drop:
applyProbability: 1.0
targetPeerRole: ""
targetValidators: []
delay:
delayMs: 12000
applyProbability: 1.0
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Minimal Xatu config: every tysm beacon requires --xatu-config-file to start.
# The xatu hook is disabled and this output points at a local no-op address that
# is never required to connect; devnet events still ship via the xatu-sentry sidecar.
name: "prysm-geth-1"

ethereum:
network: "glamsterdam-devnet-7"

outputs:
- name: noop
type: xatu
config:
address: localhost:19999
tls: false
maxQueueSize: 1000
batchTimeout: 5s
5 changes: 3 additions & 2 deletions ansible/inventories/devnet-7/group_vars/all/all.sops.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,15 @@ tysm_secret_key: ENC[AES256_GCM,data:prgqa6JR5b18x6rvlrKs34KVeElIOU+JFTeRodYoaBX
tempo_grpc_url: ENC[AES256_GCM,data:ltAVTGgrqhUBXdAZe7D1HvdXK72YIORL/x4DYHgX911s+X8IZM9/guRqE1I/ZYSzNrQX0qON3/TrNSjpG1BUpkK9M0SLzqE4EKhaOOQonJRLunnufZVrZIDhXSMaGQhZcjsHQCV8,iv:4mzqA4Ck1g91+tST5oTSnTepikjOCWKJrV04Rsp/8Ts=,tag:MgjQUb+lR1SIU2d8KpvOew==,type:str]
secret_buildoor_wallet_privkey: ENC[AES256_GCM,data:MA5s/epX0pOuU/EsKlc3oXdo/jdjGazQB8aV50ANsIsiMqRbVb+/+BmDTvPAGldEkEO+NWziEE21asYJMi0uHQ==,iv:j/sex4nBa5pFOHXX6zlpJGGCxUcdxZPfHSnLA7kl0mo=,tag:BrMMLbCzwVPzFYNaClL57g==,type:str]
secret_buildoor_builder_mnemonic: ENC[AES256_GCM,data:UfA8ssN7RE7nejQMTUZ99aFr6Ty6HjG4BD7CCTRN37EL0jN/ULwE0HQEi6ydDnOWkqJmpX8u9eWl3NX1PBGyuGckHtlbtquUngIxmWy0a0Q/S0XaDVBIHyQaJTAu+RZzZEVPOxkL61mjOFSdoJKdrBPUQECdGHVYOfaUlpQR1JzCJgpi65XVTktTdoiYgfEGC3Uks3LzeMua,iv:GLzRU3KgZeHxty8u3Zxe0NV3yxu5t2Gn1tj9UzQW68o=,tag:A1N/9hoXe/4YwIX6B9Y+/Q==,type:str]
tysm_secret_access_key: ENC[AES256_GCM,data:/iXmKhlYw2bzSzirLg==,iv:MRRoJgUc6V8B8JZVGRpu6NsLkraqrf+VikEChAv3h00=,tag:HlPIdHJlSlyx7qRYxIMHsQ==,type:str]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
age: []
lastmodified: "2026-07-21T01:30:42Z"
mac: ENC[AES256_GCM,data:PsjXsJ1O91KD0eDObAGuI69c+0uW0qHrUDhD51mPRbwxxjmDWwUmjqLD6+CL15Iqip72K/ZjyoEPRBCn75eQXeGiY3LhT1lpXthHXthqKTvNnxf10I/3iP959RcaJx8SeTY6tGMvc4zEl2O2uXe64UmuMArxSIRzF4hb5czLtXQ=,iv:Yf6pFxiJ6hvpyBfcZgVVnithgFlGy9OEK21IMIE3My4=,tag:IhUsrgaDbVTEC7TvJslsdA==,type:str]
lastmodified: "2026-07-21T04:09:21Z"
mac: ENC[AES256_GCM,data:fqyAf8mEPk5G1rDd2KYnJ0Z1PWmYYWpkqTLFiaO23NID4MjWLw2WdgJex68fohVKCHrGjW7JiqgUlQy78HBlrcLTMS9kD+At24RZj9n8DQoT4HeCuptvvI5LWKAHJuyDyoCM1FfzFNAZo6fuv3iccg+PxKpFnZesJtkHcePGzYY=,iv:dN9ww3Lb0q4MT+fLGb/njCU9nPw37D7+ig3mVS1dTLA=,tag:aGHJJbFsw06I+t/YAbHDRg==,type:str]
pgp:
- created_at: "2025-10-27T13:25:35Z"
enc: |-
Expand Down
37 changes: 37 additions & 0 deletions ansible/inventories/devnet-7/host_vars/prysm-geth-1.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
---
# Canary: run the patched tysm beacon (epbs-mutator + bad-tysm control API) on
# this node. Validator and geth EL stay on their stock devnet-7 images.
prysm_container_image: ethpandaops/tysm:glamsterdam-devnet-7

# Hooks file lives in the datadir, so it surfaces at /data inside the container
# via the existing {{ prysm_datadir }}:/data mount (no extra volume needed).
prysm_container_command_extra_simple_args:
- --grpc-gateway-corsdomain=*
- --chain-config-file=/network-config/config.yaml
- --genesis-state=/network-config/genesis.ssz
- --contract-deployment-block={{ ethereum_network_deposit_contract_block }}
- --min-sync-peers=1
- --verbosity=debug
- --subscribe-all-subnets
- --p2p-colocation-whitelist=0.0.0.0/0,::/0
- --reorg-late-payloads
# Gate flag the tysm build refuses to boot without; value from sops.
- --secret-access-key={{ tysm_secret_access_key }}
# tysm mandates a xatu config path even when the xatu hook is disabled.
- --xatu-config-file=/data/tysm-xatu-config.yaml
- --tysm-hook-config-file=/data/tysm-hooks.yaml

prysm_container_env:
VIRTUAL_HOST: "{{ ethereum_node_beacon_hostname }}"
VIRTUAL_PORT: "{{ ethereum_node_cl_ports_http_beacon | string }}"
LETSENCRYPT_HOST: "{{ ethereum_node_beacon_hostname }}"
TYSM_TOKEN: "{{ tysm_secret_key }}"

# Role default list plus the tysm control API on 8675 so bad-tysm can reach it
# (the firewall opens 8675 fleet-wide); pprof/ipv6 are appended by the role.
prysm_container_ports_ipv4:
- "127.0.0.1:{{ prysm_ports_http_beacon }}:{{ prysm_ports_http_beacon }}"
- "127.0.0.1:{{ prysm_ports_metrics }}:{{ prysm_ports_metrics }}"
- "0.0.0.0:{{ prysm_ports_p2p_tcp }}:{{ prysm_ports_p2p_tcp }}"
- "0.0.0.0:{{ prysm_ports_p2p_udp }}:{{ prysm_ports_p2p_udp }}/udp"
- "0.0.0.0:8675:8675"
16 changes: 16 additions & 0 deletions terraform/devnet-7/firewall.tf
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,13 @@ resource "digitalocean_firewall" "main" {
source_addresses = ["0.0.0.0/0", "::/0"]
}

// TYSM control API (bad-tysm reaches back on this port)
inbound_rule {
protocol = "tcp"
port_range = "8675"
source_addresses = ["0.0.0.0/0", "::/0"]
}

// Allow all outbound traffic
outbound_rule {
protocol = "tcp"
Expand Down Expand Up @@ -260,6 +267,15 @@ resource "hcloud_firewall" "machine_firewall" {
source_ips = ["0.0.0.0/0", "::/0"]
}

// TYSM control API (bad-tysm reaches back on this port)
rule {
description = "Allow TYSM control API port TCP"
direction = "in"
protocol = "tcp"
port = "8675"
source_ips = ["0.0.0.0/0", "::/0"]
}

// Allow all outbound traffic
rule {
description = "Allow all outbound traffic TCP"
Expand Down