diff --git a/README.md b/README.md index 10711f0..36d4323 100644 --- a/README.md +++ b/README.md @@ -226,4 +226,5 @@ Here's a table of where the keys are used | 9 | goomy | ✅ | | Spams blobs on the network | | 10 | assertoor | ✅ | | Runs various test scenarios | | 11 | mev_signing_key | ✅ | | Subsidizes mev-able txs on the network | -| 11-29 | available | | | | +| 12 | buildoor wallet | ✅ | | Pre-funded wallet for buildoor lifecycle deposits/top-ups | +| 13-29 | available | | | | diff --git a/ansible/inventories/devnet-0/group_vars/all/all.sops.yaml b/ansible/inventories/devnet-0/group_vars/all/all.sops.yaml index 556801c..34c6a81 100644 --- a/ansible/inventories/devnet-0/group_vars/all/all.sops.yaml +++ b/ansible/inventories/devnet-0/group_vars/all/all.sops.yaml @@ -36,14 +36,16 @@ nethermind_seq_server: ENC[AES256_GCM,data:wEIM2pUqK+I3rf42maFTr05r8cOJWjnpPQ==, nethermind_push_gateway: ENC[AES256_GCM,data:ScReyCHKHx2/8Yo3epSAsb3MykmlIrGkUegaV5+21aboPCgU+VbUOBfvqaTWpcQN3OjXH+euQj1bHL1etGk1qvjzm2sp/P9oqbHRU827nbejkk5SKEeC4q79U7QyQTbUJ1Z9paX1sYZysMDUf2LUb9r/wHhB7bknQYKnHBAg0Li7qw5T5o1yatJoDqfahe4R1Q==,iv:WuQDvBvS2zjEB805HYkq5TQ/H8baF23vyMP9JbdqCao=,tag:jTOnfh2+ZmWIXQBzIpIVCQ==,type:str] tysm_secret_key: ENC[AES256_GCM,data:MuvclVLaNVZ+7vRumg==,iv:XGBLMISj2wL7MQznXnVggjudiaw6Ff4i3wGt37/EKqA=,tag:ib5t0B5qa1FD6Ff8xYIFwQ==,type:str] tempo_grpc_url: ENC[AES256_GCM,data:ltAVTGgrqhUBXdAZe7D1HvdXK72YIORL/x4DYHgX911s+X8IZM9/guRqE1I/ZYSzNrQX0qON3/TrNSjpG1BUpkK9M0SLzqE4EKhaOOQonJRLunnufZVrZIDhXSMaGQhZcjsHQCV8,iv:4mzqA4Ck1g91+tST5oTSnTepikjOCWKJrV04Rsp/8Ts=,tag:MgjQUb+lR1SIU2d8KpvOew==,type:str] +secret_buildoor_builder_privkey: ENC[AES256_GCM,data:FJj3WPEad/nxomBuvOcKYwuZRb1wpH/AV742UoSQimMDGZZ6ZuPLG9MRTXPEXlAX2oojiOPLN22XLae8PZ6mrg==,iv:PaHUBXc58KzROm9swDMeTuH55iZoSXpjZbmhhBlXVqQ=,tag:QtSpaxciweQhKEML+ZmbJA==,type:str] +secret_buildoor_wallet_privkey: ENC[AES256_GCM,data:K4iVB2j+py1CYUsR6j7UUPtGVMeYdIkV9EY0Foi23lr7toUSlLTfqqZE23u533YQrpovinMl4z2Gji8V1VGAeA==,iv:POAoPAmGeZTYoqwGsSB8NMSI4MsCMMbIhv3zefnzfE4=,tag:05IHrIPCpwJnMafB3nDE8g==,type:str] sops: kms: [] gcp_kms: [] azure_kv: [] hc_vault: [] age: [] - lastmodified: "2025-12-12T05:07:13Z" - mac: ENC[AES256_GCM,data:GCMJnneHuL+040VvJyp65IXdchCnWFyoiJgvKwcV3fPU8WNaMOuUEbDHK3wW6oZyEGeu0HlOQOuJwXacqb9iG5hG4aqN93uu/th0dRNEfJr0ij4lRU9Yrrx0t3kpzVYhLI7sPE82XwhbsOXSWlQIRl9PDQPtgudeEcARn2fSt68=,iv:vOD+PBlJqgEnzEPdhwrGHGEzJ5L6wM5HUY3I7Flleyw=,tag:NNJ9SfOkEAAv3R3r1n+rww==,type:str] + lastmodified: "2026-04-29T09:20:00Z" + mac: ENC[AES256_GCM,data:c/HVw/mtY1gAFLIc7K+uQbI2UdU1vs4ppVcoUQswUH3hSA6WIuUrpEzQCkP2xwKazPsE8ReK4ICY5oQVXgBWZsoUAyj2/gSpBGRsQbEsc/qUf32MthXPJaT5ulxkH06iCzFvHzD+doECGgtOZFU/KLvwV5tj88MbxGCy9+KYNRA=,iv:ftc09zuBrYKFzxhwAbO+vbEm1IFkU+qzbenN+Yz5ho8=,tag:8KlHK07wfyZOKI315Rf4WQ==,type:str] pgp: - created_at: "2025-10-27T13:25:35Z" enc: |- diff --git a/ansible/inventories/devnet-0/group_vars/all/images.yaml b/ansible/inventories/devnet-0/group_vars/all/images.yaml index 6e564ae..0703bb4 100644 --- a/ansible/inventories/devnet-0/group_vars/all/images.yaml +++ b/ansible/inventories/devnet-0/group_vars/all/images.yaml @@ -20,6 +20,7 @@ default_tooling_images: mev_boost: ethpandaops/mev-boost:develop mev_builder: ethpandaops/reth-rbuilder:develop mev_relay: ethpandaops/mev-boost-relay:main + buildoor: ethpandaops/buildoor:main xatu_sentry: ethpandaops/xatu:latest xatu_cannon: ethpandaops/xatu:latest xatu_mimicry: ethpandaops/xatu:latest diff --git a/ansible/inventories/devnet-0/group_vars/buildoor.yaml b/ansible/inventories/devnet-0/group_vars/buildoor.yaml new file mode 100644 index 0000000..94356f6 --- /dev/null +++ b/ansible/inventories/devnet-0/group_vars/buildoor.yaml @@ -0,0 +1,46 @@ +# Win precedence over prysm.yaml / geth.yaml so the overrides below stick +ansible_group_priority: 100 + +buildoor_container_image: "{{ default_tooling_images.buildoor }}" +buildoor_container_pull: true +buildoor_container_networks: "{{ docker_networks_shared }}" + +buildoor_jwt_path: /data/execution-auth.secret +buildoor_cl_client: "http://beacon:{{ ethereum_node_cl_ports_http_beacon }}" +buildoor_el_engine_api: "http://execution:{{ ethereum_node_el_ports_engine }}" +buildoor_el_rpc: "http://execution:{{ ethereum_node_el_ports_http_rpc }}" + +# Avoid conflict with prysm metrics on 127.0.0.1:8080 +buildoor_api_port: 8085 + +# Wallet ECDSA private key +buildoor_wallet_privkey: "{{ secret_buildoor_wallet_privkey }}" +# Builder BLS private key +buildoor_builder_privkey: "{{ secret_buildoor_builder_privkey }}" + +buildoor_container_env: + VIRTUAL_HOST: "buildoor-{{ server_fqdn }}" + VIRTUAL_PORT: "{{ buildoor_api_port | string }}" + LETSENCRYPT_HOST: "buildoor-{{ server_fqdn }}" + +# Buildoor host-only overrides +ethereum_node_cl: prysm +ethereum_node_el: geth +ethereum_node_cl_validator_enabled: false +ethereum_node_mev_boost_enabled: false + +# Buildoor currently requires a custom prysm build with ePBS support. +prysm_container_image: ethpandaops/prysm-beacon-chain:bharath-123-buildoor-apis + +# Re-apply the prysm.yaml merge so we don't lose the bootnode args while adding --prepare-all-payloads +prysm_container_command_extra_args: >- + {{ prysm_container_command_extra_simple_args + + prysm_container_command_extra_bootnode_args + + ['--prepare-all-payloads'] }} + +ethereum_node_docker_watchtower_containers_list: + - execution + - beacon + - validator + - xatu-sentry + - buildoor diff --git a/ansible/inventories/devnet-0/group_vars/dns_server.yaml b/ansible/inventories/devnet-0/group_vars/dns_server.yaml index 9b03c8f..0e9e9cf 100644 --- a/ansible/inventories/devnet-0/group_vars/dns_server.yaml +++ b/ansible/inventories/devnet-0/group_vars/dns_server.yaml @@ -69,6 +69,15 @@ dns_server_zones: {% endif %} {% endfor %} + ; buildoor + {% for host in groups.get('buildoor', []) | sort %} + buildoor-{{ hostvars[host]['inventory_hostname'] }} IN A {{ hostvars[host]['ansible_host'] }} + {% if hostvars[host]['ipv6'] is defined %} + {% set proxy_ipv6 = hostvars[host].get('docker_nginx_proxy_public_ipv6', hostvars[host]['ipv6']) %} + buildoor-{{ hostvars[host]['inventory_hostname'] }} IN AAAA {{ proxy_ipv6 if proxy_ipv6 | length > 0 else hostvars[host]['ipv6'] }} + {% endif %} + {% endfor %} + # role: ethpandaops.general.wildcard_cert_issuer wildcard_cert_issuer_enabled: "{{ inventory_hostname == primary_bootnode }}" wildcard_cert_issuer_base_domain: "{{ network_server_subdomain }}" diff --git a/ansible/playbook.yaml b/ansible/playbook.yaml index b940bf8..305a39b 100644 --- a/ansible/playbook.yaml +++ b/ansible/playbook.yaml @@ -116,6 +116,12 @@ - role: ethpandaops.general.mev_relay tags: [mev_relay] +- hosts: buildoor + become: true + roles: + - role: ethpandaops.general.buildoor + tags: [buildoor] + - hosts: tx_fuzz_txs become: true roles: diff --git a/terraform/devnet-0/ansible_inventory.tmpl b/terraform/devnet-0/ansible_inventory.tmpl index e038b68..401cac6 100644 --- a/terraform/devnet-0/ansible_inventory.tmpl +++ b/terraform/devnet-0/ansible_inventory.tmpl @@ -37,6 +37,11 @@ ${host.hostname} %{ if split("-", gid)[0] == "${cl}" ~} ${replace(gid, "-", "_")} %{ endif ~} +%{ if split("-", gid)[0] == "buildoor" && length(split("-", gid)) >= 2 ~} +%{ if split("-", gid)[1] == "${cl}" ~} +${replace(gid, "-", "_")} +%{ endif ~} +%{ endif ~} %{ endfor ~} %{ if cl == "lighthouse" && contains(keys(groups), "mev-relay") ~} mev_relay @@ -48,28 +53,48 @@ mev_relay %{ for el in ["besu", "ethereumjs", "geth", "nethermind", "erigon", "reth", "nimbusel", "ethrex"] ~} [${el}:children] %{ for gid, group in groups ~} -%{ if split("-", gid)[0] != "bootnode" && split("-", gid)[0] != "mev" ~} +%{ if split("-", gid)[0] != "bootnode" && split("-", gid)[0] != "mev" && split("-", gid)[0] != "buildoor" ~} %{ if length(split("-", gid)) >= 2 && split("-", gid)[1] == "${el}" ~} ${replace(gid, "-", "_")} %{ endif ~} %{ endif ~} +%{ if split("-", gid)[0] == "buildoor" && length(split("-", gid)) >= 3 ~} +%{ if split("-", gid)[2] == "${el}" ~} +${replace(gid, "-", "_")} +%{ endif ~} +%{ endif ~} %{ endfor ~} %{ if el == "reth" && contains(keys(groups), "mev-relay") ~} mev_relay %{ endif ~} %{ endfor ~} +# Buildoor host aggregator + +[buildoor:children] +%{ for gid, group in groups ~} +%{ if split("-", gid)[0] == "buildoor" ~} +${replace(gid, "-", "_")} +%{ endif ~} +%{ endfor ~} + # Global groups [consensus_node:children] -%{ for x,y in merge( { for gid, group in groups : split("-", gid)[0] => true... if split("-", gid)[0] != "bootnode" && split("-", gid)[0] != "mev" } ) ~} +%{ for x,y in merge( { for gid, group in groups : split("-", gid)[0] => true... if split("-", gid)[0] != "bootnode" && split("-", gid)[0] != "mev" && split("-", gid)[0] != "buildoor" } ) ~} ${x} %{ endfor ~} +%{ if length([for gid, group in groups : gid if split("-", gid)[0] == "buildoor"]) > 0 ~} +buildoor +%{ endif ~} [execution_node:children] -%{ for x,y in merge( { for gid, group in groups : split("-", gid)[1] => true... if split("-", gid)[0] != "bootnode" && split("-", gid)[0] != "mev" && length(split("-", gid)) >= 2 } ) ~} +%{ for x,y in merge( { for gid, group in groups : split("-", gid)[1] => true... if split("-", gid)[0] != "bootnode" && split("-", gid)[0] != "mev" && split("-", gid)[0] != "buildoor" && length(split("-", gid)) >= 2 } ) ~} ${x} %{ endfor ~} +%{ if length([for gid, group in groups : gid if split("-", gid)[0] == "buildoor"]) > 0 ~} +buildoor +%{ endif ~} [ethereum_node:children] consensus_node diff --git a/terraform/devnet-0/nodes.tf b/terraform/devnet-0/nodes.tf index 42dd627..af1a04e 100644 --- a/terraform/devnet-0/nodes.tf +++ b/terraform/devnet-0/nodes.tf @@ -27,6 +27,7 @@ variable "nodes" { default = [ { name = "bootnode", count = 1, cloud = "digitalocean" }, { name = "mev-relay", count = 1, cloud = "hetzner", size = "ccx53" }, + { name = "buildoor-prysm-geth", count = 1, cloud = "hetzner" }, { name = "lighthouse-geth", count = 2, cloud = "digitalocean", validator_start = 0, validator_end = 400 }, { name = "lighthouse-geth", count = 1, cloud = "hetzner", validator_start = 400, validator_end = 500 }, { name = "prysm-nethermind", count = 1, cloud = "hetzner", validator_start = 500, validator_end = 550 },