Skip to content

Commit 100ab48

Browse files
authored
feat: allow multiple mnemonic index ranges in validator setup (#8731)
**Motivation** - @philknows wants **Description** - allow multiple index ranges in validator - this should only be used in testing and not in production
1 parent c630c55 commit 100ab48

File tree

3 files changed

+29
-13
lines changed

3 files changed

+29
-13
lines changed

packages/cli/src/cmds/dev/options.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
import {CliCommandOptions, CliOptionDefinition} from "@lodestar/utils";
22
import {NetworkName} from "../../networks/index.js";
33
import {beaconNodeOptions, globalOptions} from "../../options/index.js";
4+
import {parseRange} from "../../util/format.ts";
45
import {BeaconArgs, beaconOptions} from "../beacon/options.js";
56
import {IValidatorCliArgs, validatorOptions} from "../validator/options.js";
67

78
type IDevOwnArgs = {
89
genesisEth1Hash?: string;
910
genesisValidators: number;
10-
startValidators?: string;
11+
startValidators?: number[];
1112
genesisTime?: number;
1213
reset?: boolean;
1314
dumpTestnetFiles?: string;
@@ -29,8 +30,13 @@ const devOwnOptions: CliCommandOptions<IDevOwnArgs> = {
2930
},
3031

3132
startValidators: {
32-
description: "Start interop validators in inclusive range with notation '0..7'",
33-
type: "string",
33+
description: "Start interop validators in inclusive range(s) with notation '0..7'",
34+
type: "array",
35+
coerce: (indexes: string[]): number[] =>
36+
// Parse ["11..13,15..17"] to ["11..13", "15..17"]
37+
indexes
38+
.flatMap((item) => item.split(","))
39+
.flatMap(parseRange),
3440
group: "dev",
3541
},
3642

packages/cli/src/cmds/validator/options.ts

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import {CliCommandOptions} from "@lodestar/utils";
33
import {defaultOptions} from "@lodestar/validator";
44
import {coerceCors, enabledAllBashFriendly} from "../../options/beaconNodeOptions/api.js";
55
import {LogArgs, logOptions} from "../../options/logOptions.js";
6-
import {ensure0xPrefix} from "../../util/index.js";
6+
import {ensure0xPrefix, parseRange} from "../../util/index.js";
77
import {keymanagerRestApiServerOptsDefault} from "./keymanager/server.js";
88
import {defaultAccountPaths, defaultValidatorPaths} from "./paths.js";
99

@@ -70,9 +70,9 @@ export type IValidatorCliArgs = AccountValidatorArgs &
7070

7171
distributed?: boolean;
7272

73-
interopIndexes?: string;
73+
interopIndexes?: number[];
7474
fromMnemonic?: string;
75-
mnemonicIndexes?: string;
75+
mnemonicIndexes?: number[];
7676

7777
metrics?: boolean;
7878
"metrics.port"?: number;
@@ -453,8 +453,13 @@ export const validatorOptions: CliCommandOptions<IValidatorCliArgs> = {
453453

454454
interopIndexes: {
455455
hidden: true,
456-
description: "Range (inclusive) of interop key indexes to validate with: 0..16",
457-
type: "string",
456+
description: "Range(s) (inclusive) of interop key indexes to validate with: 0..16",
457+
type: "array",
458+
coerce: (indexes: string[]): number[] =>
459+
// Parse ["11..13,15..17"] to ["11..13", "15..17"]
460+
indexes
461+
.flatMap((item) => item.split(","))
462+
.flatMap(parseRange),
458463
},
459464

460465
fromMnemonic: {
@@ -465,7 +470,12 @@ export const validatorOptions: CliCommandOptions<IValidatorCliArgs> = {
465470

466471
mnemonicIndexes: {
467472
hidden: true,
468-
description: "UNSAFE. Range (inclusive) of mnemonic key indexes to validate with: 0..16",
469-
type: "string",
473+
description: "UNSAFE. Range(s) (inclusive) of mnemonic key indexes to validate with: 0..16",
474+
type: "array",
475+
coerce: (indexes: string[]): number[] =>
476+
// Parse ["11..13,15..17"] to ["11..13", "15..17"]
477+
indexes
478+
.flatMap((item) => item.split(","))
479+
.flatMap(parseRange),
470480
},
471481
};

packages/cli/src/cmds/validator/signers/index.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import {interopSecretKey} from "@lodestar/state-transition";
55
import {LogLevel, Logger, isValidHttpUrl} from "@lodestar/utils";
66
import {Signer, SignerType, externalSignerGetKeys} from "@lodestar/validator";
77
import {GlobalArgs, defaultNetwork} from "../../../options/index.js";
8-
import {YargsError, assertValidPubkeysHex, parseRange} from "../../../util/index.js";
8+
import {YargsError, assertValidPubkeysHex} from "../../../util/index.js";
99
import {showProgress} from "../../../util/progress.js";
1010
import {decryptKeystoreDefinitions} from "../keymanager/decryptKeystoreDefinitions.js";
1111
import {PersistedKeysBackend} from "../keymanager/persistedKeys.js";
@@ -49,7 +49,7 @@ export async function getSignersFromArgs(
4949

5050
// ONLY USE FOR TESTNETS - Derive interop keys
5151
if (args.interopIndexes) {
52-
const indexes = parseRange(args.interopIndexes);
52+
const indexes = args.interopIndexes;
5353
// Using a remote signer with TESTNETS
5454
if (args["externalSigner.pubkeys"] || args["externalSigner.fetch"]) {
5555
return getRemoteSigners(args);
@@ -67,7 +67,7 @@ export async function getSignersFromArgs(
6767
}
6868

6969
const masterSK = deriveKeyFromMnemonic(args.fromMnemonic);
70-
const indexes = parseRange(args.mnemonicIndexes);
70+
const indexes = Array.from(new Set(args.mnemonicIndexes));
7171
return indexes.map((index) => ({
7272
type: SignerType.Local,
7373
secretKey: SecretKey.fromBytes(deriveEth2ValidatorKeys(masterSK, index).signing),

0 commit comments

Comments
 (0)