@chainsafe/lodestar 1.41.0-dev.988363dff3 → 1.41.0-dev.9939b12b53

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 (123) hide show
  1. package/.git-data.json +1 -1
  2. package/lib/applyPreset.js.map +1 -1
  3. package/lib/cli.js.map +1 -1
  4. package/lib/cmds/beacon/handler.d.ts +1 -1
  5. package/lib/cmds/beacon/handler.d.ts.map +1 -1
  6. package/lib/cmds/beacon/handler.js +5 -9
  7. package/lib/cmds/beacon/handler.js.map +1 -1
  8. package/lib/cmds/beacon/initBeaconState.js.map +1 -1
  9. package/lib/cmds/beacon/initPeerIdAndEnr.d.ts.map +1 -1
  10. package/lib/cmds/beacon/initPeerIdAndEnr.js +16 -15
  11. package/lib/cmds/beacon/initPeerIdAndEnr.js.map +1 -1
  12. package/lib/cmds/beacon/options.d.ts +3 -1
  13. package/lib/cmds/beacon/options.d.ts.map +1 -1
  14. package/lib/cmds/beacon/options.js +10 -0
  15. package/lib/cmds/beacon/options.js.map +1 -1
  16. package/lib/cmds/beacon/paths.d.ts +1 -1
  17. package/lib/cmds/beacon/paths.d.ts.map +1 -1
  18. package/lib/cmds/beacon/paths.js.map +1 -1
  19. package/lib/cmds/bootnode/handler.d.ts.map +1 -1
  20. package/lib/cmds/bootnode/handler.js.map +1 -1
  21. package/lib/cmds/dev/files.js.map +1 -1
  22. package/lib/cmds/dev/handler.js.map +1 -1
  23. package/lib/cmds/dev/options.d.ts +130 -126
  24. package/lib/cmds/dev/options.d.ts.map +1 -1
  25. package/lib/cmds/lightclient/handler.js.map +1 -1
  26. package/lib/cmds/validator/blsToExecutionChange.js.map +1 -1
  27. package/lib/cmds/validator/handler.js +1 -1
  28. package/lib/cmds/validator/handler.js.map +1 -1
  29. package/lib/cmds/validator/import.js.map +1 -1
  30. package/lib/cmds/validator/keymanager/decryptKeystoreDefinitions.js.map +1 -1
  31. package/lib/cmds/validator/keymanager/decryptKeystores/threadPool.d.ts.map +1 -1
  32. package/lib/cmds/validator/keymanager/decryptKeystores/threadPool.js.map +1 -1
  33. package/lib/cmds/validator/keymanager/decryptKeystores/types.js.map +1 -1
  34. package/lib/cmds/validator/keymanager/decryptKeystores/worker.js.map +1 -1
  35. package/lib/cmds/validator/keymanager/impl.d.ts +3 -3
  36. package/lib/cmds/validator/keymanager/impl.d.ts.map +1 -1
  37. package/lib/cmds/validator/keymanager/impl.js.map +1 -1
  38. package/lib/cmds/validator/keymanager/keystoreCache.js.map +1 -1
  39. package/lib/cmds/validator/keymanager/persistedKeys.d.ts +2 -2
  40. package/lib/cmds/validator/keymanager/persistedKeys.d.ts.map +1 -1
  41. package/lib/cmds/validator/keymanager/persistedKeys.js.map +1 -1
  42. package/lib/cmds/validator/keymanager/server.d.ts.map +1 -1
  43. package/lib/cmds/validator/keymanager/server.js.map +1 -1
  44. package/lib/cmds/validator/list.js.map +1 -1
  45. package/lib/cmds/validator/options.d.ts +1 -1
  46. package/lib/cmds/validator/options.d.ts.map +1 -1
  47. package/lib/cmds/validator/options.js +16 -7
  48. package/lib/cmds/validator/options.js.map +1 -1
  49. package/lib/cmds/validator/paths.js.map +1 -1
  50. package/lib/cmds/validator/signers/importExternalKeystores.js.map +1 -1
  51. package/lib/cmds/validator/signers/index.d.ts +2 -2
  52. package/lib/cmds/validator/signers/index.js +68 -13
  53. package/lib/cmds/validator/signers/index.js.map +1 -1
  54. package/lib/cmds/validator/signers/logSigners.js +1 -1
  55. package/lib/cmds/validator/signers/logSigners.js.map +1 -1
  56. package/lib/cmds/validator/slashingProtection/export.js.map +1 -1
  57. package/lib/cmds/validator/slashingProtection/import.js.map +1 -1
  58. package/lib/cmds/validator/slashingProtection/utils.js.map +1 -1
  59. package/lib/cmds/validator/voluntaryExit.js +1 -1
  60. package/lib/cmds/validator/voluntaryExit.js.map +1 -1
  61. package/lib/config/beaconNodeOptions.d.ts.map +1 -1
  62. package/lib/config/beaconNodeOptions.js.map +1 -1
  63. package/lib/config/beaconParams.js.map +1 -1
  64. package/lib/config/peerId.js.map +1 -1
  65. package/lib/index.js.map +1 -1
  66. package/lib/networks/index.d.ts +1 -1
  67. package/lib/networks/index.d.ts.map +1 -1
  68. package/lib/networks/index.js.map +1 -1
  69. package/lib/options/beaconNodeOptions/api.js.map +1 -1
  70. package/lib/options/beaconNodeOptions/builder.js.map +1 -1
  71. package/lib/options/beaconNodeOptions/chain.js.map +1 -1
  72. package/lib/options/beaconNodeOptions/execution.js.map +1 -1
  73. package/lib/options/beaconNodeOptions/index.d.ts +79 -75
  74. package/lib/options/beaconNodeOptions/index.d.ts.map +1 -1
  75. package/lib/options/beaconNodeOptions/index.js.map +1 -1
  76. package/lib/options/beaconNodeOptions/metrics.js.map +1 -1
  77. package/lib/options/beaconNodeOptions/monitoring.js.map +1 -1
  78. package/lib/options/beaconNodeOptions/network.d.ts +7 -0
  79. package/lib/options/beaconNodeOptions/network.d.ts.map +1 -1
  80. package/lib/options/beaconNodeOptions/network.js +61 -7
  81. package/lib/options/beaconNodeOptions/network.js.map +1 -1
  82. package/lib/options/beaconNodeOptions/sync.js.map +1 -1
  83. package/lib/options/paramsOptions.js.map +1 -1
  84. package/lib/paths/global.js.map +1 -1
  85. package/lib/paths/rootDir.js.map +1 -1
  86. package/lib/util/errors.js.map +1 -1
  87. package/lib/util/ethers.d.ts +1 -1
  88. package/lib/util/ethers.d.ts.map +1 -1
  89. package/lib/util/ethers.js.map +1 -1
  90. package/lib/util/feeRecipient.js.map +1 -1
  91. package/lib/util/file.js +2 -1
  92. package/lib/util/file.js.map +1 -1
  93. package/lib/util/format.js.map +1 -1
  94. package/lib/util/fs.js.map +1 -1
  95. package/lib/util/gitData/gitDataPath.js.map +1 -1
  96. package/lib/util/gitData/index.js.map +1 -1
  97. package/lib/util/jwt.js.map +1 -1
  98. package/lib/util/lockfile.js.map +1 -1
  99. package/lib/util/logger.js.map +1 -1
  100. package/lib/util/object.js.map +1 -1
  101. package/lib/util/passphrase.js.map +1 -1
  102. package/lib/util/process.js.map +1 -1
  103. package/lib/util/progress.d.ts +1 -1
  104. package/lib/util/progress.d.ts.map +1 -1
  105. package/lib/util/progress.js.map +1 -1
  106. package/lib/util/proposerConfig.js.map +1 -1
  107. package/lib/util/pruneOldFilesInDir.js.map +1 -1
  108. package/lib/util/sleep.js.map +1 -1
  109. package/lib/util/stripOffNewlines.js.map +1 -1
  110. package/lib/util/types.js.map +1 -1
  111. package/lib/util/version.js.map +1 -1
  112. package/package.json +24 -24
  113. package/src/cmds/beacon/handler.ts +5 -9
  114. package/src/cmds/beacon/initPeerIdAndEnr.ts +17 -17
  115. package/src/cmds/beacon/options.ts +13 -1
  116. package/src/cmds/bootnode/handler.ts +2 -2
  117. package/src/cmds/dev/options.ts +1 -1
  118. package/src/cmds/validator/handler.ts +1 -1
  119. package/src/cmds/validator/options.ts +17 -8
  120. package/src/cmds/validator/signers/index.ts +80 -13
  121. package/src/cmds/validator/signers/logSigners.ts +1 -1
  122. package/src/cmds/validator/voluntaryExit.ts +1 -1
  123. package/src/options/beaconNodeOptions/network.ts +79 -7
