@chainsafe/lodestar 1.35.0-dev.e9dd48f165 → 1.35.0-dev.f45a2be721
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 +5 -3
- package/lib/cmds/validator/options.js.map +1 -1
- 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 +6 -0
- package/lib/options/beaconNodeOptions/api.d.ts.map +1 -0
- package/lib/options/beaconNodeOptions/api.js +14 -6
- package/lib/options/beaconNodeOptions/api.js.map +1 -1
- 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 +463 -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 +120 -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,232 @@
|
|
|
1
|
+
import inquirer from "inquirer";
|
|
2
|
+
import {Signature} from "@chainsafe/blst";
|
|
3
|
+
import {ApiClient, getClient} from "@lodestar/api";
|
|
4
|
+
import {BeaconConfig, createBeaconConfig} from "@lodestar/config";
|
|
5
|
+
import {
|
|
6
|
+
computeEpochAtSlot,
|
|
7
|
+
computeSigningRoot,
|
|
8
|
+
computeStartSlotAtEpoch,
|
|
9
|
+
getCurrentSlot,
|
|
10
|
+
} from "@lodestar/state-transition";
|
|
11
|
+
import {Epoch, ValidatorIndex, phase0, ssz} from "@lodestar/types";
|
|
12
|
+
import {CliCommand, fromHex, toPubkeyHex} from "@lodestar/utils";
|
|
13
|
+
import {SignableMessageType, Signer, SignerType, externalSignerPostSignature} from "@lodestar/validator";
|
|
14
|
+
import {getBeaconConfigFromArgs} from "../../config/index.js";
|
|
15
|
+
import {GlobalArgs} from "../../options/index.js";
|
|
16
|
+
import {YargsError, ensure0xPrefix, wrapError} from "../../util/index.js";
|
|
17
|
+
import {IValidatorCliArgs} from "./options.js";
|
|
18
|
+
import {getSignersFromArgs} from "./signers/index.js";
|
|
19
|
+
|
|
20
|
+
type VoluntaryExitArgs = {
|
|
21
|
+
exitEpoch?: number;
|
|
22
|
+
pubkeys?: string[];
|
|
23
|
+
yes?: boolean;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export const voluntaryExit: CliCommand<VoluntaryExitArgs, IValidatorCliArgs & GlobalArgs> = {
|
|
27
|
+
command: "voluntary-exit",
|
|
28
|
+
|
|
29
|
+
describe:
|
|
30
|
+
"Performs a voluntary exit for a given set of validators as identified via `pubkeys`. \
|
|
31
|
+
If no `pubkeys` are provided, it will exit all validators that have been imported.",
|
|
32
|
+
|
|
33
|
+
examples: [
|
|
34
|
+
{
|
|
35
|
+
command: "validator voluntary-exit --network hoodi --pubkeys 0xF00",
|
|
36
|
+
description: "Perform a voluntary exit for the validator who has a public key 0xF00",
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
command:
|
|
40
|
+
"validator voluntary-exit --network hoodi --externalSigner.url http://signer:9000 --externalSigner.fetch --pubkeys 0xF00",
|
|
41
|
+
description:
|
|
42
|
+
"Perform a voluntary exit for the validator who has a public key 0xF00 and its secret key is on an external signer",
|
|
43
|
+
},
|
|
44
|
+
],
|
|
45
|
+
|
|
46
|
+
options: {
|
|
47
|
+
exitEpoch: {
|
|
48
|
+
description:
|
|
49
|
+
"The epoch upon which to submit the voluntary exit. If no value is provided, then we default to the current epoch.",
|
|
50
|
+
type: "number",
|
|
51
|
+
},
|
|
52
|
+
|
|
53
|
+
pubkeys: {
|
|
54
|
+
description: "Public keys to exit",
|
|
55
|
+
type: "array",
|
|
56
|
+
string: true, // Ensures the pubkey string is not automatically converted to numbers
|
|
57
|
+
coerce: (pubkeys: string[]): string[] =>
|
|
58
|
+
// Parse ["0x11,0x22"] to ["0x11", "0x22"]
|
|
59
|
+
pubkeys
|
|
60
|
+
.flatMap((item) => item.split(","))
|
|
61
|
+
.map(ensure0xPrefix),
|
|
62
|
+
},
|
|
63
|
+
|
|
64
|
+
yes: {
|
|
65
|
+
description: "Skip confirmation prompt",
|
|
66
|
+
type: "boolean",
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
|
|
70
|
+
handler: async (args) => {
|
|
71
|
+
// Fetch genesisValidatorsRoot always from beacon node
|
|
72
|
+
// Do not use known networks cache, it defaults to mainnet for devnets
|
|
73
|
+
const {config: chainForkConfig, network} = getBeaconConfigFromArgs(args);
|
|
74
|
+
const client = getClient({urls: args.beaconNodes}, {config: chainForkConfig});
|
|
75
|
+
const {genesisValidatorsRoot, genesisTime} = (await client.beacon.getGenesis()).value();
|
|
76
|
+
const config = createBeaconConfig(chainForkConfig, genesisValidatorsRoot);
|
|
77
|
+
|
|
78
|
+
// Set exitEpoch to current epoch if unspecified
|
|
79
|
+
const exitEpoch = args.exitEpoch ?? computeEpochAtSlot(getCurrentSlot(config, genesisTime));
|
|
80
|
+
|
|
81
|
+
// Ignore lockfiles to allow exiting while validator client is running
|
|
82
|
+
args.force = true;
|
|
83
|
+
|
|
84
|
+
// Select signers to exit
|
|
85
|
+
const signers = await getSignersFromArgs(args, network, {logger: console, signal: new AbortController().signal});
|
|
86
|
+
if (signers.length === 0) {
|
|
87
|
+
throw new YargsError(`No validators to exit found with current args.
|
|
88
|
+
Ensure --dataDir and --network match values used when importing keys via validator import
|
|
89
|
+
or alternatively, import keys by providing --importKeystores arg to voluntary-exit command.
|
|
90
|
+
If attempting to exit validators on an external signer, make sure values are provided for
|
|
91
|
+
the necessary --externalSigner options.
|
|
92
|
+
`);
|
|
93
|
+
}
|
|
94
|
+
const signersToExit = selectSignersToExit(args, signers);
|
|
95
|
+
const validatorsToExit = await resolveValidatorIndexes(client, signersToExit);
|
|
96
|
+
|
|
97
|
+
if (!args.yes) {
|
|
98
|
+
console.log("\nWARNING: THIS IS AN IRREVERSIBLE OPERATION\n");
|
|
99
|
+
const confirmation = await inquirer.prompt<{yes: boolean}>([
|
|
100
|
+
{
|
|
101
|
+
name: "yes",
|
|
102
|
+
type: "confirm",
|
|
103
|
+
default: false,
|
|
104
|
+
message: `Confirm to exit pubkeys at epoch ${exitEpoch} from network ${network}?
|
|
105
|
+
${validatorsToExit.map((v) => `${v.pubkey} ${v.index} ${v.status}`).join("\n")}`,
|
|
106
|
+
},
|
|
107
|
+
]);
|
|
108
|
+
if (!confirmation.yes) {
|
|
109
|
+
throw new YargsError("not confirmed");
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const alreadySubmitted = [];
|
|
114
|
+
for (const [i, validatorToExit] of validatorsToExit.entries()) {
|
|
115
|
+
const {err} = await wrapError(processVoluntaryExit({config, client}, exitEpoch, validatorToExit));
|
|
116
|
+
const {pubkey, index} = validatorToExit;
|
|
117
|
+
if (err === null) {
|
|
118
|
+
console.log(`Submitted voluntary exit for ${pubkey} (${index}) ${i + 1}/${signersToExit.length}`);
|
|
119
|
+
} else {
|
|
120
|
+
if (err.message.includes("ALREADY_EXISTS")) {
|
|
121
|
+
alreadySubmitted.push(validatorToExit);
|
|
122
|
+
} else {
|
|
123
|
+
console.log(
|
|
124
|
+
`Voluntary exit errored for ${pubkey} (${index}) ${i + 1}/${signersToExit.length}: ${err.message}`
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
if (alreadySubmitted.length > 0) {
|
|
131
|
+
console.log(`Voluntary exit already submitted for ${alreadySubmitted.length}/${signersToExit.length}`);
|
|
132
|
+
for (const validatorToExit of alreadySubmitted) {
|
|
133
|
+
const {index, pubkey} = validatorToExit;
|
|
134
|
+
console.log(` - ${pubkey} (${index})`);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
},
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
async function processVoluntaryExit(
|
|
141
|
+
{config, client}: {config: BeaconConfig; client: ApiClient},
|
|
142
|
+
exitEpoch: Epoch,
|
|
143
|
+
validatorToExit: {index: ValidatorIndex; signer: Signer; pubkey: string}
|
|
144
|
+
): Promise<void> {
|
|
145
|
+
const {index, signer, pubkey} = validatorToExit;
|
|
146
|
+
const slot = computeStartSlotAtEpoch(exitEpoch);
|
|
147
|
+
const domain = config.getDomainForVoluntaryExit(slot);
|
|
148
|
+
const voluntaryExit: phase0.VoluntaryExit = {epoch: exitEpoch, validatorIndex: index};
|
|
149
|
+
const signingRoot = computeSigningRoot(ssz.phase0.VoluntaryExit, voluntaryExit, domain);
|
|
150
|
+
|
|
151
|
+
let signature: Signature;
|
|
152
|
+
switch (signer.type) {
|
|
153
|
+
case SignerType.Local:
|
|
154
|
+
signature = signer.secretKey.sign(signingRoot);
|
|
155
|
+
break;
|
|
156
|
+
case SignerType.Remote: {
|
|
157
|
+
const signatureHex = await externalSignerPostSignature(config, signer.url, pubkey, signingRoot, slot, {
|
|
158
|
+
data: voluntaryExit,
|
|
159
|
+
type: SignableMessageType.VOLUNTARY_EXIT,
|
|
160
|
+
});
|
|
161
|
+
signature = Signature.fromBytes(fromHex(signatureHex));
|
|
162
|
+
break;
|
|
163
|
+
}
|
|
164
|
+
default:
|
|
165
|
+
throw new YargsError(`Unexpected signer type for ${pubkey}`);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
const signedVoluntaryExit: phase0.SignedVoluntaryExit = {
|
|
169
|
+
message: voluntaryExit,
|
|
170
|
+
signature: signature.toBytes(),
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
(await client.beacon.submitPoolVoluntaryExit({signedVoluntaryExit})).assertOk();
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
type SignerPubkey = {signer: Signer; pubkey: string};
|
|
177
|
+
|
|
178
|
+
function selectSignersToExit(args: VoluntaryExitArgs, signers: Signer[]): SignerPubkey[] {
|
|
179
|
+
const signersWithPubkey = signers.map((signer) => ({
|
|
180
|
+
signer,
|
|
181
|
+
pubkey: getSignerPubkeyHex(signer),
|
|
182
|
+
}));
|
|
183
|
+
|
|
184
|
+
if (args.pubkeys) {
|
|
185
|
+
const signersByPubkey = new Map<string, Signer>(signersWithPubkey.map(({pubkey, signer}) => [pubkey, signer]));
|
|
186
|
+
const selectedSigners: SignerPubkey[] = [];
|
|
187
|
+
|
|
188
|
+
for (const pubkey of args.pubkeys) {
|
|
189
|
+
const signer = signersByPubkey.get(pubkey);
|
|
190
|
+
if (!signer) {
|
|
191
|
+
throw new YargsError(`Unknown pubkey ${pubkey}`);
|
|
192
|
+
}
|
|
193
|
+
selectedSigners.push({pubkey, signer});
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
return selectedSigners;
|
|
197
|
+
}
|
|
198
|
+
return signersWithPubkey;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
async function resolveValidatorIndexes(client: ApiClient, signersToExit: SignerPubkey[]) {
|
|
202
|
+
const pubkeys = signersToExit.map(({pubkey}) => pubkey);
|
|
203
|
+
|
|
204
|
+
const validators = (await client.beacon.postStateValidators({stateId: "head", validatorIds: pubkeys})).value();
|
|
205
|
+
|
|
206
|
+
const dataByPubkey = new Map(validators.map((item) => [toPubkeyHex(item.validator.pubkey), item]));
|
|
207
|
+
|
|
208
|
+
return signersToExit.map(({signer, pubkey}) => {
|
|
209
|
+
const item = dataByPubkey.get(pubkey);
|
|
210
|
+
if (!item) {
|
|
211
|
+
throw new YargsError(`Validator with pubkey ${pubkey} is unknown.
|
|
212
|
+
Re-check the pubkey submitted or wait until the validator is activated on the beacon chain to voluntary exit.`);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
return {
|
|
216
|
+
index: item.index,
|
|
217
|
+
status: item.status,
|
|
218
|
+
signer,
|
|
219
|
+
pubkey,
|
|
220
|
+
};
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
function getSignerPubkeyHex(signer: Signer): string {
|
|
225
|
+
switch (signer.type) {
|
|
226
|
+
case SignerType.Local:
|
|
227
|
+
return signer.secretKey.toPublicKey().toHex();
|
|
228
|
+
|
|
229
|
+
case SignerType.Remote:
|
|
230
|
+
return signer.pubkey;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import deepmerge from "deepmerge";
|
|
2
|
+
import {IBeaconNodeOptions, defaultOptions} from "@lodestar/beacon-node";
|
|
3
|
+
import {RecursivePartial, isPlainObject} from "@lodestar/utils";
|
|
4
|
+
|
|
5
|
+
export class BeaconNodeOptions {
|
|
6
|
+
/**
|
|
7
|
+
* Convenience class to deep merge nested options
|
|
8
|
+
*/
|
|
9
|
+
constructor(private beaconNodeOptions: RecursivePartial<IBeaconNodeOptions>) {}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Returns current options
|
|
13
|
+
*/
|
|
14
|
+
get(): RecursivePartial<IBeaconNodeOptions> {
|
|
15
|
+
return this.beaconNodeOptions;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Returns merged current options with defaultOptions
|
|
20
|
+
*/
|
|
21
|
+
getWithDefaults(): IBeaconNodeOptions {
|
|
22
|
+
return mergeBeaconNodeOptionsWithDefaults(defaultOptions, this.beaconNodeOptions);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
set(beaconNodeOptionsPartial: RecursivePartial<IBeaconNodeOptions>): void {
|
|
26
|
+
this.beaconNodeOptions = mergeBeaconNodeOptions(this.beaconNodeOptions, beaconNodeOptionsPartial);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Typesafe wrapper to merge partial IBeaconNodeOptions objects
|
|
32
|
+
*/
|
|
33
|
+
export function mergeBeaconNodeOptions(
|
|
34
|
+
...partialOptionsArr: RecursivePartial<IBeaconNodeOptions>[]
|
|
35
|
+
): RecursivePartial<IBeaconNodeOptions> {
|
|
36
|
+
return partialOptionsArr.reduce((mergedBeaconOptions, options) => {
|
|
37
|
+
// IBeaconNodeOptions contains instances so a deepmerge can only be done safely with `isMergeableObject: isPlainObject`
|
|
38
|
+
return deepmerge(mergedBeaconOptions, options, {
|
|
39
|
+
arrayMerge: overwriteTargetArrayIfItems,
|
|
40
|
+
isMergeableObject: isPlainObject,
|
|
41
|
+
});
|
|
42
|
+
}, partialOptionsArr[0]);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Typesafe wrapper to merge IBeaconNodeOptions objects
|
|
47
|
+
*/
|
|
48
|
+
export function mergeBeaconNodeOptionsWithDefaults(
|
|
49
|
+
defaultOptions: IBeaconNodeOptions,
|
|
50
|
+
...partialOptionsArr: RecursivePartial<IBeaconNodeOptions>[]
|
|
51
|
+
): IBeaconNodeOptions {
|
|
52
|
+
return mergeBeaconNodeOptions(defaultOptions, ...partialOptionsArr) as IBeaconNodeOptions;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* If override array option (source) is defined and has items
|
|
57
|
+
* replace target (original option).
|
|
58
|
+
* Example: network.localMultiaddrs has default ['/ip4/127.0.0.1/tcp/30606'] and we don't wanna append to that with cli flag
|
|
59
|
+
* as it could result in port taken
|
|
60
|
+
* @param target
|
|
61
|
+
* @param source
|
|
62
|
+
*/
|
|
63
|
+
function overwriteTargetArrayIfItems(target: unknown[], source: unknown[]): unknown[] {
|
|
64
|
+
if (source.length === 0) {
|
|
65
|
+
return target;
|
|
66
|
+
}
|
|
67
|
+
return source;
|
|
68
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ChainConfig,
|
|
3
|
+
ChainForkConfig,
|
|
4
|
+
chainConfigFromJson,
|
|
5
|
+
createChainConfig,
|
|
6
|
+
createChainForkConfig,
|
|
7
|
+
} from "@lodestar/config";
|
|
8
|
+
import {NetworkName, getNetworkBeaconParams} from "../networks/index.js";
|
|
9
|
+
import {
|
|
10
|
+
GlobalArgs,
|
|
11
|
+
ITerminalPowArgs,
|
|
12
|
+
defaultNetwork,
|
|
13
|
+
parseBeaconParamsArgs,
|
|
14
|
+
parseTerminalPowArgs,
|
|
15
|
+
} from "../options/index.js";
|
|
16
|
+
import {readFile} from "../util/index.js";
|
|
17
|
+
import {IBeaconParamsUnparsed} from "./types.js";
|
|
18
|
+
|
|
19
|
+
type BeaconParamsArgs = {
|
|
20
|
+
network?: NetworkName;
|
|
21
|
+
paramsFile?: string;
|
|
22
|
+
additionalParamsCli: IBeaconParamsUnparsed;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Convenience method to parse yargs CLI args and call getBeaconParams
|
|
27
|
+
* @see getBeaconConfig
|
|
28
|
+
*/
|
|
29
|
+
export function getBeaconConfigFromArgs(args: GlobalArgs): {config: ChainForkConfig; network: string} {
|
|
30
|
+
const config = createChainForkConfig(getBeaconParamsFromArgs(args));
|
|
31
|
+
return {
|
|
32
|
+
config,
|
|
33
|
+
network: args.network ?? config.CONFIG_NAME ?? defaultNetwork,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Convenience method to parse yargs CLI args and call getBeaconParams
|
|
39
|
+
* @see getBeaconParams
|
|
40
|
+
*/
|
|
41
|
+
export function getBeaconParamsFromArgs(args: GlobalArgs): ChainConfig {
|
|
42
|
+
return getBeaconParams({
|
|
43
|
+
network: args.network,
|
|
44
|
+
paramsFile: args.paramsFile,
|
|
45
|
+
additionalParamsCli: {
|
|
46
|
+
...parseBeaconParamsArgs(args as IBeaconParamsUnparsed),
|
|
47
|
+
...parseTerminalPowArgs(args as ITerminalPowArgs),
|
|
48
|
+
},
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Initializes BeaconConfig with params
|
|
54
|
+
* @see getBeaconParams
|
|
55
|
+
*/
|
|
56
|
+
export function getBeaconConfig(args: BeaconParamsArgs): ChainForkConfig {
|
|
57
|
+
return createChainForkConfig(getBeaconParams(args));
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Computes merged IBeaconParams type from (in order)
|
|
62
|
+
* - Network params (diff)
|
|
63
|
+
* - existing params file
|
|
64
|
+
* - CLI flags
|
|
65
|
+
*/
|
|
66
|
+
export function getBeaconParams({network, paramsFile, additionalParamsCli}: BeaconParamsArgs): ChainConfig {
|
|
67
|
+
// Default network params
|
|
68
|
+
const networkParams: Partial<ChainConfig> = network ? getNetworkBeaconParams(network) : {};
|
|
69
|
+
// Existing user custom params from file
|
|
70
|
+
const fileParams: Partial<ChainConfig> = paramsFile ? parsePartialChainConfigJson(readBeaconParams(paramsFile)) : {};
|
|
71
|
+
// Params from CLI flags
|
|
72
|
+
const cliParams: Partial<ChainConfig> = parsePartialChainConfigJson(additionalParamsCli);
|
|
73
|
+
|
|
74
|
+
return createChainConfig({
|
|
75
|
+
...networkParams,
|
|
76
|
+
...fileParams,
|
|
77
|
+
...cliParams,
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function readBeaconParams(filepath: string): IBeaconParamsUnparsed {
|
|
82
|
+
return readFile(filepath) ?? {};
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export function parsePartialChainConfigJson(input: Record<string, unknown>): Partial<ChainConfig> {
|
|
86
|
+
return chainConfigFromJson(input);
|
|
87
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import {
|
|
2
|
+
privateKeyFromProtobuf,
|
|
3
|
+
privateKeyToProtobuf,
|
|
4
|
+
publicKeyFromProtobuf,
|
|
5
|
+
publicKeyToProtobuf,
|
|
6
|
+
} from "@libp2p/crypto/keys";
|
|
7
|
+
import type {PrivateKey} from "@libp2p/interface";
|
|
8
|
+
import {peerIdFromPrivateKey, peerIdFromString} from "@libp2p/peer-id";
|
|
9
|
+
import {fromString as uint8ArrayFromString} from "uint8arrays/from-string";
|
|
10
|
+
import {toString as uint8ArrayToString} from "uint8arrays/to-string";
|
|
11
|
+
import {readFile, writeFile600Perm} from "../util/index.js";
|
|
12
|
+
|
|
13
|
+
// Peer id to / from JSON taken from peer-id-factory
|
|
14
|
+
// See https://github.com/libp2p/js-libp2p-peer-id/pull/9 for more details
|
|
15
|
+
|
|
16
|
+
// after libp2p 2.0, PeerId no longer contains a private key
|
|
17
|
+
// but we retain a semi-backwards-compatible on-disk format
|
|
18
|
+
// Note: all properties are required
|
|
19
|
+
export type PeerIdJSON = {id: string; pubKey: string; privKey: string};
|
|
20
|
+
|
|
21
|
+
export function exportToJSON(privateKey: PrivateKey): PeerIdJSON {
|
|
22
|
+
const publicKey = privateKey.publicKey;
|
|
23
|
+
const peerId = peerIdFromPrivateKey(privateKey);
|
|
24
|
+
return {
|
|
25
|
+
id: peerId.toString(),
|
|
26
|
+
pubKey: uint8ArrayToString(publicKeyToProtobuf(publicKey), "base64pad"),
|
|
27
|
+
privKey: uint8ArrayToString(privateKeyToProtobuf(privateKey), "base64pad"),
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function createFromJSON(obj: PeerIdJSON): PrivateKey {
|
|
32
|
+
const privateKey = privateKeyFromProtobuf(uint8ArrayFromString(obj.privKey, "base64pad"));
|
|
33
|
+
const publicKey = publicKeyFromProtobuf(uint8ArrayFromString(obj.pubKey, "base64pad"));
|
|
34
|
+
const peerId = peerIdFromString(obj.id);
|
|
35
|
+
if (!publicKey.equals(privateKey.publicKey)) {
|
|
36
|
+
throw new Error("Public key does not match private key");
|
|
37
|
+
}
|
|
38
|
+
if (!peerId.equals(peerIdFromPrivateKey(privateKey))) {
|
|
39
|
+
throw new Error("Peer ID does not match private key");
|
|
40
|
+
}
|
|
41
|
+
return privateKey;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export function writePrivateKey(filepath: string, privateKey: PrivateKey): void {
|
|
45
|
+
writeFile600Perm(filepath, exportToJSON(privateKey));
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export function readPrivateKey(filepath: string): PrivateKey {
|
|
49
|
+
return createFromJSON(readFile(filepath));
|
|
50
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// MUST import first to apply preset from args and set ssz hasher
|
|
4
|
+
import "./applyPreset.js";
|
|
5
|
+
|
|
6
|
+
import {getLodestarCli, yarg} from "./cli.js";
|
|
7
|
+
import {YargsError} from "./util/index.js";
|
|
8
|
+
import "source-map-support/register.js";
|
|
9
|
+
|
|
10
|
+
const lodestar = getLodestarCli();
|
|
11
|
+
|
|
12
|
+
void lodestar
|
|
13
|
+
.fail((msg, err) => {
|
|
14
|
+
if (msg?.includes("Not enough non-option arguments")) {
|
|
15
|
+
// Show command help message when no command is provided
|
|
16
|
+
yarg.showHelp();
|
|
17
|
+
console.log("\n");
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const errorMessage =
|
|
21
|
+
err !== undefined ? (err instanceof YargsError ? err.message : err.stack) : msg || "Unknown error";
|
|
22
|
+
|
|
23
|
+
console.error(` ✖ ${errorMessage}\n`);
|
|
24
|
+
process.exit(1);
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
// Execute CLI
|
|
28
|
+
.parse();
|
|
File without changes
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export {chiadoChainConfig as chainConfig} from "@lodestar/config/networks";
|
|
2
|
+
|
|
3
|
+
// eth1.providerUrls suggestion: https://rpc.chiado.gnosis.gateway.fm
|
|
4
|
+
export const depositContractDeployBlock = 155435;
|
|
5
|
+
export const genesisFileUrl = "https://raw.githubusercontent.com/gnosischain/configs/main/chiado/genesis.ssz";
|
|
6
|
+
export const genesisStateRoot = "0xa48419160f8f146ecaa53d12a5d6e1e6af414a328afdc56b60d5002bb472a077";
|
|
7
|
+
export const bootnodesFileUrl = "https://raw.githubusercontent.com/gnosischain/configs/main/chiado/bootnodes.yaml";
|
|
8
|
+
|
|
9
|
+
export const bootEnrs = [
|
|
10
|
+
"enr:-L64QOijsdi9aVIawMb5h5PWueaPM9Ai6P17GNPFlHzz7MGJQ8tFMdYrEx8WQitNKLG924g2Q9cCdzg54M0UtKa3QIKCMxaHYXR0bmV0c4j__________4RldGgykDE2cEMCAABv__________-CaWSCdjSCaXCEi5AaWYlzZWNwMjU2azGhA8CjTkD4m1s8FbKCN18LgqlYcE65jrT148vFtwd9U62SiHN5bmNuZXRzD4N0Y3CCIyiDdWRwgiMo",
|
|
11
|
+
"enr:-L64QKYKGQj5ybkfBxyFU5IEVzP7oJkGHJlie4W8BCGAYEi4P0mmMksaasiYF789mVW_AxYVNVFUjg9CyzmdvpyWQ1KCMlmHYXR0bmV0c4j__________4RldGgykDE2cEMCAABv__________-CaWSCdjSCaXCEi5CtNolzZWNwMjU2azGhAuA7BAwIijy1z81AO9nz_MOukA1ER68rGA67PYQ5pF1qiHN5bmNuZXRzD4N0Y3CCIyiDdWRwgiMo",
|
|
12
|
+
"enr:-Ly4QJJUnV9BxP_rw2Bv7E9iyw4sYS2b4OQZIf4Mu_cA6FljJvOeSTQiCUpbZhZjR4R0VseBhdTzrLrlHrAuu_OeZqgJh2F0dG5ldHOI__________-EZXRoMpAxNnBDAgAAb___________gmlkgnY0gmlwhIuQGnOJc2VjcDI1NmsxoQPT_u3IjDtB2r-nveH5DhUmlM8F2IgLyxhmwmqW4L5k3ohzeW5jbmV0cw-DdGNwgiMog3VkcIIjKA",
|
|
13
|
+
"enr:-MK4QCkOyqOTPX1_-F-5XVFjPclDUc0fj3EeR8FJ5-hZjv6ARuGlFspM0DtioHn1r6YPUXkOg2g3x6EbeeKdsrvVBYmGAYQKrixeh2F0dG5ldHOIAAAAAAAAAACEZXRoMpAxNnBDAgAAb___________gmlkgnY0gmlwhIuQGlWJc2VjcDI1NmsxoQKdW3-DgLExBkpLGMRtuM88wW_gZkC7Yeg0stYDTrlynYhzeW5jbmV0cwCDdGNwgiMog3VkcIIjKA",
|
|
14
|
+
"enr:-Ly4QLYLNqrjvSxD3lpAPBUNlxa6cIbe79JqLZLFcZZjWoCjZcw-85agLUErHiygG2weRSCLnd5V460qTbLbwJQsfZkoh2F0dG5ldHOI__________-EZXRoMpAxNnBDAgAAb___________gmlkgnY0gmlwhKq7mu-Jc2VjcDI1NmsxoQP900YAYa9kdvzlSKGjVo-F3XVzATjOYp3BsjLjSophO4hzeW5jbmV0cw-DdGNwgiMog3VkcIIjKA",
|
|
15
|
+
"enr:-Ly4QCGeYvTCNOGKi0mKRUd45rLj96b4pH98qG7B9TCUGXGpHZALtaL2-XfjASQyhbCqENccI4PGXVqYTIehNT9KJMQgh2F0dG5ldHOI__________-EZXRoMpAxNnBDAgAAb___________gmlkgnY0gmlwhIuQrVSJc2VjcDI1NmsxoQP9iDchx2PGl3JyJ29B9fhLCvVMN6n23pPAIIeFV-sHOIhzeW5jbmV0cw-DdGNwgiMog3VkcIIjKA",
|
|
16
|
+
"enr:-Ly4QAtr21x5Ps7HYhdZkIBRBgcBkvlIfEel1YNjtFWf4cV3au2LgBGICz9PtEs9-p2HUl_eME8m1WImxTxSB3AkCMwBh2F0dG5ldHOIAAAAAAAAAACEZXRoMpAxNnBDAgAAb___________gmlkgnY0gmlwhANHhOeJc2VjcDI1NmsxoQNLp1QPV8-pyMCohOtj6xGtSBM_GtVTqzlbvNsCF4ezkYhzeW5jbmV0cwCDdGNwgiMog3VkcIIjKA",
|
|
17
|
+
"enr:-Ly4QLgn8Bx6faigkKUGZQvd1HDToV2FAxZIiENK-lczruzQb90qJK-4E65ADly0s4__dQOW7IkLMW7ZAyJy2vtiLy8Bh2F0dG5ldHOIAAAAAAAAAACEZXRoMpAxNnBDAgAAb___________gmlkgnY0gmlwhANFIw2Jc2VjcDI1NmsxoQMa-fWEy9UJHfOl_lix3wdY5qust78sHAqZnWwEiyqKgYhzeW5jbmV0cwCDdGNwgiMog3VkcIIjKA",
|
|
18
|
+
"enr:-KG4QF7z4LUdMfgwvh-fS-MDv_1hPSUCqGfyOWGLNJuoBHKFAMSHz8geQn8v3qDDbuSQKud3WIAjKqR4gqJoLBUEJ08ZhGV0aDKQDc1ElgAAAG___________4JpZIJ2NIJpcIQjzq5ciXNlY3AyNTZrMaECt7YO363pV54d3QdgnluL5kxzhCR_k0yM9C-G6bqMGoKDdGNwgiMog3VkcIIjKA",
|
|
19
|
+
"enr:-LK4QCUTEmZrT1AgCKdyVgwnHL5J0VSoxsyjruAtwo-owBTBVEOyAnQRVNXlcW5aL-ycntk5oHDrKCR-DXZAlUAKpjEBh2F0dG5ldHOIAAAAAAAAAACEZXRoMpCdM7Z1BAAAb___________gmlkgnY0gmlwhCPSfheJc2VjcDI1NmsxoQNpdf8U9pzsU9m6Hzgd1rmTI-On-QImJnkZBGqDp4org4N0Y3CCIyiDdWRwgiMo",
|
|
20
|
+
];
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import {ChainConfig} from "@lodestar/config";
|
|
2
|
+
import {mainnetChainConfig, minimalChainConfig} from "@lodestar/config/configs";
|
|
3
|
+
import {gnosisChainConfig} from "@lodestar/config/networks";
|
|
4
|
+
import {ACTIVE_PRESET, PresetName} from "@lodestar/params";
|
|
5
|
+
|
|
6
|
+
let chainConfig: ChainConfig;
|
|
7
|
+
switch (ACTIVE_PRESET) {
|
|
8
|
+
case PresetName.mainnet:
|
|
9
|
+
chainConfig = mainnetChainConfig;
|
|
10
|
+
break;
|
|
11
|
+
case PresetName.minimal:
|
|
12
|
+
chainConfig = minimalChainConfig;
|
|
13
|
+
break;
|
|
14
|
+
case PresetName.gnosis:
|
|
15
|
+
chainConfig = gnosisChainConfig;
|
|
16
|
+
break;
|
|
17
|
+
default:
|
|
18
|
+
throw Error(`Preset ${ACTIVE_PRESET} not supported with dev command`);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export {chainConfig};
|
|
22
|
+
|
|
23
|
+
export const depositContractDeployBlock = 0;
|
|
24
|
+
export const genesisFileUrl = null;
|
|
25
|
+
export const genesisStateRoot = null;
|
|
26
|
+
export const bootnodesFileUrl = null;
|
|
27
|
+
export const bootEnrs = [];
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export {ephemeryChainConfig as chainConfig} from "@lodestar/config/networks";
|
|
2
|
+
|
|
3
|
+
export const depositContractDeployBlock = 0;
|
|
4
|
+
export const genesisFileUrl = "https://ephemery.dev/latest/genesis.ssz";
|
|
5
|
+
export const genesisStateRoot = null;
|
|
6
|
+
export const bootnodesFileUrl = "https://ephemery.dev/latest/bootstrap_nodes.txt";
|
|
7
|
+
|
|
8
|
+
// Pick from above file
|
|
9
|
+
export const bootEnrs = [];
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export {gnosisChainConfig as chainConfig} from "@lodestar/config/networks";
|
|
2
|
+
|
|
3
|
+
// eth1.providerUrls suggestion: https://rpc.gnosischain.com
|
|
4
|
+
export const depositContractDeployBlock = 19469077;
|
|
5
|
+
export const genesisFileUrl = "https://raw.githubusercontent.com/gnosischain/configs/main/mainnet/genesis.ssz";
|
|
6
|
+
export const genesisStateRoot = "0x1511578d6de70428bf3529ab92102f21070694cb205443437fae359a7f220537";
|
|
7
|
+
export const bootnodesFileUrl = "https://raw.githubusercontent.com/gnosischain/configs/main/mainnet/bootnodes.yaml";
|
|
8
|
+
|
|
9
|
+
export const bootEnrs = [
|
|
10
|
+
"enr:-Ly4QIAhiTHk6JdVhCdiLwT83wAolUFo5J4nI5HrF7-zJO_QEw3cmEGxC1jvqNNUN64Vu-xxqDKSM528vKRNCehZAfEBh2F0dG5ldHOIAAAAAAAAAACEZXRoMpCCS-QxAgAAZP__________gmlkgnY0gmlwhEFtZ5SJc2VjcDI1NmsxoQJwgL5C-30E8RJmW8gCb7sfwWvvfre7wGcCeV4X1G2wJYhzeW5jbmV0cwCDdGNwgiMog3VkcIIjKA",
|
|
11
|
+
"enr:-Ly4QDhEjlkf8fwO5uWAadexy88GXZneTuUCIPHhv98v8ZfXMtC0S1S_8soiT0CMEgoeLe9Db01dtkFQUnA9YcnYC_8Bh2F0dG5ldHOIAAAAAAAAAACEZXRoMpCCS-QxAgAAZP__________gmlkgnY0gmlwhEFtZ5WJc2VjcDI1NmsxoQMRSho89q2GKx_l2FZhR1RmnSiQr6o_9hfXfQUuW6bjMohzeW5jbmV0cwCDdGNwgiMog3VkcIIjKA",
|
|
12
|
+
"enr:-Ly4QLKgv5M2D4DYJgo6s4NG_K4zu4sk5HOLCfGCdtgoezsbfRbfGpQ4iSd31M88ec3DHA5FWVbkgIas9EaJeXia0nwBh2F0dG5ldHOIAAAAAAAAAACEZXRoMpCCS-QxAgAAZP__________gmlkgnY0gmlwhI1eYRaJc2VjcDI1NmsxoQLpK_A47iNBkVjka9Mde1F-Kie-R0sq97MCNKCxt2HwOIhzeW5jbmV0cwCDdGNwgiMog3VkcIIjKA",
|
|
13
|
+
"enr:-Ly4QF_0qvji6xqXrhQEhwJR1W9h5dXV7ZjVCN_NlosKxcgZW6emAfB_KXxEiPgKr_-CZG8CWvTiojEohG1ewF7P368Bh2F0dG5ldHOIAAAAAAAAAACEZXRoMpCCS-QxAgAAZP__________gmlkgnY0gmlwhI1eYUqJc2VjcDI1NmsxoQIpNRUT6llrXqEbjkAodsZOyWv8fxQkyQtSvH4sg2D7n4hzeW5jbmV0cwCDdGNwgiMog3VkcIIjKA",
|
|
14
|
+
"enr:-Ly4QCD5D99p36WafgTSxB6kY7D2V1ca71C49J4VWI2c8UZCCPYBvNRWiv0-HxOcbpuUdwPVhyWQCYm1yq2ZH0ukCbQBh2F0dG5ldHOIAAAAAAAAAACEZXRoMpCCS-QxAgAAZP__________gmlkgnY0gmlwhI1eYVSJc2VjcDI1NmsxoQJJMSV8iSZ8zvkgbi8cjIGEUVJeekLqT0LQha_co-siT4hzeW5jbmV0cwCDdGNwgiMog3VkcIIjKA",
|
|
15
|
+
"enr:-KK4QKXJq1QOVWuJAGige4uaT8LRPQGCVRf3lH3pxjaVScMRUfFW1eiiaz8RwOAYvw33D4EX-uASGJ5QVqVCqwccxa-Bi4RldGgykCGm-DYDAABk__________-CaWSCdjSCaXCEM0QnzolzZWNwMjU2azGhAhNvrRkpuK4MWTf3WqiOXSOePL8Zc-wKVpZ9FQx_BDadg3RjcIIjKIN1ZHCCIyg",
|
|
16
|
+
"enr:-LO4QO87Rn2ejN3SZdXkx7kv8m11EZ3KWWqoIN5oXwQ7iXR9CVGd1dmSyWxOL1PGsdIqeMf66OZj4QGEJckSi6okCdWBpIdhdHRuZXRziAAAAABgAAAAhGV0aDKQPr_UhAQAAGT__________4JpZIJ2NIJpcIQj0iX1iXNlY3AyNTZrMaEDd-_eqFlWWJrUfEp8RhKT9NxdYaZoLHvsp3bbejPyOoeDdGNwgiMog3VkcIIjKA",
|
|
17
|
+
"enr:-LK4QIJUAxX9uNgW4ACkq8AixjnSTcs9sClbEtWRq9F8Uy9OEExsr4ecpBTYpxX66cMk6pUHejCSX3wZkK2pOCCHWHEBh2F0dG5ldHOIAAAAAAAAAACEZXRoMpA-v9SEBAAAZP__________gmlkgnY0gmlwhCPSnDuJc2VjcDI1NmsxoQNuaAjFE-ANkH3pbeBdPiEIwjR5kxFuKaBWxHkqFuPz5IN0Y3CCIyiDdWRwgiMo",
|
|
18
|
+
];
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export {holeskyChainConfig as chainConfig} from "@lodestar/config/networks";
|
|
2
|
+
|
|
3
|
+
export const depositContractDeployBlock = 0;
|
|
4
|
+
export const genesisFileUrl = "https://media.githubusercontent.com/media/eth-clients/holesky/main/metadata/genesis.ssz";
|
|
5
|
+
export const genesisStateRoot = "0x0ea3f6f9515823b59c863454675fefcd1d8b4f2dbe454db166206a41fda060a0";
|
|
6
|
+
export const bootnodesFileUrl =
|
|
7
|
+
"https://raw.githubusercontent.com/eth-clients/holesky/main/metadata/bootstrap_nodes.yaml";
|
|
8
|
+
|
|
9
|
+
export const bootEnrs = [
|
|
10
|
+
"enr:-Ku4QFo-9q73SspYI8cac_4kTX7yF800VXqJW4Lj3HkIkb5CMqFLxciNHePmMt4XdJzHvhrCC5ADI4D_GkAsxGJRLnQBh2F0dG5ldHOIAAAAAAAAAACEZXRoMpAhnTT-AQFwAP__________gmlkgnY0gmlwhLKAiOmJc2VjcDI1NmsxoQORcM6e19T1T9gi7jxEZjk_sjVLGFscUNqAY9obgZaxbIN1ZHCCIyk",
|
|
11
|
+
"enr:-Ku4QPG7F72mbKx3gEQEx07wpYYusGDh-ni6SNkLvOS-hhN-BxIggN7tKlmalb0L5JPoAfqD-akTZ-gX06hFeBEz4WoBh2F0dG5ldHOIAAAAAAAAAACEZXRoMpAhnTT-AQFwAP__________gmlkgnY0gmlwhJK-DYCJc2VjcDI1NmsxoQKLVXFOhp2uX6jeT0DvvDpPcU8FWMjQdR4wMuORMhpX24N1ZHCCIyk",
|
|
12
|
+
"enr:-LK4QPxe-mDiSOtEB_Y82ozvxn9aQM07Ui8A-vQHNgYGMMthfsfOabaaTHhhJHFCBQQVRjBww_A5bM1rf8MlkJU_l68Eh2F0dG5ldHOIAADAAAAAAACEZXRoMpBpt9l0BAFwAAABAAAAAAAAgmlkgnY0gmlwhLKAiOmJc2VjcDI1NmsxoQJu6T9pclPObAzEVQ53DpVQqjadmVxdTLL-J3h9NFoCeIN0Y3CCIyiDdWRwgiMo",
|
|
13
|
+
"enr:-Ly4QGbOw4xNel5EhmDsJJ-QhC9XycWtsetnWoZ0uRy381GHdHsNHJiCwDTOkb3S1Ade0SFQkWJX_pgb3g8Jfh93rvMBh2F0dG5ldHOIAAAAAAAAAACEZXRoMpBpt9l0BAFwAAABAAAAAAAAgmlkgnY0gmlwhJK-DYCJc2VjcDI1NmsxoQOxKv9sv3zKF8GDewgFGGHKP5HCZZpPpTrwl9eXKAWGxIhzeW5jbmV0cwCDdGNwgiMog3VkcIIjKA",
|
|
14
|
+
"enr:-KO4QCi3ZY4TM5KL7bAG6laSYiYelDWu0crvUjCXlyc_cwEfUpMIuARuMJYGxWe-UYYpHEw_aBbZ1u-4tHQ8imyI5uaCAsGEZXRoMpBprg6ZBQFwAP__________gmlkgnY0gmlwhKyuI_mJc2VjcDI1NmsxoQLoFG5-vuNX6N49vnkTBaA3ZsBDF8B30DGqWOGtRGz5w4N0Y3CCIyiDdWRwgiMo",
|
|
15
|
+
"enr:-Le4QLoE1wFHSlGcm48a9ZESb_MRLqPPu6G0vHqu4MaUcQNDHS69tsy-zkN0K6pglyzX8m24mkb-LtBcbjAYdP1uxm4BhGV0aDKQabfZdAQBcAAAAQAAAAAAAIJpZIJ2NIJpcIQ5gR6Wg2lwNpAgAUHQBwEQAAAAAAAAADR-iXNlY3AyNTZrMaEDPMSNdcL92uNIyCsS177Z6KTXlbZakQqxv3aQcWawNXeDdWRwgiMohHVkcDaCI4I",
|
|
16
|
+
"enr:-KG4QC9Wm32mtzB5Fbj2ri2TEKglHmIWgvwTQCvNHBopuwpNAi1X6qOsBg_Z1-Bee-kfSrhzUQZSgDUyfH5outUprtoBgmlkgnY0gmlwhHEel3eDaXA2kP6AAAAAAAAAAlBW__4Srr-Jc2VjcDI1NmsxoQO7KE63Z4eSI55S1Yn7q9_xFkJ1Wt-a3LgiXuKGs19s0YN1ZHCCIyiEdWRwNoIjKA",
|
|
17
|
+
];
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export {hoodiChainConfig as chainConfig} from "@lodestar/config/networks";
|
|
2
|
+
|
|
3
|
+
export const depositContractDeployBlock = 0;
|
|
4
|
+
export const genesisFileUrl = "https://media.githubusercontent.com/media/eth-clients/hoodi/main/metadata/genesis.ssz";
|
|
5
|
+
export const genesisStateRoot = "0x2683ebc120f91f740c7bed4c866672d01e1ba51b4cc360297138465ee5df40f0";
|
|
6
|
+
export const bootnodesFileUrl =
|
|
7
|
+
"https://raw.githubusercontent.com/eth-clients/hoodi/main/metadata/bootstrap_nodes.yaml";
|
|
8
|
+
|
|
9
|
+
export const bootEnrs = [
|
|
10
|
+
"enr:-Mq4QLkmuSwbGBUph1r7iHopzRpdqE-gcm5LNZfcE-6T37OCZbRHi22bXZkaqnZ6XdIyEDTelnkmMEQB8w6NbnJUt9GGAZWaowaYh2F0dG5ldHOIABgAAAAAAACEZXRoMpDS8Zl_YAAJEAAIAAAAAAAAgmlkgnY0gmlwhNEmfKCEcXVpY4IyyIlzZWNwMjU2azGhA0hGa4jZJZYQAS-z6ZFK-m4GCFnWS8wfjO0bpSQn6hyEiHN5bmNuZXRzAIN0Y3CCIyiDdWRwgiMo",
|
|
11
|
+
"enr:-Ku4QLVumWTwyOUVS4ajqq8ZuZz2ik6t3Gtq0Ozxqecj0qNZWpMnudcvTs-4jrlwYRQMQwBS8Pvtmu4ZPP2Lx3i2t7YBh2F0dG5ldHOIAAAAAAAAAACEZXRoMpBd9cEGEAAJEP__________gmlkgnY0gmlwhNEmfKCJc2VjcDI1NmsxoQLdRlI8aCa_ELwTJhVN8k7km7IDc3pYu-FMYBs5_FiigIN1ZHCCIyk",
|
|
12
|
+
"enr:-LK4QAYuLujoiaqCAs0-qNWj9oFws1B4iy-Hff1bRB7wpQCYSS-IIMxLWCn7sWloTJzC1SiH8Y7lMQ5I36ynGV1ASj4Eh2F0dG5ldHOIYAAAAAAAAACEZXRoMpDS8Zl_YAAJEAAIAAAAAAAAgmlkgnY0gmlwhIbRilSJc2VjcDI1NmsxoQOmI5MlAu3f5WEThAYOqoygpS2wYn0XS5NV2aYq7T0a04N0Y3CCIyiDdWRwgiMo",
|
|
13
|
+
"enr:-Ku4QIC89sMC0o-irosD4_23lJJ4qCGOvdUz7SmoShWx0k6AaxCFTKviEHa-sa7-EzsiXpDp0qP0xzX6nKdXJX3X-IQBh2F0dG5ldHOIAAAAAAAAAACEZXRoMpBd9cEGEAAJEP__________gmlkgnY0gmlwhIbRilSJc2VjcDI1NmsxoQK_m0f1DzDc9Cjrspm36zuRa7072HSiMGYWLsKiVSbP34N1ZHCCIyk",
|
|
14
|
+
"enr:-Ku4QNkWjw5tNzo8DtWqKm7CnDdIq_y7xppD6c1EZSwjB8rMOkSFA1wJPLoKrq5UvA7wcxIotH6Usx3PAugEN2JMncIBh2F0dG5ldHOIAAAAAAAAAACEZXRoMpBd9cEGEAAJEP__________gmlkgnY0gmlwhIbHuBeJc2VjcDI1NmsxoQP3FwrhFYB60djwRjAoOjttq6du94DtkQuaN99wvgqaIYN1ZHCCIyk",
|
|
15
|
+
"enr:-OS4QMJGE13xEROqvKN1xnnt7U-noc51VXyM6wFMuL9LMhQDfo1p1dF_zFdS4OsnXz_vIYk-nQWnqJMWRDKvkSK6_CwDh2F0dG5ldHOIAAAAADAAAACGY2xpZW502IpMaWdodGhvdXNljDcuMC4wLWJldGEuM4RldGgykNLxmX9gAAkQAAgAAAAAAACCaWSCdjSCaXCEhse4F4RxdWljgiMqiXNlY3AyNTZrMaECef77P8k5l3PC_raLw42OAzdXfxeQ-58BJriNaqiRGJSIc3luY25ldHMAg3RjcIIjKIN1ZHCCIyg",
|
|
16
|
+
];
|