@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.
- package/.git-data.json +1 -1
- package/bin/lodestar.js +3 -0
- package/bin/lodestar.ts +3 -0
- package/lib/applyPreset.d.ts.map +1 -0
- package/lib/applyPreset.js +1 -1
- package/lib/applyPreset.js.map +1 -1
- package/lib/cli.d.ts +3 -3
- package/lib/cli.d.ts.map +1 -0
- package/lib/cli.js +1 -1
- package/lib/cli.js.map +1 -1
- package/lib/cmds/beacon/handler.d.ts +1 -1
- package/lib/cmds/beacon/handler.d.ts.map +1 -0
- package/lib/cmds/beacon/handler.js +1 -1
- package/lib/cmds/beacon/handler.js.map +1 -1
- package/lib/cmds/beacon/index.d.ts.map +1 -0
- package/lib/cmds/beacon/initBeaconState.d.ts.map +1 -0
- package/lib/cmds/beacon/initBeaconState.js.map +1 -1
- package/lib/cmds/beacon/initPeerIdAndEnr.d.ts +2 -2
- package/lib/cmds/beacon/initPeerIdAndEnr.d.ts.map +1 -0
- package/lib/cmds/beacon/initPeerIdAndEnr.js +1 -1
- package/lib/cmds/beacon/initPeerIdAndEnr.js.map +1 -1
- package/lib/cmds/beacon/options.d.ts.map +1 -0
- package/lib/cmds/beacon/paths.d.ts.map +1 -0
- package/lib/cmds/bootnode/handler.d.ts +13 -8
- package/lib/cmds/bootnode/handler.d.ts.map +1 -0
- package/lib/cmds/bootnode/handler.js +2 -2
- package/lib/cmds/bootnode/handler.js.map +1 -1
- package/lib/cmds/bootnode/index.d.ts.map +1 -0
- package/lib/cmds/bootnode/options.d.ts.map +1 -0
- package/lib/cmds/bootnode/options.js +2 -1
- package/lib/cmds/bootnode/options.js.map +1 -1
- package/lib/cmds/dev/files.d.ts.map +1 -0
- package/lib/cmds/dev/handler.d.ts.map +1 -0
- package/lib/cmds/dev/handler.js +1 -1
- package/lib/cmds/dev/handler.js.map +1 -1
- package/lib/cmds/dev/index.d.ts.map +1 -0
- package/lib/cmds/dev/options.d.ts.map +1 -0
- package/lib/cmds/index.d.ts.map +1 -0
- package/lib/cmds/lightclient/handler.d.ts.map +1 -0
- package/lib/cmds/lightclient/index.d.ts.map +1 -0
- package/lib/cmds/lightclient/options.d.ts.map +1 -0
- package/lib/cmds/validator/blsToExecutionChange.d.ts.map +1 -0
- package/lib/cmds/validator/blsToExecutionChange.js.map +1 -1
- package/lib/cmds/validator/handler.d.ts.map +1 -0
- package/lib/cmds/validator/handler.js +3 -5
- package/lib/cmds/validator/handler.js.map +1 -1
- package/lib/cmds/validator/import.d.ts.map +1 -0
- package/lib/cmds/validator/index.d.ts.map +1 -0
- package/lib/cmds/validator/keymanager/decryptKeystoreDefinitions.d.ts.map +1 -0
- package/lib/cmds/validator/keymanager/decryptKeystores/index.d.ts.map +1 -0
- package/lib/cmds/validator/keymanager/decryptKeystores/poolSize.d.ts.map +1 -0
- package/lib/cmds/validator/keymanager/decryptKeystores/threadPool.d.ts.map +1 -0
- package/lib/cmds/validator/keymanager/decryptKeystores/threadPool.js +4 -1
- package/lib/cmds/validator/keymanager/decryptKeystores/threadPool.js.map +1 -1
- package/lib/cmds/validator/keymanager/decryptKeystores/types.d.ts.map +1 -0
- package/lib/cmds/validator/keymanager/decryptKeystores/worker.d.ts.map +1 -0
- package/lib/cmds/validator/keymanager/impl.d.ts.map +1 -0
- package/lib/cmds/validator/keymanager/impl.js +4 -0
- package/lib/cmds/validator/keymanager/impl.js.map +1 -1
- package/lib/cmds/validator/keymanager/interface.d.ts.map +1 -0
- package/lib/cmds/validator/keymanager/keystoreCache.d.ts.map +1 -0
- package/lib/cmds/validator/keymanager/persistedKeys.d.ts.map +1 -0
- package/lib/cmds/validator/keymanager/persistedKeys.js +1 -0
- package/lib/cmds/validator/keymanager/persistedKeys.js.map +1 -1
- package/lib/cmds/validator/keymanager/server.d.ts.map +1 -0
- package/lib/cmds/validator/keymanager/server.js +2 -0
- package/lib/cmds/validator/keymanager/server.js.map +1 -1
- package/lib/cmds/validator/list.d.ts.map +1 -0
- package/lib/cmds/validator/options.d.ts.map +1 -0
- package/lib/cmds/validator/options.js +2 -2
- package/lib/cmds/validator/paths.d.ts.map +1 -0
- package/lib/cmds/validator/signers/importExternalKeystores.d.ts.map +1 -0
- package/lib/cmds/validator/signers/index.d.ts.map +1 -0
- package/lib/cmds/validator/signers/logSigners.d.ts.map +1 -0
- package/lib/cmds/validator/slashingProtection/export.d.ts.map +1 -0
- package/lib/cmds/validator/slashingProtection/import.d.ts.map +1 -0
- package/lib/cmds/validator/slashingProtection/index.d.ts.map +1 -0
- package/lib/cmds/validator/slashingProtection/options.d.ts.map +1 -0
- package/lib/cmds/validator/slashingProtection/utils.d.ts.map +1 -0
- package/lib/cmds/validator/slashingProtection/utils.js +1 -1
- package/lib/cmds/validator/slashingProtection/utils.js.map +1 -1
- package/lib/cmds/validator/voluntaryExit.d.ts.map +1 -0
- package/lib/cmds/validator/voluntaryExit.js +1 -1
- package/lib/cmds/validator/voluntaryExit.js.map +1 -1
- package/lib/config/beaconNodeOptions.d.ts.map +1 -0
- package/lib/config/beaconNodeOptions.js +2 -1
- package/lib/config/beaconNodeOptions.js.map +1 -1
- package/lib/config/beaconParams.d.ts.map +1 -0
- package/lib/config/index.d.ts.map +1 -0
- package/lib/config/peerId.d.ts.map +1 -0
- package/lib/config/types.d.ts.map +1 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js.map +1 -1
- package/lib/migrations/index.d.ts +1 -0
- package/lib/migrations/index.d.ts.map +1 -0
- package/lib/migrations/index.js +1 -1
- package/lib/networks/chiado.d.ts.map +1 -0
- package/lib/networks/dev.d.ts.map +1 -0
- package/lib/networks/ephemery.d.ts.map +1 -0
- package/lib/networks/gnosis.d.ts.map +1 -0
- package/lib/networks/holesky.d.ts.map +1 -0
- package/lib/networks/hoodi.d.ts.map +1 -0
- package/lib/networks/index.d.ts.map +1 -0
- package/lib/networks/index.js +1 -2
- package/lib/networks/index.js.map +1 -1
- package/lib/networks/mainnet.d.ts.map +1 -0
- package/lib/networks/sepolia.d.ts.map +1 -0
- package/lib/options/beaconNodeOptions/api.d.ts.map +1 -0
- package/lib/options/beaconNodeOptions/builder.d.ts.map +1 -0
- package/lib/options/beaconNodeOptions/chain.d.ts.map +1 -0
- package/lib/options/beaconNodeOptions/eth1.d.ts.map +1 -0
- package/lib/options/beaconNodeOptions/execution.d.ts.map +1 -0
- package/lib/options/beaconNodeOptions/index.d.ts.map +1 -0
- package/lib/options/beaconNodeOptions/metrics.d.ts.map +1 -0
- package/lib/options/beaconNodeOptions/monitoring.d.ts.map +1 -0
- package/lib/options/beaconNodeOptions/network.d.ts +1 -0
- package/lib/options/beaconNodeOptions/network.d.ts.map +1 -0
- package/lib/options/beaconNodeOptions/network.js +6 -3
- package/lib/options/beaconNodeOptions/network.js.map +1 -1
- package/lib/options/beaconNodeOptions/sync.d.ts.map +1 -0
- package/lib/options/globalOptions.d.ts.map +1 -0
- package/lib/options/index.d.ts.map +1 -0
- package/lib/options/logOptions.d.ts.map +1 -0
- package/lib/options/paramsOptions.d.ts.map +1 -0
- package/lib/paths/global.d.ts.map +1 -0
- package/lib/paths/rootDir.d.ts.map +1 -0
- package/lib/util/errors.d.ts.map +1 -0
- package/lib/util/ethers.d.ts.map +1 -0
- package/lib/util/feeRecipient.d.ts.map +1 -0
- package/lib/util/file.d.ts.map +1 -0
- package/lib/util/file.js +1 -1
- package/lib/util/file.js.map +1 -1
- package/lib/util/format.d.ts.map +1 -0
- package/lib/util/fs.d.ts.map +1 -0
- package/lib/util/gitData/gitDataPath.d.ts.map +1 -0
- package/lib/util/gitData/index.d.ts.map +1 -0
- package/lib/util/gitData/index.js.map +1 -1
- package/lib/util/gitData/writeGitData.d.ts.map +1 -0
- package/lib/util/hasher_bun.d.ts +3 -0
- package/lib/util/hasher_bun.d.ts.map +1 -0
- package/lib/util/hasher_bun.js +118 -0
- package/lib/util/hasher_bun.js.map +1 -0
- package/lib/util/hasher_nodejs.d.ts +3 -0
- package/lib/util/hasher_nodejs.d.ts.map +1 -0
- package/lib/util/hasher_nodejs.js +3 -0
- package/lib/util/hasher_nodejs.js.map +1 -0
- package/lib/util/index.d.ts +3 -3
- package/lib/util/index.d.ts.map +1 -0
- package/lib/util/index.js +3 -3
- package/lib/util/index.js.map +1 -1
- package/lib/util/jwt.d.ts.map +1 -0
- package/lib/util/lockfile.d.ts.map +1 -0
- package/lib/util/logger.d.ts.map +1 -0
- package/lib/util/logger.js +1 -1
- package/lib/util/logger.js.map +1 -1
- package/lib/util/object.d.ts.map +1 -0
- package/lib/util/object.js.map +1 -1
- package/lib/util/passphrase.d.ts.map +1 -0
- package/lib/util/process.d.ts.map +1 -0
- package/lib/util/progress.d.ts.map +1 -0
- package/lib/util/proposerConfig.d.ts.map +1 -0
- package/lib/util/proposerConfig.js.map +1 -1
- package/lib/util/pruneOldFilesInDir.d.ts.map +1 -0
- package/lib/util/sleep.d.ts.map +1 -0
- package/lib/util/stripOffNewlines.d.ts.map +1 -0
- package/lib/util/types.d.ts.map +1 -0
- package/lib/util/version.d.ts.map +1 -0
- package/package.json +33 -20
- package/src/applyPreset.ts +92 -0
- package/src/cli.ts +56 -0
- package/src/cmds/beacon/handler.ts +267 -0
- package/src/cmds/beacon/index.ts +18 -0
- package/src/cmds/beacon/initBeaconState.ts +275 -0
- package/src/cmds/beacon/initPeerIdAndEnr.ts +199 -0
- package/src/cmds/beacon/options.ts +214 -0
- package/src/cmds/beacon/paths.ts +62 -0
- package/src/cmds/bootnode/handler.ts +203 -0
- package/src/cmds/bootnode/index.ts +13 -0
- package/src/cmds/bootnode/options.ts +109 -0
- package/src/cmds/dev/files.ts +52 -0
- package/src/cmds/dev/handler.ts +86 -0
- package/src/cmds/dev/index.ts +18 -0
- package/src/cmds/dev/options.ts +110 -0
- package/src/cmds/index.ts +15 -0
- package/src/cmds/lightclient/handler.ts +36 -0
- package/src/cmds/lightclient/index.ts +18 -0
- package/src/cmds/lightclient/options.ts +21 -0
- package/src/cmds/validator/blsToExecutionChange.ts +91 -0
- package/src/cmds/validator/handler.ts +300 -0
- package/src/cmds/validator/import.ts +111 -0
- package/src/cmds/validator/index.ts +28 -0
- package/src/cmds/validator/keymanager/decryptKeystoreDefinitions.ts +189 -0
- package/src/cmds/validator/keymanager/decryptKeystores/index.ts +1 -0
- package/src/cmds/validator/keymanager/decryptKeystores/poolSize.ts +16 -0
- package/src/cmds/validator/keymanager/decryptKeystores/threadPool.ts +75 -0
- package/src/cmds/validator/keymanager/decryptKeystores/types.ts +12 -0
- package/src/cmds/validator/keymanager/decryptKeystores/worker.ts +24 -0
- package/src/cmds/validator/keymanager/impl.ts +425 -0
- package/src/cmds/validator/keymanager/interface.ts +35 -0
- package/src/cmds/validator/keymanager/keystoreCache.ts +91 -0
- package/src/cmds/validator/keymanager/persistedKeys.ts +268 -0
- package/src/cmds/validator/keymanager/server.ts +86 -0
- package/src/cmds/validator/list.ts +35 -0
- package/src/cmds/validator/options.ts +461 -0
- package/src/cmds/validator/paths.ts +95 -0
- package/src/cmds/validator/signers/importExternalKeystores.ts +69 -0
- package/src/cmds/validator/signers/index.ts +176 -0
- package/src/cmds/validator/signers/logSigners.ts +81 -0
- package/src/cmds/validator/slashingProtection/export.ts +110 -0
- package/src/cmds/validator/slashingProtection/import.ts +70 -0
- package/src/cmds/validator/slashingProtection/index.ts +12 -0
- package/src/cmds/validator/slashingProtection/options.ts +15 -0
- package/src/cmds/validator/slashingProtection/utils.ts +56 -0
- package/src/cmds/validator/voluntaryExit.ts +232 -0
- package/src/config/beaconNodeOptions.ts +68 -0
- package/src/config/beaconParams.ts +87 -0
- package/src/config/index.ts +3 -0
- package/src/config/peerId.ts +50 -0
- package/src/config/types.ts +3 -0
- package/src/index.ts +28 -0
- package/src/migrations/index.ts +0 -0
- package/src/networks/chiado.ts +20 -0
- package/src/networks/dev.ts +27 -0
- package/src/networks/ephemery.ts +9 -0
- package/src/networks/gnosis.ts +18 -0
- package/src/networks/holesky.ts +17 -0
- package/src/networks/hoodi.ts +16 -0
- package/src/networks/index.ts +236 -0
- package/src/networks/mainnet.ts +34 -0
- package/src/networks/sepolia.ts +17 -0
- package/src/options/beaconNodeOptions/api.ts +110 -0
- package/src/options/beaconNodeOptions/builder.ts +63 -0
- package/src/options/beaconNodeOptions/chain.ts +326 -0
- package/src/options/beaconNodeOptions/eth1.ts +95 -0
- package/src/options/beaconNodeOptions/execution.ts +92 -0
- package/src/options/beaconNodeOptions/index.ts +50 -0
- package/src/options/beaconNodeOptions/metrics.ts +39 -0
- package/src/options/beaconNodeOptions/monitoring.ts +61 -0
- package/src/options/beaconNodeOptions/network.ts +401 -0
- package/src/options/beaconNodeOptions/sync.ts +65 -0
- package/src/options/globalOptions.ts +72 -0
- package/src/options/index.ts +3 -0
- package/src/options/logOptions.ts +70 -0
- package/src/options/paramsOptions.ts +72 -0
- package/src/paths/global.ts +24 -0
- package/src/paths/rootDir.ts +11 -0
- package/src/util/errors.ts +20 -0
- package/src/util/ethers.ts +44 -0
- package/src/util/feeRecipient.ts +6 -0
- package/src/util/file.ts +167 -0
- package/src/util/format.ts +76 -0
- package/src/util/fs.ts +59 -0
- package/src/util/gitData/gitDataPath.ts +48 -0
- package/src/util/gitData/index.ts +70 -0
- package/src/util/gitData/writeGitData.ts +10 -0
- package/src/util/hasher_bun.ts +133 -0
- package/src/util/hasher_nodejs.ts +3 -0
- package/src/util/index.ts +17 -0
- package/src/util/jwt.ts +10 -0
- package/src/util/lockfile.ts +45 -0
- package/src/util/logger.ts +105 -0
- package/src/util/object.ts +15 -0
- package/src/util/passphrase.ts +25 -0
- package/src/util/process.ts +25 -0
- package/src/util/progress.ts +58 -0
- package/src/util/proposerConfig.ts +136 -0
- package/src/util/pruneOldFilesInDir.ts +27 -0
- package/src/util/sleep.ts +3 -0
- package/src/util/stripOffNewlines.ts +6 -0
- package/src/util/types.ts +8 -0
- package/src/util/version.ts +74 -0
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import {ENR} from "@chainsafe/enr";
|
|
3
|
+
import {WireFormat, getClient} from "@lodestar/api";
|
|
4
|
+
import {getStateSlotFromBytes} from "@lodestar/beacon-node";
|
|
5
|
+
import {ChainConfig, ChainForkConfig} from "@lodestar/config";
|
|
6
|
+
import {SLOTS_PER_EPOCH} from "@lodestar/params";
|
|
7
|
+
import {
|
|
8
|
+
BeaconStateAllForks,
|
|
9
|
+
computeCheckpointEpochAtStateSlot,
|
|
10
|
+
getLatestBlockRoot,
|
|
11
|
+
loadState,
|
|
12
|
+
} from "@lodestar/state-transition";
|
|
13
|
+
import {Slot, sszTypesFor} from "@lodestar/types";
|
|
14
|
+
import {Checkpoint} from "@lodestar/types/phase0";
|
|
15
|
+
import {Logger, callFnWhenAwait, fetch, formatBytes, fromHex} from "@lodestar/utils";
|
|
16
|
+
import {parseBootnodesFile} from "../util/format.js";
|
|
17
|
+
import * as chiado from "./chiado.js";
|
|
18
|
+
import * as dev from "./dev.js";
|
|
19
|
+
import * as ephemery from "./ephemery.js";
|
|
20
|
+
import * as gnosis from "./gnosis.js";
|
|
21
|
+
import * as holesky from "./holesky.js";
|
|
22
|
+
import * as hoodi from "./hoodi.js";
|
|
23
|
+
import * as mainnet from "./mainnet.js";
|
|
24
|
+
import * as sepolia from "./sepolia.js";
|
|
25
|
+
|
|
26
|
+
export type NetworkName = "mainnet" | "dev" | "gnosis" | "sepolia" | "holesky" | "hoodi" | "chiado" | "ephemery";
|
|
27
|
+
export const networkNames: NetworkName[] = [
|
|
28
|
+
"mainnet",
|
|
29
|
+
"gnosis",
|
|
30
|
+
"sepolia",
|
|
31
|
+
"holesky",
|
|
32
|
+
"hoodi",
|
|
33
|
+
"chiado",
|
|
34
|
+
"ephemery",
|
|
35
|
+
|
|
36
|
+
// Leave always as last network. The order matters for the --help printout
|
|
37
|
+
"dev",
|
|
38
|
+
];
|
|
39
|
+
|
|
40
|
+
export function isKnownNetworkName(network: string): network is NetworkName {
|
|
41
|
+
return networkNames.includes(network as NetworkName);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export type WeakSubjectivityFetchOptions = {
|
|
45
|
+
weakSubjectivityServerUrl: string;
|
|
46
|
+
weakSubjectivityCheckpoint?: string;
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
// log to screen every 30s when downloading state from a lodestar node
|
|
50
|
+
const GET_STATE_LOG_INTERVAL = 30 * 1000;
|
|
51
|
+
|
|
52
|
+
export function getNetworkData(network: NetworkName): {
|
|
53
|
+
chainConfig: ChainConfig;
|
|
54
|
+
depositContractDeployBlock: number;
|
|
55
|
+
genesisFileUrl: string | null;
|
|
56
|
+
genesisStateRoot: string | null;
|
|
57
|
+
bootnodesFileUrl: string | null;
|
|
58
|
+
bootEnrs: string[];
|
|
59
|
+
} {
|
|
60
|
+
switch (network) {
|
|
61
|
+
case "mainnet":
|
|
62
|
+
return mainnet;
|
|
63
|
+
case "dev":
|
|
64
|
+
return dev;
|
|
65
|
+
case "gnosis":
|
|
66
|
+
return gnosis;
|
|
67
|
+
case "sepolia":
|
|
68
|
+
return sepolia;
|
|
69
|
+
case "holesky":
|
|
70
|
+
return holesky;
|
|
71
|
+
case "hoodi":
|
|
72
|
+
return hoodi;
|
|
73
|
+
case "chiado":
|
|
74
|
+
return chiado;
|
|
75
|
+
case "ephemery":
|
|
76
|
+
return ephemery;
|
|
77
|
+
default:
|
|
78
|
+
throw Error(`Network not supported: ${network}`);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export function getNetworkBeaconParams(network: NetworkName): ChainConfig {
|
|
83
|
+
return getNetworkData(network).chainConfig;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Get genesisStateFile URL to download. Returns null if not available
|
|
88
|
+
*/
|
|
89
|
+
export function getGenesisFileUrl(network: NetworkName): string | null {
|
|
90
|
+
return getNetworkData(network).genesisFileUrl;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Get expected genesisStateRoot for validation. Returns null if not available.
|
|
95
|
+
* For example, this returns null for Ephemery, since its genesis state root
|
|
96
|
+
* changes with each iteration and we don't know the permanent state root.
|
|
97
|
+
*/
|
|
98
|
+
export function getGenesisStateRoot(network: NetworkName | undefined): string | null {
|
|
99
|
+
if (!network) {
|
|
100
|
+
return null;
|
|
101
|
+
}
|
|
102
|
+
return getNetworkData(network).genesisStateRoot;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Fetches the latest list of bootnodes for a network
|
|
107
|
+
* Bootnodes file is expected to contain bootnode ENR's concatenated by newlines
|
|
108
|
+
*/
|
|
109
|
+
export async function fetchBootnodes(network: NetworkName): Promise<string[]> {
|
|
110
|
+
const bootnodesFileUrl = getNetworkData(network).bootnodesFileUrl;
|
|
111
|
+
if (bootnodesFileUrl === null) {
|
|
112
|
+
return [];
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
const res = await fetch(bootnodesFileUrl);
|
|
116
|
+
if (!res.ok) {
|
|
117
|
+
throw new Error(`Failed to fetch bootnodes: ${res.status} ${res.statusText}`);
|
|
118
|
+
}
|
|
119
|
+
const bootnodesFile = await res.text();
|
|
120
|
+
return parseBootnodesFile(bootnodesFile);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
export async function getNetworkBootnodes(network: NetworkName): Promise<string[]> {
|
|
124
|
+
const bootnodes = [...getNetworkData(network).bootEnrs];
|
|
125
|
+
|
|
126
|
+
// Hidden option for testing
|
|
127
|
+
if (!process.env.SKIP_FETCH_NETWORK_BOOTNODES) {
|
|
128
|
+
try {
|
|
129
|
+
const bootEnrs = await fetchBootnodes(network);
|
|
130
|
+
bootnodes.push(...bootEnrs);
|
|
131
|
+
} catch (e) {
|
|
132
|
+
console.error(`Error fetching latest bootnodes: ${(e as Error).stack}`);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
return bootnodes;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Reads and parses a list of bootnodes for a network from a file.
|
|
141
|
+
*/
|
|
142
|
+
export function readBootnodes(bootnodesFilePath: string): string[] {
|
|
143
|
+
const bootnodesFile = fs.readFileSync(bootnodesFilePath, "utf8");
|
|
144
|
+
|
|
145
|
+
const bootnodes = parseBootnodesFile(bootnodesFile);
|
|
146
|
+
for (const enrStr of bootnodes) {
|
|
147
|
+
try {
|
|
148
|
+
ENR.decodeTxt(enrStr);
|
|
149
|
+
} catch (_e) {
|
|
150
|
+
throw new Error(`Invalid ENR found in ${bootnodesFilePath}:\n ${enrStr}`);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
if (bootnodes.length === 0) {
|
|
155
|
+
throw new Error(`No bootnodes found on file ${bootnodesFilePath}`);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
return bootnodes;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Fetch weak subjectivity state from a remote beacon node
|
|
163
|
+
*/
|
|
164
|
+
export async function fetchWeakSubjectivityState(
|
|
165
|
+
config: ChainForkConfig,
|
|
166
|
+
logger: Logger,
|
|
167
|
+
{checkpointSyncUrl, wssCheckpoint}: {checkpointSyncUrl: string; wssCheckpoint?: string},
|
|
168
|
+
{
|
|
169
|
+
lastDbState,
|
|
170
|
+
lastDbValidatorsBytes,
|
|
171
|
+
}: {lastDbState: BeaconStateAllForks | null; lastDbValidatorsBytes: Uint8Array | null}
|
|
172
|
+
): Promise<{wsState: BeaconStateAllForks; wsStateBytes: Uint8Array; wsCheckpoint: Checkpoint}> {
|
|
173
|
+
try {
|
|
174
|
+
let wsCheckpoint: Checkpoint | null;
|
|
175
|
+
let stateId: Slot | "finalized";
|
|
176
|
+
|
|
177
|
+
const api = getClient({baseUrl: checkpointSyncUrl}, {config});
|
|
178
|
+
if (wssCheckpoint) {
|
|
179
|
+
wsCheckpoint = getCheckpointFromArg(wssCheckpoint);
|
|
180
|
+
stateId = wsCheckpoint.epoch * SLOTS_PER_EPOCH;
|
|
181
|
+
} else {
|
|
182
|
+
// Fetch current finalized state and extract checkpoint from it
|
|
183
|
+
stateId = "finalized";
|
|
184
|
+
wsCheckpoint = null;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// getStateV2 should be available for all forks including phase0
|
|
188
|
+
const getStatePromise = api.debug.getStateV2({stateId}, {responseWireFormat: WireFormat.ssz});
|
|
189
|
+
|
|
190
|
+
const {wsStateBytes, fork} = await callFnWhenAwait(
|
|
191
|
+
getStatePromise,
|
|
192
|
+
() => logger.info("Download in progress, please wait..."),
|
|
193
|
+
GET_STATE_LOG_INTERVAL
|
|
194
|
+
).then((res) => {
|
|
195
|
+
return {wsStateBytes: res.ssz(), fork: res.meta().version};
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
const wsSlot = getStateSlotFromBytes(wsStateBytes);
|
|
199
|
+
const logData = {stateId, size: formatBytes(wsStateBytes.length)};
|
|
200
|
+
logger.info("Download completed", typeof stateId === "number" ? logData : {...logData, slot: wsSlot});
|
|
201
|
+
|
|
202
|
+
let wsState: BeaconStateAllForks;
|
|
203
|
+
if (lastDbState && lastDbValidatorsBytes) {
|
|
204
|
+
// use lastDbState to load wsState if possible to share the same state tree
|
|
205
|
+
wsState = loadState(config, lastDbState, wsStateBytes, lastDbValidatorsBytes).state;
|
|
206
|
+
} else {
|
|
207
|
+
wsState = sszTypesFor(fork).BeaconState.deserializeToViewDU(wsStateBytes);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
return {
|
|
211
|
+
wsState,
|
|
212
|
+
wsStateBytes,
|
|
213
|
+
wsCheckpoint: wsCheckpoint ?? getCheckpointFromState(wsState),
|
|
214
|
+
};
|
|
215
|
+
} catch (e) {
|
|
216
|
+
throw new Error("Unable to fetch weak subjectivity state: " + (e as Error).message);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
export function getCheckpointFromArg(checkpointStr: string): Checkpoint {
|
|
221
|
+
const checkpointRegex = /^(?:0x)?([0-9a-f]{64}):([0-9]+)$/;
|
|
222
|
+
const match = checkpointRegex.exec(checkpointStr.toLowerCase());
|
|
223
|
+
if (!match) {
|
|
224
|
+
throw new Error(`Could not parse checkpoint string: ${checkpointStr}`);
|
|
225
|
+
}
|
|
226
|
+
return {root: fromHex(match[1]), epoch: parseInt(match[2])};
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
export function getCheckpointFromState(state: BeaconStateAllForks): Checkpoint {
|
|
230
|
+
return {
|
|
231
|
+
// the correct checkpoint is based on state's slot, its latestBlockHeader's slot's epoch can be
|
|
232
|
+
// behind the state
|
|
233
|
+
epoch: computeCheckpointEpochAtStateSlot(state.slot),
|
|
234
|
+
root: getLatestBlockRoot(state),
|
|
235
|
+
};
|
|
236
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export {mainnetChainConfig as chainConfig} from "@lodestar/config/networks";
|
|
2
|
+
|
|
3
|
+
export const depositContractDeployBlock = 11052984;
|
|
4
|
+
export const genesisFileUrl =
|
|
5
|
+
"https://raw.githubusercontent.com/eth-clients/mainnet/refs/heads/main/metadata/genesis.ssz";
|
|
6
|
+
export const genesisStateRoot = "0x7e76880eb67bbdc86250aa578958e9d0675e64e714337855204fb5abaaf82c2b";
|
|
7
|
+
export const bootnodesFileUrl =
|
|
8
|
+
"https://raw.githubusercontent.com/eth-clients/mainnet/refs/heads/main/metadata/bootstrap_nodes.yaml";
|
|
9
|
+
|
|
10
|
+
export const bootEnrs = [
|
|
11
|
+
// Teku team's bootnodes
|
|
12
|
+
"enr:-Iu4QLm7bZGdAt9NSeJG0cEnJohWcQTQaI9wFLu3Q7eHIDfrI4cwtzvEW3F3VbG9XdFXlrHyFGeXPn9snTCQJ9bnMRABgmlkgnY0gmlwhAOTJQCJc2VjcDI1NmsxoQIZdZD6tDYpkpEfVo5bgiU8MGRjhcOmHGD2nErK0UKRrIN0Y3CCIyiDdWRwgiMo",
|
|
13
|
+
"enr:-Iu4QEDJ4Wa_UQNbK8Ay1hFEkXvd8psolVK6OhfTL9irqz3nbXxxWyKwEplPfkju4zduVQj6mMhUCm9R2Lc4YM5jPcIBgmlkgnY0gmlwhANrfESJc2VjcDI1NmsxoQJCYz2-nsqFpeEj6eov9HSi9QssIVIVNr0I89J1vXM9foN0Y3CCIyiDdWRwgiMo",
|
|
14
|
+
// Prylab team's bootnodes
|
|
15
|
+
"enr:-Ku4QImhMc1z8yCiNJ1TyUxdcfNucje3BGwEHzodEZUan8PherEo4sF7pPHPSIB1NNuSg5fZy7qFsjmUKs2ea1Whi0EBh2F0dG5ldHOIAAAAAAAAAACEZXRoMpD1pf1CAAAAAP__________gmlkgnY0gmlwhBLf22SJc2VjcDI1NmsxoQOVphkDqal4QzPMksc5wnpuC3gvSC8AfbFOnZY_On34wIN1ZHCCIyg",
|
|
16
|
+
"enr:-Ku4QP2xDnEtUXIjzJ_DhlCRN9SN99RYQPJL92TMlSv7U5C1YnYLjwOQHgZIUXw6c-BvRg2Yc2QsZxxoS_pPRVe0yK8Bh2F0dG5ldHOIAAAAAAAAAACEZXRoMpD1pf1CAAAAAP__________gmlkgnY0gmlwhBLf22SJc2VjcDI1NmsxoQMeFF5GrS7UZpAH2Ly84aLK-TyvH-dRo0JM1i8yygH50YN1ZHCCJxA",
|
|
17
|
+
"enr:-Ku4QPp9z1W4tAO8Ber_NQierYaOStqhDqQdOPY3bB3jDgkjcbk6YrEnVYIiCBbTxuar3CzS528d2iE7TdJsrL-dEKoBh2F0dG5ldHOIAAAAAAAAAACEZXRoMpD1pf1CAAAAAP__________gmlkgnY0gmlwhBLf22SJc2VjcDI1NmsxoQMw5fqqkw2hHC4F5HZZDPsNmPdB1Gi8JPQK7pRc9XHh-oN1ZHCCKvg",
|
|
18
|
+
// Lighthouse team's bootnodes
|
|
19
|
+
"enr:-Le4QPUXJS2BTORXxyx2Ia-9ae4YqA_JWX3ssj4E_J-3z1A-HmFGrU8BpvpqhNabayXeOZ2Nq_sbeDgtzMJpLLnXFgAChGV0aDKQtTA_KgEAAAAAIgEAAAAAAIJpZIJ2NIJpcISsaa0Zg2lwNpAkAIkHAAAAAPA8kv_-awoTiXNlY3AyNTZrMaEDHAD2JKYevx89W0CcFJFiskdcEzkH_Wdv9iW42qLK79ODdWRwgiMohHVkcDaCI4I",
|
|
20
|
+
"enr:-Le4QLHZDSvkLfqgEo8IWGG96h6mxwe_PsggC20CL3neLBjfXLGAQFOPSltZ7oP6ol54OvaNqO02Rnvb8YmDR274uq8ChGV0aDKQtTA_KgEAAAAAIgEAAAAAAIJpZIJ2NIJpcISLosQxg2lwNpAqAX4AAAAAAPA8kv_-ax65iXNlY3AyNTZrMaEDBJj7_dLFACaxBfaI8KZTh_SSJUjhyAyfshimvSqo22WDdWRwgiMohHVkcDaCI4I",
|
|
21
|
+
"enr:-Le4QH6LQrusDbAHPjU_HcKOuMeXfdEB5NJyXgHWFadfHgiySqeDyusQMvfphdYWOzuSZO9Uq2AMRJR5O4ip7OvVma8BhGV0aDKQtTA_KgEAAAAAIgEAAAAAAIJpZIJ2NIJpcISLY9ncg2lwNpAkAh8AgQIBAAAAAAAAAAmXiXNlY3AyNTZrMaECDYCZTZEksF-kmgPholqgVt8IXr-8L7Nu7YrZ7HUpgxmDdWRwgiMohHVkcDaCI4I",
|
|
22
|
+
"enr:-Le4QIqLuWybHNONr933Lk0dcMmAB5WgvGKRyDihy1wHDIVlNuuztX62W51voT4I8qD34GcTEOTmag1bcdZ_8aaT4NUBhGV0aDKQtTA_KgEAAAAAIgEAAAAAAIJpZIJ2NIJpcISLY04ng2lwNpAkAh8AgAIBAAAAAAAAAA-fiXNlY3AyNTZrMaEDscnRV6n1m-D9ID5UsURk0jsoKNXt1TIrj8uKOGW6iluDdWRwgiMohHVkcDaCI4I",
|
|
23
|
+
// EF bootnodes
|
|
24
|
+
"enr:-Ku4QHqVeJ8PPICcWk1vSn_XcSkjOkNiTg6Fmii5j6vUQgvzMc9L1goFnLKgXqBJspJjIsB91LTOleFmyWWrFVATGngBh2F0dG5ldHOIAAAAAAAAAACEZXRoMpC1MD8qAAAAAP__________gmlkgnY0gmlwhAMRHkWJc2VjcDI1NmsxoQKLVXFOhp2uX6jeT0DvvDpPcU8FWMjQdR4wMuORMhpX24N1ZHCCIyg",
|
|
25
|
+
"enr:-Ku4QG-2_Md3sZIAUebGYT6g0SMskIml77l6yR-M_JXc-UdNHCmHQeOiMLbylPejyJsdAPsTHJyjJB2sYGDLe0dn8uYBh2F0dG5ldHOIAAAAAAAAAACEZXRoMpC1MD8qAAAAAP__________gmlkgnY0gmlwhBLY-NyJc2VjcDI1NmsxoQORcM6e19T1T9gi7jxEZjk_sjVLGFscUNqAY9obgZaxbIN1ZHCCIyg",
|
|
26
|
+
"enr:-Ku4QPn5eVhcoF1opaFEvg1b6JNFD2rqVkHQ8HApOKK61OIcIXD127bKWgAtbwI7pnxx6cDyk_nI88TrZKQaGMZj0q0Bh2F0dG5ldHOIAAAAAAAAAACEZXRoMpC1MD8qAAAAAP__________gmlkgnY0gmlwhDayLMaJc2VjcDI1NmsxoQK2sBOLGcUb4AwuYzFuAVCaNHA-dy24UuEKkeFNgCVCsIN1ZHCCIyg",
|
|
27
|
+
"enr:-Ku4QEWzdnVtXc2Q0ZVigfCGggOVB2Vc1ZCPEc6j21NIFLODSJbvNaef1g4PxhPwl_3kax86YPheFUSLXPRs98vvYsoBh2F0dG5ldHOIAAAAAAAAAACEZXRoMpC1MD8qAAAAAP__________gmlkgnY0gmlwhDZBrP2Jc2VjcDI1NmsxoQM6jr8Rb1ktLEsVcKAPa08wCsKUmvoQ8khiOl_SLozf9IN1ZHCCIyg",
|
|
28
|
+
// Nimbus team's bootnodes
|
|
29
|
+
"enr:-LK4QA8FfhaAjlb_BXsXxSfiysR7R52Nhi9JBt4F8SPssu8hdE1BXQQEtVDC3qStCW60LSO7hEsVHv5zm8_6Vnjhcn0Bh2F0dG5ldHOIAAAAAAAAAACEZXRoMpC1MD8qAAAAAP__________gmlkgnY0gmlwhAN4aBKJc2VjcDI1NmsxoQJerDhsJ-KxZ8sHySMOCmTO6sHM3iCFQ6VMvLTe948MyYN0Y3CCI4yDdWRwgiOM",
|
|
30
|
+
"enr:-LK4QKWrXTpV9T78hNG6s8AM6IO4XH9kFT91uZtFg1GcsJ6dKovDOr1jtAAFPnS2lvNltkOGA9k29BUN7lFh_sjuc9QBh2F0dG5ldHOIAAAAAAAAAACEZXRoMpC1MD8qAAAAAP__________gmlkgnY0gmlwhANAdd-Jc2VjcDI1NmsxoQLQa6ai7y9PMN5hpLe5HmiJSlYzMuzP7ZhwRiwHvqNXdoN0Y3CCI4yDdWRwgiOM",
|
|
31
|
+
// Lodestar team's bootnodes
|
|
32
|
+
"enr:-IS4QPi-onjNsT5xAIAenhCGTDl4z-4UOR25Uq-3TmG4V3kwB9ljLTb_Kp1wdjHNj-H8VVLRBSSWVZo3GUe3z6k0E-IBgmlkgnY0gmlwhKB3_qGJc2VjcDI1NmsxoQMvAfgB4cJXvvXeM6WbCG86CstbSxbQBSGx31FAwVtOTYN1ZHCCIyg",
|
|
33
|
+
"enr:-KG4QCb8NC3gEM3I0okStV5BPX7Bg6ZXTYCzzbYyEXUPGcZtHmvQtiJH4C4F2jG7azTcb9pN3JlgpfxAnRVFzJ3-LykBgmlkgnY0gmlwhFPlR9KDaXA2kP6AAAAAAAAAAlBW__4my5iJc2VjcDI1NmsxoQLdUv9Eo9sxCt0tc_CheLOWnX59yHJtkBSOL7kpxdJ6GYN1ZHCCIyiEdWRwNoIjKA",
|
|
34
|
+
];
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export {sepoliaChainConfig as chainConfig} from "@lodestar/config/networks";
|
|
2
|
+
|
|
3
|
+
export const depositContractDeployBlock = 1273020;
|
|
4
|
+
export const genesisFileUrl = "https://github.com/eth-clients/sepolia/raw/main/metadata/genesis.ssz";
|
|
5
|
+
export const genesisStateRoot = "0xfb9afe32150fa39f4b346be2519a67e2a4f5efcd50a1dc192c3f6b3d013d2798";
|
|
6
|
+
export const bootnodesFileUrl =
|
|
7
|
+
"https://raw.githubusercontent.com/eth-clients/sepolia/main/metadata/bootstrap_nodes.yaml";
|
|
8
|
+
|
|
9
|
+
export const bootEnrs = [
|
|
10
|
+
"enr:-KO4QP7MmB3juk8rUjJHcUoxZDU9Np4FlW0HyDEGIjSO7GD9PbSsabu7713cWSUWKDkxIypIXg1A-6lG7ySRGOMZHeGCAmuEZXRoMpDTH2GRkAAAc___________gmlkgnY0gmlwhBSoyGOJc2VjcDI1NmsxoQNta5b_bexSSwwrGW2Re24MjfMntzFd0f2SAxQtMj3ueYN0Y3CCIyiDdWRwgiMo",
|
|
11
|
+
"enr:-Ku4QDZ_rCowZFsozeWr60WwLgOfHzv1Fz2cuMvJqN5iJzLxKtVjoIURY42X_YTokMi3IGstW5v32uSYZyGUXj9Q_IECh2F0dG5ldHOIAAAAAAAAAACEZXRoMpCo_ujukAAAaf__________gmlkgnY0gmlwhIpEe5iJc2VjcDI1NmsxoQNHTpFdaNSCEWiN_QqT396nb0PzcUpLe3OVtLph-AciBYN1ZHCCIy0",
|
|
12
|
+
"enr:-Ku4QHRyRwEPT7s0XLYzJ_EeeWvZTXBQb4UCGy1F_3m-YtCNTtDlGsCMr4UTgo4uR89pv11uM-xq4w6GKfKhqU31hTgCh2F0dG5ldHOIAAAAAAAAAACEZXRoMpCo_ujukAAAaf__________gmlkgnY0gmlwhIrFM7WJc2VjcDI1NmsxoQI4diTwChN3zAAkarf7smOHCdFb1q3DSwdiQ_Lc_FdzFIN1ZHCCIy0",
|
|
13
|
+
"enr:-Ku4QOkvvf0u5Hg4-HhY-SJmEyft77G5h3rUM8VF_e-Hag5cAma3jtmFoX4WElLAqdILCA-UWFRN1ZCDJJVuEHrFeLkDh2F0dG5ldHOIAAAAAAAAAACEZXRoMpCo_ujukAAAaf__________gmlkgnY0gmlwhJK-AWeJc2VjcDI1NmsxoQLFcT5VE_NMiIC8Ll7GypWDnQ4UEmuzD7hF_Hf4veDJwIN1ZHCCIy0",
|
|
14
|
+
"enr:-Ku4QH6tYsHKITYeHUu5kdfXgEZWI18EWk_2RtGOn1jBPlx2UlS_uF3Pm5Dx7tnjOvla_zs-wwlPgjnEOcQDWXey51QCh2F0dG5ldHOIAAAAAAAAAACEZXRoMpCo_ujukAAAaf__________gmlkgnY0gmlwhIs7Mc6Jc2VjcDI1NmsxoQIET4Mlv9YzhrYhX_H9D7aWMemUrvki6W4J2Qo0YmFMp4N1ZHCCIy0",
|
|
15
|
+
"enr:-Ku4QDmz-4c1InchGitsgNk4qzorWMiFUoaPJT4G0IiF8r2UaevrekND1o7fdoftNucirj7sFFTTn2-JdC2Ej0p1Mn8Ch2F0dG5ldHOIAAAAAAAAAACEZXRoMpCo_ujukAAAaf__________gmlkgnY0gmlwhKpA-liJc2VjcDI1NmsxoQMpHP5U1DK8O_JQU6FadmWbE42qEdcGlllR8HcSkkfWq4N1ZHCCIy0",
|
|
16
|
+
"enr:-KG4QJejf8KVtMeAPWFhN_P0c4efuwu1pZHELTveiXUeim6nKYcYcMIQpGxxdgT2Xp9h-M5pr9gn2NbbwEAtxzu50Y8BgmlkgnY0gmlwhEEVkQCDaXA2kCoBBPnAEJg4AAAAAAAAAAGJc2VjcDI1NmsxoQLEh_eVvk07AQABvLkTGBQTrrIOQkzouMgSBtNHIRUxOIN1ZHCCIyiEdWRwNoIjKA",
|
|
17
|
+
];
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import {IBeaconNodeOptions, allNamespaces, defaultOptions} from "@lodestar/beacon-node";
|
|
2
|
+
import {CliCommandOptions} from "@lodestar/utils";
|
|
3
|
+
|
|
4
|
+
const enabledAll = "*";
|
|
5
|
+
|
|
6
|
+
export type ApiArgs = {
|
|
7
|
+
"api.maxGindicesInProof"?: number;
|
|
8
|
+
"rest.namespace"?: string[];
|
|
9
|
+
"rest.cors"?: string;
|
|
10
|
+
rest: boolean;
|
|
11
|
+
"rest.address"?: string;
|
|
12
|
+
"rest.port": number;
|
|
13
|
+
"rest.headerLimit"?: number;
|
|
14
|
+
"rest.bodyLimit"?: number;
|
|
15
|
+
"rest.stacktraces"?: boolean;
|
|
16
|
+
"rest.swaggerUI"?: boolean;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export function parseArgs(args: ApiArgs): IBeaconNodeOptions["api"] {
|
|
20
|
+
return {
|
|
21
|
+
maxGindicesInProof: args["api.maxGindicesInProof"],
|
|
22
|
+
rest: {
|
|
23
|
+
api: args["rest.namespace"] as IBeaconNodeOptions["api"]["rest"]["api"],
|
|
24
|
+
cors: args["rest.cors"],
|
|
25
|
+
enabled: args.rest,
|
|
26
|
+
address: args["rest.address"],
|
|
27
|
+
port: args["rest.port"],
|
|
28
|
+
headerLimit: args["rest.headerLimit"],
|
|
29
|
+
bodyLimit: args["rest.bodyLimit"],
|
|
30
|
+
stacktraces: args["rest.stacktraces"],
|
|
31
|
+
swaggerUI: args["rest.swaggerUI"],
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export const options: CliCommandOptions<ApiArgs> = {
|
|
37
|
+
rest: {
|
|
38
|
+
type: "boolean",
|
|
39
|
+
description: "Enable/disable HTTP API",
|
|
40
|
+
default: defaultOptions.api.rest.enabled,
|
|
41
|
+
group: "api",
|
|
42
|
+
},
|
|
43
|
+
|
|
44
|
+
"api.maxGindicesInProof": {
|
|
45
|
+
hidden: true,
|
|
46
|
+
type: "number",
|
|
47
|
+
description: "Limit max number of gindices in a single proof request. DoS vector protection",
|
|
48
|
+
defaultDescription: String(defaultOptions.api.maxGindicesInProof),
|
|
49
|
+
group: "api",
|
|
50
|
+
},
|
|
51
|
+
|
|
52
|
+
"rest.namespace": {
|
|
53
|
+
type: "array",
|
|
54
|
+
choices: [...allNamespaces, enabledAll],
|
|
55
|
+
description: `Pick namespaces to expose for HTTP API. Set to '${enabledAll}' to enable all namespaces`,
|
|
56
|
+
defaultDescription: JSON.stringify(defaultOptions.api.rest.api),
|
|
57
|
+
group: "api",
|
|
58
|
+
coerce: (namespaces: string[]): string[] => {
|
|
59
|
+
// Enable all
|
|
60
|
+
if (namespaces.includes(enabledAll)) return allNamespaces;
|
|
61
|
+
// Parse ["debug,lodestar"] to ["debug", "lodestar"]
|
|
62
|
+
return namespaces.flatMap((val) => val.split(","));
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
|
|
66
|
+
"rest.cors": {
|
|
67
|
+
type: "string",
|
|
68
|
+
description: "Configures the Access-Control-Allow-Origin CORS header for HTTP API",
|
|
69
|
+
defaultDescription: defaultOptions.api.rest.cors,
|
|
70
|
+
group: "api",
|
|
71
|
+
},
|
|
72
|
+
|
|
73
|
+
"rest.address": {
|
|
74
|
+
type: "string",
|
|
75
|
+
description: "Set host for HTTP API",
|
|
76
|
+
defaultDescription: defaultOptions.api.rest.address,
|
|
77
|
+
group: "api",
|
|
78
|
+
},
|
|
79
|
+
|
|
80
|
+
"rest.port": {
|
|
81
|
+
type: "number",
|
|
82
|
+
description: "Set port for HTTP API",
|
|
83
|
+
default: defaultOptions.api.rest.port,
|
|
84
|
+
group: "api",
|
|
85
|
+
},
|
|
86
|
+
"rest.headerLimit": {
|
|
87
|
+
hidden: true,
|
|
88
|
+
type: "number",
|
|
89
|
+
description: "Defines the maximum length of request headers, in bytes, the server is allowed to accept",
|
|
90
|
+
},
|
|
91
|
+
"rest.bodyLimit": {
|
|
92
|
+
hidden: true,
|
|
93
|
+
type: "number",
|
|
94
|
+
description: "Defines the maximum payload, in bytes, the server is allowed to accept",
|
|
95
|
+
},
|
|
96
|
+
|
|
97
|
+
"rest.stacktraces": {
|
|
98
|
+
hidden: true,
|
|
99
|
+
type: "boolean",
|
|
100
|
+
description: "Return stacktraces in HTTP error responses",
|
|
101
|
+
group: "api",
|
|
102
|
+
},
|
|
103
|
+
|
|
104
|
+
"rest.swaggerUI": {
|
|
105
|
+
type: "boolean",
|
|
106
|
+
description: "Enable Swagger UI for API exploration at http://{address}:{port}/documentation",
|
|
107
|
+
default: Boolean(defaultOptions.api.rest.swaggerUI),
|
|
108
|
+
group: "api",
|
|
109
|
+
},
|
|
110
|
+
};
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import {IBeaconNodeOptions, defaultExecutionBuilderHttpOpts} from "@lodestar/beacon-node";
|
|
2
|
+
import {CliCommandOptions} from "@lodestar/utils";
|
|
3
|
+
import {YargsError} from "../../util/index.js";
|
|
4
|
+
|
|
5
|
+
export type ExecutionBuilderArgs = {
|
|
6
|
+
builder: boolean;
|
|
7
|
+
"builder.url"?: string;
|
|
8
|
+
"builder.timeout"?: number;
|
|
9
|
+
"builder.faultInspectionWindow"?: number;
|
|
10
|
+
"builder.allowedFaults"?: number;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export function parseArgs(args: ExecutionBuilderArgs): IBeaconNodeOptions["executionBuilder"] {
|
|
14
|
+
if (Array.isArray(args["builder.url"]) || args["builder.url"]?.includes(",http")) {
|
|
15
|
+
throw new YargsError(
|
|
16
|
+
"Lodestar only supports a single builder URL. External tooling like mev-boost can be used to connect to multiple builder/relays"
|
|
17
|
+
);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
return {
|
|
21
|
+
enabled: args.builder,
|
|
22
|
+
url: args["builder.url"] ?? defaultExecutionBuilderHttpOpts.url,
|
|
23
|
+
timeout: args["builder.timeout"],
|
|
24
|
+
faultInspectionWindow: args["builder.faultInspectionWindow"],
|
|
25
|
+
allowedFaults: args["builder.allowedFaults"],
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export const options: CliCommandOptions<ExecutionBuilderArgs> = {
|
|
30
|
+
builder: {
|
|
31
|
+
description: "Enable external builder",
|
|
32
|
+
type: "boolean",
|
|
33
|
+
default: defaultExecutionBuilderHttpOpts.enabled,
|
|
34
|
+
group: "builder",
|
|
35
|
+
},
|
|
36
|
+
|
|
37
|
+
"builder.url": {
|
|
38
|
+
alias: ["builder.urls"],
|
|
39
|
+
description: "Url hosting the builder API",
|
|
40
|
+
defaultDescription: defaultExecutionBuilderHttpOpts.url,
|
|
41
|
+
type: "string",
|
|
42
|
+
group: "builder",
|
|
43
|
+
},
|
|
44
|
+
|
|
45
|
+
"builder.timeout": {
|
|
46
|
+
description: "Timeout in milliseconds for builder API HTTP client",
|
|
47
|
+
type: "number",
|
|
48
|
+
defaultDescription: String(defaultExecutionBuilderHttpOpts.timeout),
|
|
49
|
+
group: "builder",
|
|
50
|
+
},
|
|
51
|
+
|
|
52
|
+
"builder.faultInspectionWindow": {
|
|
53
|
+
type: "number",
|
|
54
|
+
description: "Window to inspect missed slots for enabling/disabling builder circuit breaker",
|
|
55
|
+
group: "builder",
|
|
56
|
+
},
|
|
57
|
+
|
|
58
|
+
"builder.allowedFaults": {
|
|
59
|
+
type: "number",
|
|
60
|
+
description: "Number of missed slots allowed in the `faultInspectionWindow` for builder circuit",
|
|
61
|
+
group: "builder",
|
|
62
|
+
},
|
|
63
|
+
};
|