@@ -20,8 +20,8 @@ const KEYSTORE_IMPORT_PROGRESS_MS = 10000;
20
20
  * --interopIndexes
21
21
  * --fromMnemonic, then requires --mnemonicIndexes
22
22
  * --importKeystores, then requires --importKeystoresPassword
23
- * --externalSigner.fetch, then requires --externalSigner.url
24
- * --externalSigner.pubkeys, then requires --externalSigner.url
23
+ * --externalSigner.fetch, then requires --externalSigner.urls
24
+ * --externalSigner.pubkeys, then requires --externalSigner.urls
25
25
  * else load from persisted
26
26
  * - both remote keys and local keystores
27
27
  *
@@ -52,7 +52,7 @@ export async function getSignersFromArgs(
52
52
  const indexes = args.interopIndexes;
53
53
  // Using a remote signer with TESTNETS
54
54
  if (args["externalSigner.pubkeys"] || args["externalSigner.fetch"]) {
55
- return getRemoteSigners(args);
55
+ return getRemoteSigners(args, logger);
56
56
  }
57
57
  return indexes.map((index) => ({type: SignerType.Local, secretKey: interopSecretKey(index)}));
58
58
  }
@@ -105,7 +105,7 @@ export async function getSignersFromArgs(
105
105
 
106
106
  // Remote keys are declared manually or will be fetched from external signer
107
107
  if (args["externalSigner.pubkeys"] || args["externalSigner.fetch"]) {
108
- return getRemoteSigners(args);
108
+ return getRemoteSigners(args, logger);
109
109
  }
110
110
 
111
111
  // Read keys from local account manager
@@ -153,24 +153,91 @@ export function getSignerPubkeyHex(signer: Signer): string {
153
153
  }
154
154
  }
