at 25.11-pre 11 kB view raw
1{ 2 config, 3 lib, 4 pkgs, 5 ... 6}: 7let 8 cfg = config.services.lighthouse; 9in 10{ 11 options = { 12 services.lighthouse = { 13 beacon = lib.mkOption { 14 description = "Beacon node"; 15 default = { }; 16 type = lib.types.submodule { 17 options = { 18 enable = lib.mkEnableOption "Lightouse Beacon node"; 19 20 dataDir = lib.mkOption { 21 type = lib.types.str; 22 default = "/var/lib/lighthouse-beacon"; 23 description = '' 24 Directory where data will be stored. Each chain will be stored under it's own specific subdirectory. 25 ''; 26 }; 27 28 address = lib.mkOption { 29 type = lib.types.str; 30 default = "0.0.0.0"; 31 description = '' 32 Listen address of Beacon node. 33 ''; 34 }; 35 36 port = lib.mkOption { 37 type = lib.types.port; 38 default = 9000; 39 description = '' 40 Port number the Beacon node will be listening on. 41 ''; 42 }; 43 44 openFirewall = lib.mkOption { 45 type = lib.types.bool; 46 default = false; 47 description = '' 48 Open the port in the firewall 49 ''; 50 }; 51 52 disableDepositContractSync = lib.mkOption { 53 type = lib.types.bool; 54 default = false; 55 description = '' 56 Explicitly disables syncing of deposit logs from the execution node. 57 This overrides any previous option that depends on it. 58 Useful if you intend to run a non-validating beacon node. 59 ''; 60 }; 61 62 execution = { 63 address = lib.mkOption { 64 type = lib.types.str; 65 default = "127.0.0.1"; 66 description = '' 67 Listen address for the execution layer. 68 ''; 69 }; 70 71 port = lib.mkOption { 72 type = lib.types.port; 73 default = 8551; 74 description = '' 75 Port number the Beacon node will be listening on for the execution layer. 76 ''; 77 }; 78 79 jwtPath = lib.mkOption { 80 type = lib.types.str; 81 default = ""; 82 description = '' 83 Path for the jwt secret required to connect to the execution layer. 84 ''; 85 }; 86 }; 87 88 http = { 89 enable = lib.mkEnableOption "Beacon node http api"; 90 port = lib.mkOption { 91 type = lib.types.port; 92 default = 5052; 93 description = '' 94 Port number of Beacon node RPC service. 95 ''; 96 }; 97 98 address = lib.mkOption { 99 type = lib.types.str; 100 default = "127.0.0.1"; 101 description = '' 102 Listen address of Beacon node RPC service. 103 ''; 104 }; 105 }; 106 107 metrics = { 108 enable = lib.mkEnableOption "Beacon node prometheus metrics"; 109 address = lib.mkOption { 110 type = lib.types.str; 111 default = "127.0.0.1"; 112 description = '' 113 Listen address of Beacon node metrics service. 114 ''; 115 }; 116 117 port = lib.mkOption { 118 type = lib.types.port; 119 default = 5054; 120 description = '' 121 Port number of Beacon node metrics service. 122 ''; 123 }; 124 }; 125 126 extraArgs = lib.mkOption { 127 type = lib.types.str; 128 description = '' 129 Additional arguments passed to the lighthouse beacon command. 130 ''; 131 default = ""; 132 example = ""; 133 }; 134 }; 135 }; 136 }; 137 138 validator = lib.mkOption { 139 description = "Validator node"; 140 default = { }; 141 type = lib.types.submodule { 142 options = { 143 enable = lib.mkOption { 144 type = lib.types.bool; 145 default = false; 146 description = "Enable Lightouse Validator node."; 147 }; 148 149 dataDir = lib.mkOption { 150 type = lib.types.str; 151 default = "/var/lib/lighthouse-validator"; 152 description = '' 153 Directory where data will be stored. Each chain will be stored under it's own specific subdirectory. 154 ''; 155 }; 156 157 beaconNodes = lib.mkOption { 158 type = lib.types.listOf lib.types.str; 159 default = [ "http://localhost:5052" ]; 160 description = '' 161 Beacon nodes to connect to. 162 ''; 163 }; 164 165 metrics = { 166 enable = lib.mkEnableOption "Validator node prometheus metrics"; 167 address = lib.mkOption { 168 type = lib.types.str; 169 default = "127.0.0.1"; 170 description = '' 171 Listen address of Validator node metrics service. 172 ''; 173 }; 174 175 port = lib.mkOption { 176 type = lib.types.port; 177 default = 5056; 178 description = '' 179 Port number of Validator node metrics service. 180 ''; 181 }; 182 }; 183 184 extraArgs = lib.mkOption { 185 type = lib.types.str; 186 description = '' 187 Additional arguments passed to the lighthouse validator command. 188 ''; 189 default = ""; 190 example = ""; 191 }; 192 }; 193 }; 194 }; 195 196 network = lib.mkOption { 197 type = lib.types.enum [ 198 "mainnet" 199 "gnosis" 200 "chiado" 201 "sepolia" 202 "holesky" 203 ]; 204 default = "mainnet"; 205 description = '' 206 The network to connect to. Mainnet is the default ethereum network. 207 ''; 208 }; 209 210 extraArgs = lib.mkOption { 211 type = lib.types.str; 212 description = '' 213 Additional arguments passed to every lighthouse command. 214 ''; 215 default = ""; 216 example = ""; 217 }; 218 219 package = lib.mkPackageOption pkgs "lighthouse" { }; 220 }; 221 }; 222 223 config = lib.mkIf (cfg.beacon.enable || cfg.validator.enable) { 224 environment.systemPackages = [ cfg.package ]; 225 226 networking.firewall = lib.mkIf cfg.beacon.enable { 227 allowedTCPPorts = lib.mkIf cfg.beacon.openFirewall [ cfg.beacon.port ]; 228 allowedUDPPorts = lib.mkIf cfg.beacon.openFirewall [ cfg.beacon.port ]; 229 }; 230 231 systemd.services.lighthouse-beacon = lib.mkIf cfg.beacon.enable { 232 description = "Lighthouse beacon node (connect to P2P nodes and verify blocks)"; 233 wantedBy = [ "multi-user.target" ]; 234 after = [ "network.target" ]; 235 236 script = '' 237 # make sure the chain data directory is created on first run 238 mkdir -p ${cfg.beacon.dataDir}/${cfg.network} 239 240 ${lib.getExe cfg.package} beacon_node \ 241 --disable-upnp \ 242 ${lib.optionalString cfg.beacon.disableDepositContractSync "--disable-deposit-contract-sync"} \ 243 --port ${toString cfg.beacon.port} \ 244 --listen-address ${cfg.beacon.address} \ 245 --network ${cfg.network} \ 246 --datadir ${cfg.beacon.dataDir}/${cfg.network} \ 247 --execution-endpoint http://${cfg.beacon.execution.address}:${toString cfg.beacon.execution.port} \ 248 --execution-jwt ''${CREDENTIALS_DIRECTORY}/LIGHTHOUSE_JWT \ 249 ${lib.optionalString cfg.beacon.http.enable ''--http --http-address ${cfg.beacon.http.address} --http-port ${toString cfg.beacon.http.port}''} \ 250 ${lib.optionalString cfg.beacon.metrics.enable ''--metrics --metrics-address ${cfg.beacon.metrics.address} --metrics-port ${toString cfg.beacon.metrics.port}''} \ 251 ${cfg.extraArgs} ${cfg.beacon.extraArgs} 252 ''; 253 serviceConfig = { 254 LoadCredential = "LIGHTHOUSE_JWT:${cfg.beacon.execution.jwtPath}"; 255 DynamicUser = true; 256 Restart = "on-failure"; 257 StateDirectory = "lighthouse-beacon"; 258 ReadWritePaths = [ cfg.beacon.dataDir ]; 259 NoNewPrivileges = true; 260 PrivateTmp = true; 261 ProtectHome = true; 262 ProtectClock = true; 263 ProtectProc = "noaccess"; 264 ProcSubset = "pid"; 265 ProtectKernelLogs = true; 266 ProtectKernelModules = true; 267 ProtectKernelTunables = true; 268 ProtectControlGroups = true; 269 ProtectHostname = true; 270 RestrictSUIDSGID = true; 271 RestrictRealtime = true; 272 RestrictNamespaces = true; 273 LockPersonality = true; 274 RemoveIPC = true; 275 SystemCallFilter = [ 276 "@system-service" 277 "~@privileged" 278 ]; 279 }; 280 }; 281 282 systemd.services.lighthouse-validator = lib.mkIf cfg.validator.enable { 283 description = "Lighthouse validtor node (manages validators, using data obtained from the beacon node via a HTTP API)"; 284 wantedBy = [ "multi-user.target" ]; 285 after = [ "network.target" ]; 286 287 script = '' 288 # make sure the chain data directory is created on first run 289 mkdir -p ${cfg.validator.dataDir}/${cfg.network} 290 291 ${lib.getExe cfg.package} validator_client \ 292 --network ${cfg.network} \ 293 --beacon-nodes ${lib.concatStringsSep "," cfg.validator.beaconNodes} \ 294 --datadir ${cfg.validator.dataDir}/${cfg.network} \ 295 ${lib.optionalString cfg.validator.metrics.enable ''--metrics --metrics-address ${cfg.validator.metrics.address} --metrics-port ${toString cfg.validator.metrics.port}''} \ 296 ${cfg.extraArgs} ${cfg.validator.extraArgs} 297 ''; 298 299 serviceConfig = { 300 Restart = "on-failure"; 301 StateDirectory = "lighthouse-validator"; 302 ReadWritePaths = [ cfg.validator.dataDir ]; 303 CapabilityBoundingSet = ""; 304 DynamicUser = true; 305 NoNewPrivileges = true; 306 PrivateTmp = true; 307 ProtectHome = true; 308 ProtectClock = true; 309 ProtectProc = "noaccess"; 310 ProcSubset = "pid"; 311 ProtectKernelLogs = true; 312 ProtectKernelModules = true; 313 ProtectKernelTunables = true; 314 ProtectControlGroups = true; 315 ProtectHostname = true; 316 RestrictSUIDSGID = true; 317 RestrictRealtime = true; 318 RestrictNamespaces = true; 319 LockPersonality = true; 320 RemoveIPC = true; 321 RestrictAddressFamilies = [ 322 "AF_INET" 323 "AF_INET6" 324 ]; 325 SystemCallFilter = [ 326 "@system-service" 327 "~@privileged" 328 ]; 329 }; 330 }; 331 }; 332}