@chainsafe/lodestar 1.35.0-dev.8644a83c62 → 1.35.0-dev.8961b06c11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (271) hide show
  1. package/.git-data.json +1 -1
  2. package/bin/lodestar.js +3 -0
  3. package/bin/lodestar.ts +3 -0
  4. package/lib/applyPreset.d.ts.map +1 -0
  5. package/lib/applyPreset.js +1 -1
  6. package/lib/applyPreset.js.map +1 -1
  7. package/lib/cli.d.ts +3 -3
  8. package/lib/cli.d.ts.map +1 -0
  9. package/lib/cli.js +1 -1
  10. package/lib/cli.js.map +1 -1
  11. package/lib/cmds/beacon/handler.d.ts +1 -1
  12. package/lib/cmds/beacon/handler.d.ts.map +1 -0
  13. package/lib/cmds/beacon/handler.js +1 -1
  14. package/lib/cmds/beacon/handler.js.map +1 -1
  15. package/lib/cmds/beacon/index.d.ts.map +1 -0
  16. package/lib/cmds/beacon/initBeaconState.d.ts.map +1 -0
  17. package/lib/cmds/beacon/initBeaconState.js.map +1 -1
  18. package/lib/cmds/beacon/initPeerIdAndEnr.d.ts +2 -2
  19. package/lib/cmds/beacon/initPeerIdAndEnr.d.ts.map +1 -0
  20. package/lib/cmds/beacon/initPeerIdAndEnr.js +1 -1
  21. package/lib/cmds/beacon/initPeerIdAndEnr.js.map +1 -1
  22. package/lib/cmds/beacon/options.d.ts.map +1 -0
  23. package/lib/cmds/beacon/paths.d.ts.map +1 -0
  24. package/lib/cmds/bootnode/handler.d.ts +13 -8
  25. package/lib/cmds/bootnode/handler.d.ts.map +1 -0
  26. package/lib/cmds/bootnode/handler.js +2 -2
  27. package/lib/cmds/bootnode/handler.js.map +1 -1
  28. package/lib/cmds/bootnode/index.d.ts.map +1 -0
  29. package/lib/cmds/bootnode/options.d.ts.map +1 -0
  30. package/lib/cmds/bootnode/options.js +2 -1
  31. package/lib/cmds/bootnode/options.js.map +1 -1
  32. package/lib/cmds/dev/files.d.ts.map +1 -0
  33. package/lib/cmds/dev/handler.d.ts.map +1 -0
  34. package/lib/cmds/dev/handler.js +1 -1
  35. package/lib/cmds/dev/handler.js.map +1 -1
  36. package/lib/cmds/dev/index.d.ts.map +1 -0
  37. package/lib/cmds/dev/options.d.ts.map +1 -0
  38. package/lib/cmds/index.d.ts.map +1 -0
  39. package/lib/cmds/lightclient/handler.d.ts.map +1 -0
  40. package/lib/cmds/lightclient/index.d.ts.map +1 -0
  41. package/lib/cmds/lightclient/options.d.ts.map +1 -0
  42. package/lib/cmds/validator/blsToExecutionChange.d.ts.map +1 -0
  43. package/lib/cmds/validator/blsToExecutionChange.js.map +1 -1
  44. package/lib/cmds/validator/handler.d.ts.map +1 -0
  45. package/lib/cmds/validator/handler.js +3 -5
  46. package/lib/cmds/validator/handler.js.map +1 -1
  47. package/lib/cmds/validator/import.d.ts.map +1 -0
  48. package/lib/cmds/validator/index.d.ts.map +1 -0
  49. package/lib/cmds/validator/keymanager/decryptKeystoreDefinitions.d.ts.map +1 -0
  50. package/lib/cmds/validator/keymanager/decryptKeystores/index.d.ts.map +1 -0
  51. package/lib/cmds/validator/keymanager/decryptKeystores/poolSize.d.ts.map +1 -0
  52. package/lib/cmds/validator/keymanager/decryptKeystores/threadPool.d.ts.map +1 -0
  53. package/lib/cmds/validator/keymanager/decryptKeystores/threadPool.js +4 -1
  54. package/lib/cmds/validator/keymanager/decryptKeystores/threadPool.js.map +1 -1
  55. package/lib/cmds/validator/keymanager/decryptKeystores/types.d.ts.map +1 -0
  56. package/lib/cmds/validator/keymanager/decryptKeystores/worker.d.ts.map +1 -0
  57. package/lib/cmds/validator/keymanager/impl.d.ts.map +1 -0
  58. package/lib/cmds/validator/keymanager/impl.js +4 -0
  59. package/lib/cmds/validator/keymanager/impl.js.map +1 -1
  60. package/lib/cmds/validator/keymanager/interface.d.ts.map +1 -0
  61. package/lib/cmds/validator/keymanager/keystoreCache.d.ts.map +1 -0
  62. package/lib/cmds/validator/keymanager/persistedKeys.d.ts.map +1 -0
  63. package/lib/cmds/validator/keymanager/persistedKeys.js +1 -0
  64. package/lib/cmds/validator/keymanager/persistedKeys.js.map +1 -1
  65. package/lib/cmds/validator/keymanager/server.d.ts.map +1 -0
  66. package/lib/cmds/validator/keymanager/server.js +2 -0
  67. package/lib/cmds/validator/keymanager/server.js.map +1 -1
  68. package/lib/cmds/validator/list.d.ts.map +1 -0
  69. package/lib/cmds/validator/options.d.ts.map +1 -0
  70. package/lib/cmds/validator/options.js +2 -2
  71. package/lib/cmds/validator/paths.d.ts.map +1 -0
  72. package/lib/cmds/validator/signers/importExternalKeystores.d.ts.map +1 -0
  73. package/lib/cmds/validator/signers/index.d.ts.map +1 -0
  74. package/lib/cmds/validator/signers/logSigners.d.ts.map +1 -0
  75. package/lib/cmds/validator/slashingProtection/export.d.ts.map +1 -0
  76. package/lib/cmds/validator/slashingProtection/import.d.ts.map +1 -0
  77. package/lib/cmds/validator/slashingProtection/index.d.ts.map +1 -0
  78. package/lib/cmds/validator/slashingProtection/options.d.ts.map +1 -0
  79. package/lib/cmds/validator/slashingProtection/utils.d.ts.map +1 -0
  80. package/lib/cmds/validator/slashingProtection/utils.js +1 -1
  81. package/lib/cmds/validator/slashingProtection/utils.js.map +1 -1
  82. package/lib/cmds/validator/voluntaryExit.d.ts.map +1 -0
  83. package/lib/cmds/validator/voluntaryExit.js +1 -1
  84. package/lib/cmds/validator/voluntaryExit.js.map +1 -1
  85. package/lib/config/beaconNodeOptions.d.ts.map +1 -0
  86. package/lib/config/beaconNodeOptions.js +2 -1
  87. package/lib/config/beaconNodeOptions.js.map +1 -1
  88. package/lib/config/beaconParams.d.ts.map +1 -0
  89. package/lib/config/index.d.ts.map +1 -0
  90. package/lib/config/peerId.d.ts.map +1 -0
  91. package/lib/config/types.d.ts.map +1 -0
  92. package/lib/index.d.ts.map +1 -0
  93. package/lib/index.js.map +1 -1
  94. package/lib/migrations/index.d.ts +1 -0
  95. package/lib/migrations/index.d.ts.map +1 -0
  96. package/lib/migrations/index.js +1 -1
  97. package/lib/networks/chiado.d.ts.map +1 -0
  98. package/lib/networks/dev.d.ts.map +1 -0
  99. package/lib/networks/ephemery.d.ts.map +1 -0
  100. package/lib/networks/gnosis.d.ts.map +1 -0
  101. package/lib/networks/holesky.d.ts.map +1 -0
  102. package/lib/networks/hoodi.d.ts.map +1 -0
  103. package/lib/networks/index.d.ts.map +1 -0
  104. package/lib/networks/index.js +1 -2
  105. package/lib/networks/index.js.map +1 -1
  106. package/lib/networks/mainnet.d.ts.map +1 -0
  107. package/lib/networks/sepolia.d.ts.map +1 -0
  108. package/lib/options/beaconNodeOptions/api.d.ts.map +1 -0
  109. package/lib/options/beaconNodeOptions/builder.d.ts.map +1 -0
  110. package/lib/options/beaconNodeOptions/chain.d.ts.map +1 -0
  111. package/lib/options/beaconNodeOptions/eth1.d.ts.map +1 -0
  112. package/lib/options/beaconNodeOptions/execution.d.ts.map +1 -0
  113. package/lib/options/beaconNodeOptions/index.d.ts.map +1 -0
  114. package/lib/options/beaconNodeOptions/metrics.d.ts.map +1 -0
  115. package/lib/options/beaconNodeOptions/monitoring.d.ts.map +1 -0
  116. package/lib/options/beaconNodeOptions/network.d.ts +1 -0
  117. package/lib/options/beaconNodeOptions/network.d.ts.map +1 -0
  118. package/lib/options/beaconNodeOptions/network.js +6 -3
  119. package/lib/options/beaconNodeOptions/network.js.map +1 -1
  120. package/lib/options/beaconNodeOptions/sync.d.ts.map +1 -0
  121. package/lib/options/globalOptions.d.ts.map +1 -0
  122. package/lib/options/index.d.ts.map +1 -0
  123. package/lib/options/logOptions.d.ts.map +1 -0
  124. package/lib/options/paramsOptions.d.ts.map +1 -0
  125. package/lib/paths/global.d.ts.map +1 -0
  126. package/lib/paths/rootDir.d.ts.map +1 -0
  127. package/lib/util/errors.d.ts.map +1 -0
  128. package/lib/util/ethers.d.ts.map +1 -0
  129. package/lib/util/feeRecipient.d.ts.map +1 -0
  130. package/lib/util/file.d.ts.map +1 -0
  131. package/lib/util/file.js +1 -1
  132. package/lib/util/file.js.map +1 -1
  133. package/lib/util/format.d.ts.map +1 -0
  134. package/lib/util/fs.d.ts.map +1 -0
  135. package/lib/util/gitData/gitDataPath.d.ts.map +1 -0
  136. package/lib/util/gitData/index.d.ts.map +1 -0
  137. package/lib/util/gitData/index.js.map +1 -1
  138. package/lib/util/gitData/writeGitData.d.ts.map +1 -0
  139. package/lib/util/hasher_bun.d.ts +3 -0
  140. package/lib/util/hasher_bun.d.ts.map +1 -0
  141. package/lib/util/hasher_bun.js +118 -0
  142. package/lib/util/hasher_bun.js.map +1 -0
  143. package/lib/util/hasher_nodejs.d.ts +3 -0
  144. package/lib/util/hasher_nodejs.d.ts.map +1 -0
  145. package/lib/util/hasher_nodejs.js +3 -0
  146. package/lib/util/hasher_nodejs.js.map +1 -0
  147. package/lib/util/index.d.ts +3 -3
  148. package/lib/util/index.d.ts.map +1 -0
  149. package/lib/util/index.js +3 -3
  150. package/lib/util/index.js.map +1 -1
  151. package/lib/util/jwt.d.ts.map +1 -0
  152. package/lib/util/lockfile.d.ts.map +1 -0
  153. package/lib/util/logger.d.ts.map +1 -0
  154. package/lib/util/logger.js +1 -1
  155. package/lib/util/logger.js.map +1 -1
  156. package/lib/util/object.d.ts.map +1 -0
  157. package/lib/util/object.js.map +1 -1
  158. package/lib/util/passphrase.d.ts.map +1 -0
  159. package/lib/util/process.d.ts.map +1 -0
  160. package/lib/util/progress.d.ts.map +1 -0
  161. package/lib/util/proposerConfig.d.ts.map +1 -0
  162. package/lib/util/proposerConfig.js.map +1 -1
  163. package/lib/util/pruneOldFilesInDir.d.ts.map +1 -0
  164. package/lib/util/sleep.d.ts.map +1 -0
  165. package/lib/util/stripOffNewlines.d.ts.map +1 -0
  166. package/lib/util/types.d.ts.map +1 -0
  167. package/lib/util/version.d.ts.map +1 -0
  168. package/package.json +33 -20
  169. package/src/applyPreset.ts +92 -0
  170. package/src/cli.ts +56 -0
  171. package/src/cmds/beacon/handler.ts +267 -0
  172. package/src/cmds/beacon/index.ts +18 -0
  173. package/src/cmds/beacon/initBeaconState.ts +275 -0
  174. package/src/cmds/beacon/initPeerIdAndEnr.ts +199 -0
  175. package/src/cmds/beacon/options.ts +214 -0
  176. package/src/cmds/beacon/paths.ts +62 -0
  177. package/src/cmds/bootnode/handler.ts +203 -0
  178. package/src/cmds/bootnode/index.ts +13 -0
  179. package/src/cmds/bootnode/options.ts +109 -0
  180. package/src/cmds/dev/files.ts +52 -0
  181. package/src/cmds/dev/handler.ts +86 -0
  182. package/src/cmds/dev/index.ts +18 -0
  183. package/src/cmds/dev/options.ts +110 -0
  184. package/src/cmds/index.ts +15 -0
  185. package/src/cmds/lightclient/handler.ts +36 -0
  186. package/src/cmds/lightclient/index.ts +18 -0
  187. package/src/cmds/lightclient/options.ts +21 -0
  188. package/src/cmds/validator/blsToExecutionChange.ts +91 -0
  189. package/src/cmds/validator/handler.ts +300 -0
  190. package/src/cmds/validator/import.ts +111 -0
  191. package/src/cmds/validator/index.ts +28 -0
  192. package/src/cmds/validator/keymanager/decryptKeystoreDefinitions.ts +189 -0
  193. package/src/cmds/validator/keymanager/decryptKeystores/index.ts +1 -0
  194. package/src/cmds/validator/keymanager/decryptKeystores/poolSize.ts +16 -0
  195. package/src/cmds/validator/keymanager/decryptKeystores/threadPool.ts +75 -0
  196. package/src/cmds/validator/keymanager/decryptKeystores/types.ts +12 -0
  197. package/src/cmds/validator/keymanager/decryptKeystores/worker.ts +24 -0
  198. package/src/cmds/validator/keymanager/impl.ts +425 -0
  199. package/src/cmds/validator/keymanager/interface.ts +35 -0
  200. package/src/cmds/validator/keymanager/keystoreCache.ts +91 -0
  201. package/src/cmds/validator/keymanager/persistedKeys.ts +268 -0
  202. package/src/cmds/validator/keymanager/server.ts +86 -0
  203. package/src/cmds/validator/list.ts +35 -0
  204. package/src/cmds/validator/options.ts +461 -0
  205. package/src/cmds/validator/paths.ts +95 -0
  206. package/src/cmds/validator/signers/importExternalKeystores.ts +69 -0
  207. package/src/cmds/validator/signers/index.ts +176 -0
  208. package/src/cmds/validator/signers/logSigners.ts +81 -0
  209. package/src/cmds/validator/slashingProtection/export.ts +110 -0
  210. package/src/cmds/validator/slashingProtection/import.ts +70 -0
  211. package/src/cmds/validator/slashingProtection/index.ts +12 -0
  212. package/src/cmds/validator/slashingProtection/options.ts +15 -0
  213. package/src/cmds/validator/slashingProtection/utils.ts +56 -0
  214. package/src/cmds/validator/voluntaryExit.ts +232 -0
  215. package/src/config/beaconNodeOptions.ts +68 -0
  216. package/src/config/beaconParams.ts +87 -0
  217. package/src/config/index.ts +3 -0
  218. package/src/config/peerId.ts +50 -0
  219. package/src/config/types.ts +3 -0
  220. package/src/index.ts +28 -0
  221. package/src/migrations/index.ts +0 -0
  222. package/src/networks/chiado.ts +20 -0
  223. package/src/networks/dev.ts +27 -0
  224. package/src/networks/ephemery.ts +9 -0
  225. package/src/networks/gnosis.ts +18 -0
  226. package/src/networks/holesky.ts +17 -0
  227. package/src/networks/hoodi.ts +16 -0
  228. package/src/networks/index.ts +236 -0
  229. package/src/networks/mainnet.ts +34 -0
  230. package/src/networks/sepolia.ts +17 -0
  231. package/src/options/beaconNodeOptions/api.ts +110 -0
  232. package/src/options/beaconNodeOptions/builder.ts +63 -0
  233. package/src/options/beaconNodeOptions/chain.ts +326 -0
  234. package/src/options/beaconNodeOptions/eth1.ts +95 -0
  235. package/src/options/beaconNodeOptions/execution.ts +92 -0
  236. package/src/options/beaconNodeOptions/index.ts +50 -0
  237. package/src/options/beaconNodeOptions/metrics.ts +39 -0
  238. package/src/options/beaconNodeOptions/monitoring.ts +61 -0
  239. package/src/options/beaconNodeOptions/network.ts +401 -0
  240. package/src/options/beaconNodeOptions/sync.ts +65 -0
  241. package/src/options/globalOptions.ts +72 -0
  242. package/src/options/index.ts +3 -0
  243. package/src/options/logOptions.ts +70 -0
  244. package/src/options/paramsOptions.ts +72 -0
  245. package/src/paths/global.ts +24 -0
  246. package/src/paths/rootDir.ts +11 -0
  247. package/src/util/errors.ts +20 -0
  248. package/src/util/ethers.ts +44 -0
  249. package/src/util/feeRecipient.ts +6 -0
  250. package/src/util/file.ts +167 -0
  251. package/src/util/format.ts +76 -0
  252. package/src/util/fs.ts +59 -0
  253. package/src/util/gitData/gitDataPath.ts +48 -0
  254. package/src/util/gitData/index.ts +70 -0
  255. package/src/util/gitData/writeGitData.ts +10 -0
  256. package/src/util/hasher_bun.ts +133 -0
  257. package/src/util/hasher_nodejs.ts +3 -0
  258. package/src/util/index.ts +17 -0
  259. package/src/util/jwt.ts +10 -0
  260. package/src/util/lockfile.ts +45 -0
  261. package/src/util/logger.ts +105 -0
  262. package/src/util/object.ts +15 -0
  263. package/src/util/passphrase.ts +25 -0
  264. package/src/util/process.ts +25 -0
  265. package/src/util/progress.ts +58 -0
  266. package/src/util/proposerConfig.ts +136 -0
  267. package/src/util/pruneOldFilesInDir.ts +27 -0
  268. package/src/util/sleep.ts +3 -0
  269. package/src/util/stripOffNewlines.ts +6 -0
  270. package/src/util/types.ts +8 -0
  271. package/src/util/version.ts +74 -0