155
155
 
156
- async function getRemoteSigners(args: IValidatorCliArgs & GlobalArgs): Promise<Signer[]> {
157
- const externalSignerUrl = args["externalSigner.url"];
158
- if (!externalSignerUrl) {
156
+ async function getRemoteSigners(
157
+ args: IValidatorCliArgs & GlobalArgs,
158
+ logger: Pick<Logger, LogLevel.info | LogLevel.warn | LogLevel.debug>
159
+ ): Promise<Signer[]> {
160
+ const externalSignerUrls = args["externalSigner.urls"] ?? [];
161
+
162
+ if (externalSignerUrls.length === 0) {
159
163
  throw new YargsError(
160
- `Must set externalSigner.url with ${
164
+ `Must set externalSigner.urls with ${
161
165
  args["externalSigner.pubkeys"] ? "externalSigner.pubkeys" : "externalSigner.fetch"
162
166
  }`
163
167
  );
164
168
  }
165
- if (!isValidHttpUrl(externalSignerUrl)) {
166
- throw new YargsError(`Invalid external signer URL: ${externalSignerUrl}`);
169
+
170
+ for (const url of externalSignerUrls) {
171
+ if (!isValidHttpUrl(url)) {
172
+ throw new YargsError(`Invalid external signer URL: ${url}`);
173
+ }
167
174
  }
175
+
168
176
  if (args["externalSigner.pubkeys"] && args["externalSigner.pubkeys"].length === 0) {
169
177
  throw new YargsError("externalSigner.pubkeys is set to an empty list");
170
178
  }
171
179
 
172
- const pubkeys = args["externalSigner.pubkeys"] ?? (await externalSignerGetKeys(externalSignerUrl));
173
- assertValidPubkeysHex(pubkeys);
180
+ const signers: Signer[] = [];
181
+
182
+ if (args["externalSigner.pubkeys"]) {
183
+ // If pubkeys are explicitly provided with multiple URLs, warn user about limitation
184
+ if (externalSignerUrls.length > 1) {
185
+ throw new YargsError(
186
+ "Cannot use --externalSigner.pubkeys with multiple --externalSigner.urls. " +
187
+ "When using --externalSigner.pubkeys, only a single URL is allowed. " +
188
+ "To use multiple signers, use --externalSigner.fetch instead to fetch pubkeys from each signer."
189
+ );
190
+ }
191
+ // If pubkeys are explicitly provided, assign them to the first (and only) URL
192
+ // This maintains backward compatibility
193
+ const pubkeys = args["externalSigner.pubkeys"];
194
+ assertValidPubkeysHex(pubkeys);
195
+ for (const pubkey of pubkeys) {
196
+ signers.push({type: SignerType.Remote, pubkey, url: externalSignerUrls[0]});
197
+ }
198
+ } else {
199
+ // Fetch pubkeys from all external signer URLs, fail startup if any signer is unavailable
200
+ const results: {url: string; pubkeys: string[]}[] = [];
201
+ const failures: {url: string; error: string}[] = [];
202
+ await Promise.all(
203
+ externalSignerUrls.map(async (url) => {
204
+ try {
205
+ const pubkeys = await externalSignerGetKeys(url);
206
+ results.push({url, pubkeys});
207
+ } catch (e) {
208
+ const errorMsg = e instanceof Error ? e.message : String(e);
209
+ failures.push({url, error: errorMsg});
210
+ }
211
+ })
212
+ );
213
+ if (failures.length > 0) {
214
+ const errorMessages = failures.map((f) => ` ${f.url}: ${f.error}`).join("\n");
215
+ throw new YargsError(
216
+ `Failed to fetch pubkeys from external signer(s):\n${errorMessages}\n` +
217
+ "Please verify the signer URLs are correct and reachable."
218
+ );
219
+ }
220
+
221
+ const seenPubkeys = new Map<string, string>();
222
+ for (const {url, pubkeys} of results) {
223
+ if (pubkeys.length > 0) {
224
+ assertValidPubkeysHex(pubkeys);
225
+ for (const pubkey of pubkeys) {
226
+ const firstUrl = seenPubkeys.get(pubkey);
227
+ if (firstUrl !== undefined) {
228
+ logger.warn("Duplicate pubkey found on multiple signers, using first occurrence only", {
229
+ pubkey,
230
+ firstUrl,
231
+ duplicateUrl: url,
232
+ });
233
+ continue;
234
+ }
235
+ seenPubkeys.set(pubkey, url);
236
+ signers.push({type: SignerType.Remote, pubkey, url});
237
+ }
238
+ }
239
+ }
240
+ }
174
241
 
175
- return pubkeys.map((pubkey) => ({type: SignerType.Remote, pubkey, url: externalSignerUrl}));
242
+ return signers;
176
243
  }
@@ -69,7 +69,7 @@ export function warnOrExitNoSigners(args: IValidatorCliArgs, logger: Pick<Logger
69
69
  "No local keystores or remote keys found with current args, expecting to be added via keymanager or fetched from external signer later"
70
70
  );
71
71
  } else {
72
- if (args["externalSigner.url"]) {
72
+ if (args["externalSigner.urls"]) {
73
73
  throw new YargsError(
74
74
  "No remote keys found with current args, start with --externalSigner.fetch to automatically fetch from external signer"
75
75
  );
@@ -37,7 +37,7 @@ If no `pubkeys` are provided, it will exit all validators that have been importe
37
37
  },
38
38
  {
39
39
  command:
40
- "validator voluntary-exit --network hoodi --externalSigner.url http://signer:9000 --externalSigner.fetch --pubkeys 0xF00",
40
+ "validator voluntary-exit --network hoodi --externalSigner.urls http://signer:9000 --externalSigner.fetch --pubkeys 0xF00",
41
41
  description:
42
42
  "Perform a voluntary exit for the validator who has a public key 0xF00 and its secret key is on an external signer",
43
43
  },
@@ -7,20 +7,25 @@ import {YargsError} from "../../util/index.js";
7
7
  export const defaultListenAddress = "0.0.0.0";
8
8
  export const defaultListenAddress6 = "::";
9
9
  export const defaultP2pPort = 9000;
10
+ export const defaultQuicPort = 9001;
10
11
 
11
12
  export type NetworkArgs = {
12
13
  discv5?: boolean;
13
14
  listenAddress?: string;
14
15
  port?: number;
15
16
  discoveryPort?: number;
17
+ quicPort?: number;
16
18
  listenAddress6?: string;
17
19
  port6?: number;
18
20
  discoveryPort6?: number;
21
+ quicPort6?: number;
19
22
  bootnodes?: string[];
20
23
  targetPeers?: number;
21
24
  subscribeAllSubnets?: boolean;
22
25
  slotsToSubscribeBeforeAggregatorDuty?: number;
23
26
  disablePeerScoring?: boolean;
27
+ quic?: boolean;
28
+ tcp?: boolean;
24
29
  mdns?: boolean;
25
30
  directPeers?: string[];
26
31
  "network.maxPeers"?: number;
@@ -65,43 +70,79 @@ export function parseListenArgs(args: NetworkArgs) {
65
70
  const listenAddress = args.listenAddress ?? (args.listenAddress6 ? undefined : defaultListenAddress);
66
71
  const port = listenAddress ? (args.port ?? defaultP2pPort) : undefined;
67
72
  const discoveryPort = listenAddress ? (args.discoveryPort ?? port) : undefined;
73
+ const quicPort = listenAddress ? (args.quicPort ?? (port !== undefined ? port + 1 : defaultQuicPort)) : undefined;
68
74
 
69
75
  // If listenAddress6 is explicitly set, use it
70
76
  // If listenAddress is not set, use defaultListenAddress6
71
77
  const listenAddress6 = args.listenAddress6 ?? (args.listenAddress ? undefined : defaultListenAddress6);
72
78
  const port6 = listenAddress6 ? (args.port6 ?? args.port ?? defaultP2pPort) : undefined;
73
79
  const discoveryPort6 = listenAddress6 ? (args.discoveryPort6 ?? port6) : undefined;
80
+ const quicPort6 = listenAddress6
81
+ ? (args.quicPort6 ?? (port6 !== undefined ? port6 + 1 : defaultQuicPort))
82
+ : undefined;
74
83
 
75
- return {listenAddress, port, discoveryPort, listenAddress6, port6, discoveryPort6};
84
+ return {listenAddress, port, discoveryPort, quicPort, listenAddress6, port6, discoveryPort6, quicPort6};
76
85
  }
77
86
 
78
87
  export function parseArgs(args: NetworkArgs): IBeaconNodeOptions["network"] {
79
- const {listenAddress, port, discoveryPort, listenAddress6, port6, discoveryPort6} = parseListenArgs(args);
88
+ const {listenAddress, port, discoveryPort, quicPort, listenAddress6, port6, discoveryPort6, quicPort6} =
89
+ parseListenArgs(args);
90
+ const quic = args.quic ?? false;
91
+ const tcp = args.tcp ?? true;
92
+
93
+ if (!quic && !tcp) {
94
+ throw new YargsError("Cannot disable both TCP and QUIC transports");
95
+ }
96
+
80
97
  // validate ip, ip6, ports
81
98
  const muArgs = {
82
99
  listenAddress: listenAddress ? `/ip4/${listenAddress}` : undefined,
83
100
  port: listenAddress ? `/tcp/${port}` : undefined,
84
101
  discoveryPort: listenAddress ? `/udp/${discoveryPort}` : undefined,
102
+ quicPort: listenAddress ? `/udp/${quicPort}/quic-v1` : undefined,
85
103
  listenAddress6: listenAddress6 ? `/ip6/${listenAddress6}` : undefined,
86
104
  port6: listenAddress6 ? `/tcp/${port6}` : undefined,
87
105
  discoveryPort6: listenAddress6 ? `/udp/${discoveryPort6}` : undefined,
106
+ quicPort6: listenAddress6 ? `/udp/${quicPort6}/quic-v1` : undefined,
88
107
  };
89
108
 
90
- for (const key of [
109
+ const keysToValidate: (keyof typeof muArgs)[] = [
91
110
  "listenAddress",
92
111
  "port",
93
112
  "discoveryPort",
94
113
  "listenAddress6",
95
114
  "port6",
96
115
  "discoveryPort6",
97
- ] as (keyof typeof muArgs)[]) {
116
+ ];
117
+
118
+ if (quic) {
119
+ keysToValidate.push("quicPort");
120
+ keysToValidate.push("quicPort6");
121
+ }
122
+
123
+ for (const key of keysToValidate) {
98
124
  validateMultiaddrArg(muArgs, key);
99
125
  }
100
126
 
127
+ if (quic) {
128
+ if (discoveryPort !== undefined && quicPort !== undefined && discoveryPort === quicPort) {
129
+ throw new YargsError(
130
+ `discoveryPort and quicPort must not collide, both are UDP. Got discoveryPort=${discoveryPort} quicPort=${quicPort}`
131
+ );
132
+ }
133
+ if (discoveryPort6 !== undefined && quicPort6 !== undefined && discoveryPort6 === quicPort6) {
134
+ throw new YargsError(
135
+ `discoveryPort6 and quicPort6 must not collide, both are UDP. Got discoveryPort6=${discoveryPort6} quicPort6=${quicPort6}`
136
+ );
137
+ }
138
+ }
139
+
101
140
  const bindMu = listenAddress ? `${muArgs.listenAddress}${muArgs.discoveryPort}` : undefined;
102
- const localMu = listenAddress ? `${muArgs.listenAddress}${muArgs.port}` : undefined;
141
+ const localMu = listenAddress && tcp ? `${muArgs.listenAddress}${muArgs.port}` : undefined;
142
+ const quicMu = listenAddress && quic ? `${muArgs.listenAddress}${muArgs.quicPort}` : undefined;
103
143
  const bindMu6 = listenAddress6 ? `${muArgs.listenAddress6}${muArgs.discoveryPort6}` : undefined;
104
- const localMu6 = listenAddress6 ? `${muArgs.listenAddress6}${muArgs.port6}` : undefined;
144
+ const localMu6 = listenAddress6 && tcp ? `${muArgs.listenAddress6}${muArgs.port6}` : undefined;
145
+ const quicMu6 = listenAddress6 && quic ? `${muArgs.listenAddress6}${muArgs.quicPort6}` : undefined;
105
146
 
106
147
  const targetPeers = args.targetPeers;
107
148
  const maxPeers = args["network.maxPeers"] ?? (targetPeers !== undefined ? Math.floor(targetPeers * 1.1) : undefined);
@@ -137,11 +178,13 @@ export function parseArgs(args: NetworkArgs): IBeaconNodeOptions["network"] {
137
178
  : null,
138
179
  maxPeers: maxPeers ?? defaultOptions.network.maxPeers,
139
180
  targetPeers: targetPeers ?? defaultOptions.network.targetPeers,
140
- localMultiaddrs: [localMu, localMu6].filter(Boolean) as string[],
181
+ localMultiaddrs: [quicMu, quicMu6, localMu, localMu6].filter(Boolean) as string[],
141
182
  subscribeAllSubnets: args.subscribeAllSubnets,
142
183
  slotsToSubscribeBeforeAggregatorDuty:
143
184
  args.slotsToSubscribeBeforeAggregatorDuty ?? defaultOptions.network.slotsToSubscribeBeforeAggregatorDuty,
144
185
  disablePeerScoring: args.disablePeerScoring,
186
+ quic,
187
+ tcp,
145
188
  connectToDiscv5Bootnodes: args["network.connectToDiscv5Bootnodes"],
146
189
  discv5FirstQueryDelayMs: args["network.discv5FirstQueryDelayMs"],
147
190
  dontSendGossipAttestationsToForkchoice: args["network.dontSendGossipAttestationsToForkchoice"],
@@ -192,6 +235,13 @@ export const options: CliCommandOptions<NetworkArgs> = {
192
235
  group: "network",
193
236
  },
194
237
 
238
+ quicPort: {
239
+ description: "The UDP port that QUIC will listen on. Defaults to `port` + 1",
240
+ type: "number",
241
+ defaultDescription: "`port` + 1",
242
+ group: "network",
243
+ },
244
+
195
245
  listenAddress6: {
196
246
  type: "string",
197
247
  description: "The IPv6 address to listen for p2p UDP and TCP connections",
@@ -214,6 +264,13 @@ export const options: CliCommandOptions<NetworkArgs> = {
214
264
  group: "network",
215
265
  },
216
266
 
267
+ quicPort6: {
268
+ description: "The UDP port that QUIC will listen on. Defaults to `port6` + 1",
269
+ type: "number",
270
+ defaultDescription: "`port6` + 1",
271
+ group: "network",
272
+ },
273
+
217
274
  bootnodes: {
218
275
  type: "array",
219
276
  description: "Bootnodes for discv5 discovery",
@@ -254,6 +311,21 @@ export const options: CliCommandOptions<NetworkArgs> = {
254
311
  group: "network",
255
312
  },
256
313
 
314
+ quic: {
315
+ type: "boolean",
316
+ description: "Enable QUIC transport",
317
+ default: false,
318
+ group: "network",
319
+ },
320
+
321
+ tcp: {
322
+ hidden: true,
323
+ type: "boolean",
324
+ description: "Enable TCP transport",
325
+ default: true,
326
+ group: "network",
327
+ },
328
+
257
329
  mdns: {
258
330
  type: "boolean",
259
331
  description: "Enable mdns local peer discovery",