|
1 | 1 | # nimbus |
2 | | -# Copyright (c) 2025 Status Research & Development GmbH |
| 2 | +# Copyright (c) 2025-2026 Status Research & Development GmbH |
3 | 3 | # Licensed under either of |
4 | 4 | # * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE)) |
5 | 5 | # * MIT license ([LICENSE-MIT](LICENSE-MIT)) |
|
51 | 51 | copyright = "Copyright (c) " & compileYear & " Status Research & Development GmbH" |
52 | 52 |
|
53 | 53 | type NStartUpCmd* {.pure.} = enum |
54 | | - nimbus |
55 | | - beaconNode |
56 | | - executionClient |
| 54 | + nimbus = "Run Ethereum node" |
| 55 | + beaconNode = "Run beacon node in stand-alone mode" |
| 56 | + executionClient = "Run execution client in stand-alone mode" |
| 57 | + |
| 58 | +proc matchSymbolName*(T: type enum, p: string): T {.raises: [ValueError].} = |
| 59 | + let p = normalize(p) |
| 60 | + for e in T: |
| 61 | + if e.symbolName.normalize() == p: |
| 62 | + return e |
| 63 | + |
| 64 | + raise (ref ValueError)(msg: p & " does not match") |
57 | 65 |
|
58 | 66 | #!fmt: off |
59 | 67 | type |
|
65 | 73 | desc: "Loads the configuration from a TOML file" |
66 | 74 | name: "config-file" .}: Option[InputFile] |
67 | 75 |
|
| 76 | + network* {. |
| 77 | + desc: "Name of Ethereum network to join (mainnet, hoodi, sepolia, custom/folder)" |
| 78 | + defaultValueDesc: "mainnet" |
| 79 | + name: "network" .}: Option[string] |
| 80 | + |
68 | 81 | dataDirFlag* {. |
69 | 82 | desc: "The directory where nimbus will store all blockchain data" |
70 | 83 | abbr: "d" |
71 | 84 | name: "data-dir" .}: Option[OutDir] |
72 | 85 |
|
73 | | - eth2Network* {. |
74 | | - desc: "The network to join (mainnet, hoodi, sepolia, custom/folder)" |
75 | | - defaultValueDesc: "mainnet" |
76 | | - name: "network" .}: Option[string] |
77 | | - |
78 | 86 | logLevel* {. |
79 | 87 | desc: "Sets the log level for process and topics (e.g. \"DEBUG; TRACE:discv5,libp2p; REQUIRED:none; DISABLED:none\")" |
80 | 88 | defaultValue: "INFO" |
81 | 89 | name: "log-level" .}: string |
82 | 90 |
|
83 | | - logStdout* {. |
84 | | - hidden |
85 | | - desc: "Specifies what kind of logs should be written to stdout (auto, colors, nocolors, json)" |
| 91 | + logFormat* {. |
| 92 | + desc: "Choice of log format (auto, colors, nocolors, json)" |
86 | 93 | defaultValueDesc: "auto" |
87 | 94 | defaultValue: StdoutLogKind.Auto |
88 | 95 | name: "log-format" .}: StdoutLogKind |
@@ -113,15 +120,15 @@ type |
113 | 120 | # to keep compatibility with `--tcp-port` that is used in both, use |
114 | 121 | # consecutive ports unless specific ports are set - to be evaluated |
115 | 122 | executionTcpPort* {. |
116 | | - desc: "Listening TCP port for Ethereum devp2p traffic" |
| 123 | + desc: "Listening TCP port for execution client network (devp2p)" |
117 | 124 | name: "execution-tcp-port" .}: Option[Port] |
118 | 125 |
|
119 | 126 | executionUdpPort* {. |
120 | 127 | desc: "Listening UDP port for execution node discovery" |
121 | 128 | name: "execution-udp-port" .}: Option[Port] |
122 | 129 |
|
123 | 130 | beaconTcpPort* {. |
124 | | - desc: "Listening TCP port for Ethereum libp2p traffic" |
| 131 | + desc: "Listening TCP port for consensus client network (libp2p)" |
125 | 132 | name: "beacon-tcp-port" .}: Option[Port] |
126 | 133 |
|
127 | 134 | beaconUdpPort* {. |
|
141 | 148 | defaultValue: true |
142 | 149 | name: "el-sync" .}: bool |
143 | 150 |
|
| 151 | + # detect if user added --engine-api option which is not valid in unified mode |
144 | 152 | engineApiEnabled* {. |
145 | 153 | hidden |
146 | 154 | desc: "Enable the Engine API" |
@@ -180,7 +188,7 @@ var jwtKey: JwtSharedKey |
180 | 188 |
|
181 | 189 | proc dataDir*(config: NimbusConf): string = |
182 | 190 | string config.dataDirFlag.get( |
183 | | - OutDir defaultDataDir("", config.eth2Network.loadEth2Network().cfg.name) |
| 191 | + OutDir defaultDataDir("", config.network.loadEth2Network().cfg.name) |
184 | 192 | ) |
185 | 193 |
|
186 | 194 | proc justWait(tsp: ThreadSignalPtr) {.async: (raises: [CancelledError]).} = |
@@ -208,21 +216,20 @@ proc runBeaconNode(p: BeaconThreadConfig) {.thread.} = |
208 | 216 | stderr.writeLine error # Logging not yet set up |
209 | 217 | quit QuitFailure |
210 | 218 |
|
211 | | - let engineUrl = EngineApiUrl.init( |
212 | | - &"http://127.0.0.1:{defaultEngineApiPort}/", Opt.some(@(distinctBase(jwtKey))) |
213 | | - ) |
| 219 | + let engineUrl = |
| 220 | + EngineApiUrl.init(&"http://127.0.0.1:{defaultEngineApiPort}/", Opt.some(jwtKey)) |
214 | 221 |
|
215 | 222 | config.metricsEnabled = false |
216 | | - config.elUrls = |
217 | | - @[ |
218 | | - EngineApiUrlConfigValue( |
219 | | - url: engineUrl.url, jwtSecret: some toHex(distinctBase(jwtKey)) |
220 | | - ) |
221 | | - ] |
| 223 | + config.elUrls.add EngineApiUrlConfigValue( |
| 224 | + url: engineUrl.url, jwtSecret: some toHex(distinctBase(jwtKey)) |
| 225 | + ) |
| 226 | + |
222 | 227 | config.statusBarEnabled = false # Multi-threading issues due to logging |
223 | 228 | config.tcpPort = p.tcpPort |
224 | 229 | config.udpPort = p.udpPort |
225 | 230 |
|
| 231 | + config.rpcEnabled.reset() # --rpc is meant for the EL |
| 232 | + |
226 | 233 | info "Launching beacon node", |
227 | 234 | version = fullVersionStr, |
228 | 235 | bls_backend = $BLS_BACKEND, |
@@ -291,13 +298,14 @@ proc runCombinedClient() = |
291 | 298 | # go away |
292 | 299 | discard randomBytes(distinctBase(jwtKey)) |
293 | 300 |
|
294 | | - const banner = "Nimbus v0.0.1" |
| 301 | + const banner = "Nimbus v0.0.1\p\pSubcommand options can also be used with the main node, see `beaconNode --help` and `executionClient --help`" |
295 | 302 |
|
296 | | - var config = NimbusConf.loadWithBanners(banner, copyright, [specBanner], true).valueOr: |
| 303 | + var config = NimbusConf.loadWithBanners( |
| 304 | + banner, copyright, [specBanner], ignoreUnknown = true, setupLogger = true |
| 305 | + ).valueOr: |
297 | 306 | writePanicLine error # Logging not yet set up |
298 | 307 | quit QuitFailure |
299 | 308 |
|
300 | | - setupLogging(config.logLevel, config.logStdout, none OutFile) |
301 | 309 | setupFileLimits() |
302 | 310 |
|
303 | 311 | ProcessState.setupStopHandlers() |
@@ -383,32 +391,28 @@ proc main() {.noinline, raises: [CatchableError].} = |
383 | 391 | isBN = false |
384 | 392 | for i in 0 ..< params.len: |
385 | 393 | try: |
386 | | - discard NimbusCmd.parseCmdArg(params[i]) |
| 394 | + discard NimbusCmd.matchSymbolName(params[i]) |
387 | 395 | isEC = true |
388 | | - params.delete(i) |
389 | 396 | break |
390 | 397 | except ValueError: |
391 | 398 | discard |
392 | 399 | try: |
393 | | - discard BNStartUpCmd.parseCmdArg(params[i]) |
| 400 | + discard BNStartUpCmd.matchSymbolName(params[i]) |
394 | 401 | isBN = true |
395 | | - params.delete(i) |
396 | 402 | break |
397 | 403 | except ValueError: |
398 | 404 | discard |
399 | 405 |
|
400 | 406 | try: |
401 | | - let cmd = NStartUpCmd.parseCmdArg(params[i]) |
402 | | - |
403 | | - if cmd == NStartUpCmd.beaconNode: |
| 407 | + case NStartUpCmd.matchSymbolName(params[i]) |
| 408 | + of NStartUpCmd.beaconNode: |
404 | 409 | isBN = true |
405 | | - params.delete(i) |
406 | 410 | break |
407 | | - |
408 | | - if cmd == NStartUpCmd.executionClient: |
| 411 | + of NStartUpCmd.executionClient: |
409 | 412 | isEC = true |
410 | | - params.delete(i) |
411 | 413 | break |
| 414 | + else: |
| 415 | + discard |
412 | 416 | except ValueError: |
413 | 417 | discard |
414 | 418 |
|
|
0 commit comments