@@ -0,0 +1,92 @@
1
+ // MUST import this file first before anything and not import any Lodestar code.
2
+
3
+ import {hasher as hashtreeHasher} from "#hashtree-hasher";
4
+ import {setHasher} from "@chainsafe/persistent-merkle-tree";
5
+
6
+ // Without setting this first, persistent-merkle-tree will use noble instead
7
+ setHasher(hashtreeHasher);
8
+
9
+ //
10
+ // ## Rationale
11
+ //
12
+ // Lodestar implemented PRESET / CONFIG separation to allow importing types and preset constants directly
13
+ // see https://github.com/ChainSafe/lodestar/pull/2585
14
+ //
15
+ // However this prevents dynamic configuration changes which is exactly what the CLI required before.
16
+ // - The dev command can't apply the minimal preset dynamically
17
+ // - `--network gnosis` can't apply a different preset dynamically
18
+ // - `--network chiado` can't apply a different preset dynamically
19
+ //
20
+ // Running this file allows us to keep a static export strategy while NOT requiring users to
21
+ // set LODESTAR_PRESET manually every time.
22
+
23
+ // IMPORTANT: only import Lodestar code here which does not import any other Lodestar libraries
24
+ import {PresetName, presetFromJson, setActivePreset} from "@lodestar/params/setPreset";
25
+ import {readFile} from "./util/file.js";
26
+
27
+ const network = valueOfArg("network");
28
+ const preset = valueOfArg("preset");
29
+ const presetFile = valueOfArg("presetFile");
30
+
31
+ // Apply preset flag if present
32
+ if (preset) {
33
+ process.env.LODESTAR_PRESET = preset;
34
+ }
35
+
36
+ // If ENV is set overrides, network (otherwise can not override network --dev in mainnet mode)
37
+ else if (process.env.LODESTAR_PRESET) {
38
+ // break
39
+ }
40
+
41
+ // Translate network to preset
42
+ else if (network) {
43
+ if (network === "dev") {
44
+ process.env.LODESTAR_PRESET = "minimal";
45
+ // the kzg library has hardcoded the mainnet value, do not use presets
46
+ setActivePreset(PresetName.minimal, {FIELD_ELEMENTS_PER_BLOB: 4096});
47
+ } else if (network === "gnosis" || network === "chiado") {
48
+ process.env.LODESTAR_PRESET = "gnosis";
49
+ }
50
+ }
51
+
52
+ // If running dev top level command `$ lodestar dev`, apply minimal
53
+ else if (process.argv[2] === "dev") {
54
+ process.env.LODESTAR_PRESET = "minimal";
55
+ process.env.LODESTAR_NETWORK = "dev";
56
+ // the kzg library has hardcoded the mainnet value, do not use presets
57
+ setActivePreset(PresetName.minimal, {FIELD_ELEMENTS_PER_BLOB: 4096});
58
+ }
59
+
60
+ if (presetFile) {
61
+ // Override the active preset with custom values from file
62
+ // Do not modify the preset to use as a base by passing null
63
+ setActivePreset(null, presetFromJson(readFile(presetFile) ?? {}));
64
+ }
65
+
66
+ /**
67
+ * Valid syntax
68
+ * - `--preset minimal`
69
+ * - `--preset=minimal`
70
+ */
71
+ function valueOfArg(argName: string): string | null {
72
+ // Syntax `--preset minimal`
73
+ // process.argv = ["--preset", "minimal"];
74
+
75
+ {
76
+ const index = process.argv.indexOf(`--${argName}`);
77
+ if (index > -1) {
78
+ return process.argv[index + 1] ?? "";
79
+ }
80
+ }
81
+
82
+ // Syntax `--preset=minimal`
83
+ {
84
+ const prefix = `--${argName}=`;
85
+ const item = process.argv.find((arg) => arg.startsWith(prefix));
86
+ if (item) {
87
+ return item.slice(prefix.length);
88
+ }
89
+ }
90
+
91
+ return null;
92
+ }
package/src/cli.ts ADDED
@@ -0,0 +1,56 @@
1
+ // Must not use `* as yargs`, see https://github.com/yargs/yargs/issues/1131
2
+ import yargs, {Argv} from "yargs";
3
+ import {hideBin} from "yargs/helpers";
4
+ import {registerCommandToYargs} from "@lodestar/utils";
5
+ import {cmds} from "./cmds/index.js";
6
+ import {globalOptions, rcConfigOption} from "./options/index.js";
7
+ import {getVersionData} from "./util/version.js";
8
+
9
+ const {version} = getVersionData();
10
+ const topBanner = `🌟 Lodestar: TypeScript Implementation of the Ethereum Consensus Beacon Chain.
11
+ * Version: ${version}
12
+ * by ChainSafe Systems, 2018-${new Date().getFullYear()}`;
13
+ const bottomBanner = `📖 For more information, check the CLI reference:
14
+ * https://chainsafe.github.io/lodestar/reference/cli
15
+
16
+ ✍️ Give feedback and report issues on GitHub:
17
+ * https://github.com/ChainSafe/lodestar`;
18
+
19
+ export const yarg = yargs((hideBin as (args: string[]) => string[])(process.argv));
20
+
21
+ /**
22
+ * Common factory for running the CLI and running integration tests
23
+ * The CLI must actually be executed in a different script
24
+ */
25
+ export function getLodestarCli(): Argv {
26
+ const lodestar = yarg
27
+ .env("LODESTAR")
28
+ .parserConfiguration({
29
+ // As of yargs v16.1.0 dot-notation breaks strictOptions()
30
+ // Manually processing options is typesafe tho more verbose
31
+ "dot-notation": false,
32
+ })
33
+ .options(globalOptions)
34
+ // blank scriptName so that help text doesn't display the cli name before each command
35
+ .scriptName("")
36
+ .demandCommand(1)
37
+ // Control show help behaviour below on .fail()
38
+ .showHelpOnFail(false)
39
+ .usage(topBanner)
40
+ .epilogue(bottomBanner)
41
+ .version(topBanner)
42
+ .alias("h", "help")
43
+ .alias("v", "version")
44
+ .recommendCommands();
45
+
46
+ // yargs.command and all ./cmds
47
+ for (const cmd of cmds) {
48
+ registerCommandToYargs(lodestar, cmd);
49
+ }
50
+
51
+ // throw an error if we see an unrecognized cmd
52
+ lodestar.recommendCommands().strict();
53
+ lodestar.config(...rcConfigOption);
54
+
55
+ return lodestar;
56
+ }
@@ -0,0 +1,267 @@
1
+ import path from "node:path";
2
+ import {getHeapStatistics} from "node:v8";
3
+ import {SignableENR} from "@chainsafe/enr";
4
+ import {hasher} from "@chainsafe/persistent-merkle-tree";
5
+ import {BeaconDb, BeaconNode} from "@lodestar/beacon-node";
6
+ import {ChainForkConfig, createBeaconConfig} from "@lodestar/config";
7
+ import {LevelDbController} from "@lodestar/db/controller/level";
8
+ import {LoggerNode, getNodeLogger} from "@lodestar/logger/node";
9
+ import {ACTIVE_PRESET, PresetName} from "@lodestar/params";
10
+ import {ErrorAborted, bytesToInt} from "@lodestar/utils";
11
+ import {ProcessShutdownCallback} from "@lodestar/validator";
12
+ import {BeaconNodeOptions, getBeaconConfigFromArgs} from "../../config/index.js";
13
+ import {getNetworkBootnodes, getNetworkData, isKnownNetworkName, readBootnodes} from "../../networks/index.js";
14
+ import {GlobalArgs, parseBeaconNodeArgs} from "../../options/index.js";
15
+ import {LogArgs} from "../../options/logOptions.js";
16
+ import {
17
+ cleanOldLogFiles,
18
+ mkdir,
19
+ onGracefulShutdown,
20
+ parseLoggerArgs,
21
+ pruneOldFilesInDir,
22
+ writeFile600Perm,
23
+ } from "../../util/index.js";
24
+ import {getVersionData} from "../../util/version.js";
25
+ import {initBeaconState} from "./initBeaconState.js";
26
+ import {initPrivateKeyAndEnr} from "./initPeerIdAndEnr.js";
27
+ import {BeaconArgs} from "./options.js";
28
+ import {getBeaconPaths} from "./paths.js";
29
+
30
+ const DEFAULT_RETENTION_SSZ_OBJECTS_HOURS = 15 * 24;
31
+ const HOURS_TO_MS = 3600 * 1000;
32
+ const EIGHT_GB = 8 * 1024 * 1024 * 1024;
33
+
34
+ /**
35
+ * Runs a beacon node.
36
+ */
37
+ export async function beaconHandler(args: BeaconArgs & GlobalArgs): Promise<void> {
38
+ const {config, options, beaconPaths, network, version, commit, privateKey, logger} = await beaconHandlerInit(args);
39
+
40
+ if (hasher.name !== "hashtree") {
41
+ logger.warn(`hashtree is not supported, using hasher ${hasher.name}`);
42
+ }
43
+
44
+ const heapSizeLimit = getHeapStatistics().heap_size_limit;
45
+ if (heapSizeLimit < EIGHT_GB) {
46
+ logger.warn(
47
+ `Node.js heap size limit is too low, consider increasing it to at least ${EIGHT_GB}. See https://chainsafe.github.io/lodestar/faqs/#running-a-beacon-node for more details.`
48
+ );
49
+ }
50
+
51
+ // initialize directories
52
+ mkdir(beaconPaths.dataDir);
53
+ mkdir(beaconPaths.beaconDir);
54
+ mkdir(beaconPaths.dbDir);
55
+
56
+ const abortController = new AbortController();
57
+
58
+ logger.info("Lodestar", {network, version, commit});
59
+ // Callback for beacon to request forced exit, for e.g. in case of irrecoverable
60
+ // forkchoice errors
61
+ const processShutdownCallback: ProcessShutdownCallback = (err) => {
62
+ logger.error("Process shutdown requested", {}, err);
63
+ process.kill(process.pid, "SIGINT");
64
+ };
65
+
66
+ if (ACTIVE_PRESET === PresetName.minimal) logger.info("ACTIVE_PRESET == minimal preset");
67
+
68
+ const db = new BeaconDb(config, await LevelDbController.create(options.db, {metrics: null, logger}));
69
+ logger.info("Connected to LevelDB database", {path: options.db.name});
70
+
71
+ // BeaconNode setup
72
+ try {
73
+ const {anchorState, wsCheckpoint} = await initBeaconState(
74
+ options,
75
+ args,
76
+ config,
77
+ db,
78
+ logger,
79
+ abortController.signal
80
+ );
81
+ const beaconConfig = createBeaconConfig(config, anchorState.genesisValidatorsRoot);
82
+ const node = await BeaconNode.init({
83
+ opts: options,
84
+ config: beaconConfig,
85
+ db,
86
+ logger,
87
+ processShutdownCallback,
88
+ privateKey,
89
+ dataDir: beaconPaths.dataDir,
90
+ peerStoreDir: beaconPaths.peerStoreDir,
91
+ anchorState,
92
+ wsCheckpoint,
93
+ });
94
+
95
+ // dev debug option to have access to the BN instance
96
+ if (args.attachToGlobalThis) {
97
+ (globalThis as unknown as {bn: BeaconNode}).bn = node;
98
+ }
99
+
100
+ // Prune invalid SSZ objects every interval
101
+ const {persistInvalidSszObjectsDir, persistInvalidSszObjects} = options.chain;
102
+ const pruneInvalidSSZObjectsInterval =
103
+ persistInvalidSszObjectsDir && persistInvalidSszObjects
104
+ ? setInterval(() => {
105
+ try {
106
+ const deletedFileCount = pruneOldFilesInDir(
107
+ persistInvalidSszObjectsDir,
108
+ (args.persistInvalidSszObjectsRetentionHours ?? DEFAULT_RETENTION_SSZ_OBJECTS_HOURS) * HOURS_TO_MS
109
+ );
110
+ logger.info("Pruned invalid SSZ objects", {deletedFileCount});
111
+ } catch (e) {
112
+ logger.warn("Error pruning invalid SSZ objects", {persistInvalidSszObjectsDir}, e as Error);
113
+ }
114
+ // Run every ~1 hour
115
+ }, HOURS_TO_MS)
116
+ : null;
117
+
118
+ // Intercept SIGINT signal, to perform final ops before exiting
119
+ onGracefulShutdown(async () => {
120
+ if (args.persistNetworkIdentity) {
121
+ try {
122
+ const networkIdentity = await node.network.getNetworkIdentity();
123
+ const enrPath = path.join(beaconPaths.beaconDir, "enr");
124
+ writeFile600Perm(enrPath, networkIdentity.enr);
125
+ } catch (e) {
126
+ logger.warn("Unable to persist enr", {}, e as Error);
127
+ }
128
+ }
129
+ abortController.abort();
130
+
131
+ if (pruneInvalidSSZObjectsInterval !== null) {
132
+ clearInterval(pruneInvalidSSZObjectsInterval);
133
+ }
134
+ }, logger.info.bind(logger));
135
+
136
+ abortController.signal.addEventListener(
137
+ "abort",
138
+ async () => {
139
+ try {
140
+ await node.close();
141
+ logger.debug("Beacon node closed");
142
+ // Explicitly exit until active handles issue is resolved
143
+ // See https://github.com/ChainSafe/lodestar/issues/5642
144
+ process.exit(0);
145
+ } catch (e) {
146
+ logger.error("Error closing beacon node", {}, e as Error);
147
+ // Make sure db is always closed gracefully
148
+ await db.close();
149
+ // Must explicitly exit process due to potential active handles
150
+ process.exit(1);
151
+ }
152
+ },
153
+ {once: true}
154
+ );
155
+ } catch (e) {
156
+ await db.close();
157
+
158
+ if (e instanceof ErrorAborted) {
159
+ logger.info(e.message); // Let the user know the abort was received but don't print as error
160
+ } else {
161
+ throw e;
162
+ }
163
+ }
164
+ }
165
+
166
+ /** Separate function to simplify unit testing of options merging */
167
+ export async function beaconHandlerInit(args: BeaconArgs & GlobalArgs) {
168
+ const {config, network} = getBeaconConfigFromArgs(args);
169
+
170
+ const beaconNodeOptions = new BeaconNodeOptions(parseBeaconNodeArgs(args));
171
+
172
+ const {version, commit} = getVersionData();
173
+ const beaconPaths = getBeaconPaths(args, network);
174
+ // TODO: Rename db.name to db.path or db.location
175
+ beaconNodeOptions.set({db: {name: beaconPaths.dbDir}});
176
+ beaconNodeOptions.set({
177
+ chain: {
178
+ validatorMonitorLogs: args.validatorMonitorLogs,
179
+ persistInvalidSszObjectsDir: beaconPaths.persistInvalidSszObjectsDir,
180
+ persistOrphanedBlocksDir: beaconPaths.persistOrphanedBlocksDir,
181
+ },
182
+ });
183
+ // Add metrics metadata to show versioning + network info in Prometheus + Grafana
184
+ beaconNodeOptions.set({metrics: {metadata: {version, commit, network}}});
185
+ // Add detailed version string for API node/version endpoint
186
+ beaconNodeOptions.set({api: {commit, version}});
187
+
188
+ if (args.supernode) {
189
+ beaconNodeOptions.set({chain: {supernode: true}, network: {supernode: true}});
190
+ }
191
+
192
+ // Set known depositContractDeployBlock
193
+ if (isKnownNetworkName(network)) {
194
+ const {depositContractDeployBlock} = getNetworkData(network);
195
+ beaconNodeOptions.set({eth1: {depositContractDeployBlock}});
196
+ }
197
+
198
+ const logger = initLogger(args, beaconPaths.dataDir, config);
199
+ const {privateKey, enr} = await initPrivateKeyAndEnr(args, beaconPaths.beaconDir, logger);
200
+
201
+ if (args.discv5 !== false) {
202
+ // Inject ENR to beacon options
203
+ beaconNodeOptions.set({network: {discv5: {enr: enr.encodeTxt(), config: {enrUpdate: !enr.ip && !enr.ip6}}}});
204
+
205
+ // Combine bootnodes from different sources
206
+ const bootnodes = (beaconNodeOptions.get().network?.discv5?.bootEnrs ?? []).concat(
207
+ args.bootnodesFile ? readBootnodes(args.bootnodesFile) : [],
208
+ isKnownNetworkName(network) ? await getNetworkBootnodes(network) : []
209
+ );
210
+ // Deduplicate and set combined bootnodes
211
+ beaconNodeOptions.set({network: {discv5: {bootEnrs: [...new Set(bootnodes)]}}});
212
+ }
213
+
214
+ beaconNodeOptions.set({chain: {initialCustodyGroupCount: getInitialCustodyGroupCount(args, config, enr)}});
215
+
216
+ if (args.disableLightClientServer) {
217
+ beaconNodeOptions.set({chain: {disableLightClientServer: true}});
218
+ }
219
+
220
+ if (args.private) {
221
+ beaconNodeOptions.set({network: {private: true}, api: {private: true}});
222
+ } else {
223
+ const versionStr = `Lodestar/${version}`;
224
+ const simpleVersionStr = version.split("/")[0];
225
+ // Add simple version string for libp2p agent version
226
+ beaconNodeOptions.set({network: {version: simpleVersionStr}});
227
+ // Add User-Agent header to all builder requests
228
+ beaconNodeOptions.set({executionBuilder: {userAgent: versionStr}});
229
+ // Set jwt version with version string
230
+ beaconNodeOptions.set({executionEngine: {jwtVersion: versionStr}, eth1: {jwtVersion: versionStr}});
231
+ // Set commit and version for ClientVersion
232
+ beaconNodeOptions.set({executionEngine: {commit, version}});
233
+ }
234
+
235
+ // Render final options
236
+ const options = beaconNodeOptions.getWithDefaults();
237
+
238
+ return {config, options, beaconPaths, network, version, commit, privateKey, logger};
239
+ }
240
+
241
+ export function initLogger(
242
+ args: LogArgs & Pick<GlobalArgs, "dataDir">,
243
+ dataDir: string,
244
+ config: ChainForkConfig,
245
+ fileName = "beacon.log"
246
+ ): LoggerNode {
247
+ const defaultLogFilepath = path.join(dataDir, fileName);
248
+ const logger = getNodeLogger(parseLoggerArgs(args, {defaultLogFilepath}, config));
249
+ try {
250
+ cleanOldLogFiles(args, {defaultLogFilepath});
251
+ } catch (e) {
252
+ logger.debug("Not able to delete log files", {}, e as Error);
253
+ }
254
+
255
+ return logger;
256
+ }
257
+
258
+ function getInitialCustodyGroupCount(args: BeaconArgs & GlobalArgs, config: ChainForkConfig, enr: SignableENR): number {
259
+ if (args.supernode) {
260
+ return config.NUMBER_OF_CUSTODY_GROUPS;
261
+ }
262
+
263
+ const enrCgcBytes = enr.kvs.get("cgc");
264
+ const enrCgc = enrCgcBytes != null ? bytesToInt(enrCgcBytes, "be") : 0;
265
+
266
+ return Math.max(enrCgc, config.CUSTODY_REQUIREMENT);
267
+ }
@@ -0,0 +1,18 @@
1
+ import {CliCommand, CliCommandOptions} from "@lodestar/utils";
2
+ import {GlobalArgs} from "../../options/index.js";
3
+ import {beaconHandler} from "./handler.js";
4
+ import {BeaconArgs, beaconOptions} from "./options.js";
5
+
6
+ export const beacon: CliCommand<BeaconArgs, GlobalArgs> = {
7
+ command: "beacon",
8
+ describe: "Run a beacon chain node",
9
+ docsFolder: "run/beacon-management",
10
+ examples: [
11
+ {
12
+ command: "beacon --network hoodi",
13
+ description: "Run a beacon chain node and connect to the hoodi testnet",
14
+ },
15
+ ],
16
+ options: beaconOptions as CliCommandOptions<BeaconArgs>,
17
+ handler: beaconHandler,
18
+ };