@lodestar/config 1.45.0 → 1.46.0-dev.1680f4f4dc

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 (36) hide show
  1. package/lib/beaconConfig.js.map +1 -1
  2. package/lib/chainConfig/configs/mainnet.d.ts.map +1 -1
  3. package/lib/chainConfig/configs/mainnet.js +16 -4
  4. package/lib/chainConfig/configs/mainnet.js.map +1 -1
  5. package/lib/chainConfig/configs/minimal.d.ts.map +1 -1
  6. package/lib/chainConfig/configs/minimal.js +14 -2
  7. package/lib/chainConfig/configs/minimal.js.map +1 -1
  8. package/lib/chainConfig/index.d.ts +1 -0
  9. package/lib/chainConfig/index.d.ts.map +1 -1
  10. package/lib/chainConfig/index.js +1 -0
  11. package/lib/chainConfig/index.js.map +1 -1
  12. package/lib/chainConfig/json.js.map +1 -1
  13. package/lib/chainConfig/params.d.ts +20 -0
  14. package/lib/chainConfig/params.d.ts.map +1 -0
  15. package/lib/chainConfig/params.js +310 -0
  16. package/lib/chainConfig/params.js.map +1 -0
  17. package/lib/chainConfig/types.d.ts +6 -0
  18. package/lib/chainConfig/types.d.ts.map +1 -1
  19. package/lib/chainConfig/types.js +8 -0
  20. package/lib/chainConfig/types.js.map +1 -1
  21. package/lib/forkConfig/index.d.ts.map +1 -1
  22. package/lib/forkConfig/index.js +9 -1
  23. package/lib/forkConfig/index.js.map +1 -1
  24. package/lib/genesisConfig/index.js.map +1 -1
  25. package/lib/testUtils/config.d.ts.map +1 -1
  26. package/lib/testUtils/config.js +12 -0
  27. package/lib/testUtils/config.js.map +1 -1
  28. package/lib/utils/validateBlobSchedule.js.map +1 -1
  29. package/package.json +13 -13
  30. package/src/chainConfig/configs/mainnet.ts +19 -4
  31. package/src/chainConfig/configs/minimal.ts +15 -2
  32. package/src/chainConfig/index.ts +1 -0
  33. package/src/chainConfig/params.ts +358 -0
  34. package/src/chainConfig/types.ts +20 -0
  35. package/src/forkConfig/index.ts +9 -1
  36. package/src/testUtils/config.ts +12 -0
@@ -0,0 +1,358 @@
1
+ import {BeaconPreset, activePreset, presetToJson} from "@lodestar/params";
2
+ import {chainConfigToJson, deserializeBlobSchedule} from "./json.js";
3
+ import {BlobScheduleEntry, ChainConfig, SpecJson} from "./types.js";
4
+
5
+ export class NotEqualParamsError extends Error {}
6
+
7
+ type ConfigWithPreset = ChainConfig & BeaconPreset;
8
+
9
+ /**
10
+ * Assert localConfig values match externalSpecJson. externalSpecJson may contain more values than localConfig.
11
+ *
12
+ * This check ensures that the validator is connected to a beacon node of the exact same network and params.
13
+ * Otherwise, signatures may be rejected, time may be un-equal and other bugs that are harder to debug caused
14
+ * by different parameters.
15
+ *
16
+ * This check however can't compare the full config as is, since some parameters are not critical to the spec and
17
+ * can be changed un-expectedly. Also, fork parameters can change un-expectedly, like their _FORK_VERSION or _EPOCH.
18
+ * Note that the config API endpoint is not precisely specified, so each clients can return a different set of
19
+ * parameters.
20
+ *
21
+ * So this check only compares a specific list of parameters that are consensus critical, ignoring the rest. Typed
22
+ * config and preset ensure new parameters are labeled critical or ignore, facilitating maintenance of the list.
23
+ */
24
+ export function assertEqualParams(localConfig: ChainConfig, externalSpecJson: SpecJson): void {
25
+ // Before comparing, add preset which is bundled in api impl config route.
26
+ // config and preset must be serialized to JSON for safe comparisions.
27
+ const localSpecJson = {
28
+ ...chainConfigToJson(localConfig),
29
+ ...presetToJson(activePreset),
30
+ };
31
+
32
+ // Get list of keys to check, and keys to ignore. Otherwise this function throws for false positives
33
+ const criticalParams = getSpecCriticalParams(localConfig);
34
+
35
+ // Accumulate errors first and print all of them at once
36
+ const errors: string[] = [];
37
+
38
+ for (const key of Object.keys(criticalParams) as (keyof typeof criticalParams)[]) {
39
+ if (
40
+ // Ignore non-critical params
41
+ !criticalParams[key] ||
42
+ // This condition should never be true, but just in case
43
+ localSpecJson[key] === undefined ||
44
+ // The config/spec endpoint is poorly specified, so in practice each client returns a custom selection of keys.
45
+ // For example Lighthouse returns a manually selected list of keys that may be updated at any time.
46
+ // https://github.com/sigp/lighthouse/blob/bac7c3fa544495a257722aaad9cd8f72fee2f2b4/consensus/types/src/chain_spec.rs#L941
47
+ //
48
+ // So if we assert that spec critical keys are present in the spec we may break interoperability unexpectedly.
49
+ // So it's best to ignore keys are not defined in both specs and trust that the ones defined are sufficient
50
+ // to detect spec discrepancies in all cases.
51
+ externalSpecJson[key] === undefined
52
+ ) {
53
+ continue;
54
+ }
55
+
56
+ if (key === "BLOB_SCHEDULE") {
57
+ const localBlobSchedule = deserializeBlobSchedule(localSpecJson[key]).sort((a, b) => a.EPOCH - b.EPOCH);
58
+ const remoteBlobSchedule = deserializeBlobSchedule(externalSpecJson[key]).sort((a, b) => a.EPOCH - b.EPOCH);
59
+
60
+ if (localBlobSchedule.length !== remoteBlobSchedule.length) {
61
+ errors.push(`BLOB_SCHEDULE different length: ${localBlobSchedule.length} != ${remoteBlobSchedule.length}`);
62
+
63
+ // Skip per entry comparison
64
+ continue;
65
+ }
66
+
67
+ for (let i = 0; i < localBlobSchedule.length; i++) {
68
+ const localEntry = localBlobSchedule[i];
69
+ const remoteEntry = remoteBlobSchedule[i];
70
+
71
+ for (const entryKey of ["EPOCH", "MAX_BLOBS_PER_BLOCK"] as Array<keyof BlobScheduleEntry>) {
72
+ const localValue = String(localEntry[entryKey]);
73
+ const remoteValue = String(remoteEntry[entryKey]);
74
+
75
+ if (localValue !== remoteValue) {
76
+ errors.push(`BLOB_SCHEDULE[${i}].${entryKey} different value: ${localValue} != ${remoteValue}`);
77
+ }
78
+ }
79
+ }
80
+
81
+ // Skip generic string comparison
82
+ continue;
83
+ }
84
+
85
+ // Must compare JSON serialized specs, to ensure all strings are rendered in the same way
86
+ // Must compare as lowercase to ensure checksum addresses and names have same capilatization
87
+ const localValue = String(localSpecJson[key]).toLocaleLowerCase();
88
+ const remoteValue = String(externalSpecJson[key]).toLocaleLowerCase();
89
+ if (localValue !== remoteValue) {
90
+ errors.push(`${key} different value: ${localValue} != ${remoteValue}`);
91
+ }
92
+ }
93
+
94
+ if (errors.length > 0) {
95
+ throw new NotEqualParamsError("Local and remote configs are different\n" + errors.join("\n"));
96
+ }
97
+ }
98
+
99
+ function getSpecCriticalParams(localConfig: ChainConfig): Record<keyof ConfigWithPreset, boolean> {
100
+ const altairForkRelevant = localConfig.ALTAIR_FORK_EPOCH < Infinity;
101
+ const bellatrixForkRelevant = localConfig.BELLATRIX_FORK_EPOCH < Infinity;
102
+ const capellaForkRelevant = localConfig.CAPELLA_FORK_EPOCH < Infinity;
103
+ const denebForkRelevant = localConfig.DENEB_FORK_EPOCH < Infinity;
104
+ const electraForkRelevant = localConfig.ELECTRA_FORK_EPOCH < Infinity;
105
+ const fuluForkRelevant = localConfig.FULU_FORK_EPOCH < Infinity;
106
+ const gloasForkRelevant = localConfig.GLOAS_FORK_EPOCH < Infinity;
107
+ const hezeForkRelevant = localConfig.HEZE_FORK_EPOCH < Infinity;
108
+
109
+ return {
110
+ // # Config
111
+ ///////////
112
+
113
+ PRESET_BASE: false, // Not relevant, each preset value is checked below
114
+ CONFIG_NAME: false, // Arbitrary string, not relevant
115
+
116
+ // Deprecated - All networks have completed the merge transition
117
+ TERMINAL_TOTAL_DIFFICULTY: false,
118
+ TERMINAL_BLOCK_HASH: false,
119
+ TERMINAL_BLOCK_HASH_ACTIVATION_EPOCH: false,
120
+
121
+ // Genesis
122
+ MIN_GENESIS_ACTIVE_VALIDATOR_COUNT: true,
123
+ MIN_GENESIS_TIME: true,
124
+ GENESIS_FORK_VERSION: true,
125
+ GENESIS_DELAY: true,
126
+
127
+ // Forking
128
+ // Altair
129
+ ALTAIR_FORK_VERSION: altairForkRelevant,
130
+ ALTAIR_FORK_EPOCH: altairForkRelevant,
131
+ // Bellatrix
132
+ BELLATRIX_FORK_VERSION: bellatrixForkRelevant,
133
+ BELLATRIX_FORK_EPOCH: bellatrixForkRelevant,
134
+ // Capella
135
+ CAPELLA_FORK_VERSION: capellaForkRelevant,
136
+ CAPELLA_FORK_EPOCH: capellaForkRelevant,
137
+ // Deneb
138
+ DENEB_FORK_VERSION: denebForkRelevant,
139
+ DENEB_FORK_EPOCH: denebForkRelevant,
140
+ // electra
141
+ ELECTRA_FORK_VERSION: electraForkRelevant,
142
+ ELECTRA_FORK_EPOCH: electraForkRelevant,
143
+ // fulu
144
+ FULU_FORK_VERSION: fuluForkRelevant,
145
+ FULU_FORK_EPOCH: fuluForkRelevant,
146
+ // gloas
147
+ GLOAS_FORK_VERSION: gloasForkRelevant,
148
+ GLOAS_FORK_EPOCH: gloasForkRelevant,
149
+ // heze
150
+ HEZE_FORK_VERSION: hezeForkRelevant,
151
+ HEZE_FORK_EPOCH: hezeForkRelevant,
152
+
153
+ // Time parameters
154
+ SECONDS_PER_SLOT: false, // Deprecated
155
+ SLOT_DURATION_MS: true,
156
+ SECONDS_PER_ETH1_BLOCK: false, // Legacy
157
+ MIN_VALIDATOR_WITHDRAWABILITY_DELAY: true,
158
+ SHARD_COMMITTEE_PERIOD: true,
159
+ ETH1_FOLLOW_DISTANCE: true,
160
+ PROPOSER_REORG_CUTOFF_BPS: true,
161
+ ATTESTATION_DUE_BPS: true,
162
+ AGGREGATE_DUE_BPS: true,
163
+ // Altair
164
+ SYNC_MESSAGE_DUE_BPS: altairForkRelevant,
165
+ CONTRIBUTION_DUE_BPS: altairForkRelevant,
166
+
167
+ // Validator cycle
168
+ INACTIVITY_SCORE_BIAS: true,
169
+ INACTIVITY_SCORE_RECOVERY_RATE: true,
170
+ EJECTION_BALANCE: true,
171
+ MIN_PER_EPOCH_CHURN_LIMIT: true,
172
+ MAX_PER_EPOCH_ACTIVATION_CHURN_LIMIT: denebForkRelevant,
173
+ CHURN_LIMIT_QUOTIENT: true,
174
+
175
+ // Fork choice
176
+ PROPOSER_SCORE_BOOST: false, // Ignored as it's changing https://github.com/ethereum/consensus-specs/pull/2895
177
+ REORG_HEAD_WEIGHT_THRESHOLD: false, // Non-critical since proposer boost reorg is optional feature
178
+ REORG_PARENT_WEIGHT_THRESHOLD: false, // Non-critical since proposer boost reorg is optional feature
179
+ REORG_MAX_EPOCHS_SINCE_FINALIZATION: false, // Non-critical since proposer boost reorg is optional feature
180
+
181
+ // Deposit contract
182
+ DEPOSIT_CHAIN_ID: false, // Non-critical
183
+ DEPOSIT_NETWORK_ID: false, // Non-critical
184
+ DEPOSIT_CONTRACT_ADDRESS: true,
185
+
186
+ // Networking (non-critical as those do not affect consensus)
187
+ MAX_PAYLOAD_SIZE: false,
188
+ EPOCHS_PER_SUBNET_SUBSCRIPTION: false,
189
+ ATTESTATION_PROPAGATION_SLOT_RANGE: false,
190
+ MAXIMUM_GOSSIP_CLOCK_DISPARITY: false,
191
+ MESSAGE_DOMAIN_INVALID_SNAPPY: false,
192
+ MESSAGE_DOMAIN_VALID_SNAPPY: false,
193
+ SUBNETS_PER_NODE: false,
194
+ MAX_REQUEST_BLOCKS: false,
195
+ MAX_REQUEST_BLOCKS_DENEB: false,
196
+ MIN_EPOCHS_FOR_BLOCK_REQUESTS: false,
197
+ MIN_EPOCHS_FOR_BLOB_SIDECARS_REQUESTS: false,
198
+ MIN_EPOCHS_FOR_DATA_COLUMN_SIDECARS_REQUESTS: false,
199
+ BLOB_SIDECAR_SUBNET_COUNT: false,
200
+ BLOB_SIDECAR_SUBNET_COUNT_ELECTRA: false,
201
+ DATA_COLUMN_SIDECAR_SUBNET_COUNT: false,
202
+ MAX_REQUEST_BLOB_SIDECARS: false,
203
+ MAX_REQUEST_BLOB_SIDECARS_ELECTRA: false,
204
+ MAX_REQUEST_DATA_COLUMN_SIDECARS: false,
205
+ MAX_REQUEST_PAYLOADS: false,
206
+
207
+ // # Phase0Preset
208
+ /////////////////
209
+
210
+ MAX_COMMITTEES_PER_SLOT: true,
211
+ TARGET_COMMITTEE_SIZE: true,
212
+ MAX_VALIDATORS_PER_COMMITTEE: true,
213
+
214
+ SHUFFLE_ROUND_COUNT: true,
215
+
216
+ HYSTERESIS_QUOTIENT: true,
217
+ HYSTERESIS_DOWNWARD_MULTIPLIER: true,
218
+ HYSTERESIS_UPWARD_MULTIPLIER: true,
219
+
220
+ // Gwei Values
221
+ MIN_DEPOSIT_AMOUNT: true,
222
+ MAX_EFFECTIVE_BALANCE: true,
223
+ EFFECTIVE_BALANCE_INCREMENT: true,
224
+
225
+ // Time parameters
226
+ MIN_ATTESTATION_INCLUSION_DELAY: true,
227
+ SLOTS_PER_EPOCH: true,
228
+ MIN_SEED_LOOKAHEAD: true,
229
+ MAX_SEED_LOOKAHEAD: true,
230
+ EPOCHS_PER_ETH1_VOTING_PERIOD: true,
231
+ SLOTS_PER_HISTORICAL_ROOT: true,
232
+ MIN_EPOCHS_TO_INACTIVITY_PENALTY: true,
233
+
234
+ // State vector lengths
235
+ EPOCHS_PER_HISTORICAL_VECTOR: true,
236
+ EPOCHS_PER_SLASHINGS_VECTOR: true,
237
+ HISTORICAL_ROOTS_LIMIT: true,
238
+ VALIDATOR_REGISTRY_LIMIT: true,
239
+
240
+ // Reward and penalty quotients
241
+ BASE_REWARD_FACTOR: true,
242
+ WHISTLEBLOWER_REWARD_QUOTIENT: true,
243
+ PROPOSER_REWARD_QUOTIENT: true,
244
+ INACTIVITY_PENALTY_QUOTIENT: true,
245
+ MIN_SLASHING_PENALTY_QUOTIENT: true,
246
+ PROPORTIONAL_SLASHING_MULTIPLIER: true,
247
+
248
+ // Max operations per block
249
+ MAX_PROPOSER_SLASHINGS: true,
250
+ MAX_ATTESTER_SLASHINGS: true,
251
+ MAX_ATTESTATIONS: true,
252
+ MAX_DEPOSITS: true,
253
+ MAX_VOLUNTARY_EXITS: true,
254
+
255
+ // # AltairPreset
256
+ /////////////////
257
+
258
+ SYNC_COMMITTEE_SIZE: altairForkRelevant,
259
+ EPOCHS_PER_SYNC_COMMITTEE_PERIOD: altairForkRelevant,
260
+ INACTIVITY_PENALTY_QUOTIENT_ALTAIR: altairForkRelevant,
261
+ MIN_SLASHING_PENALTY_QUOTIENT_ALTAIR: altairForkRelevant,
262
+ PROPORTIONAL_SLASHING_MULTIPLIER_ALTAIR: altairForkRelevant,
263
+ MIN_SYNC_COMMITTEE_PARTICIPANTS: false, // Only relevant for lightclients
264
+ UPDATE_TIMEOUT: false, // Only relevant for lightclients
265
+
266
+ // # BellatrixPreset
267
+ /////////////////
268
+
269
+ INACTIVITY_PENALTY_QUOTIENT_BELLATRIX: bellatrixForkRelevant,
270
+ MIN_SLASHING_PENALTY_QUOTIENT_BELLATRIX: bellatrixForkRelevant,
271
+ PROPORTIONAL_SLASHING_MULTIPLIER_BELLATRIX: bellatrixForkRelevant,
272
+ MAX_BYTES_PER_TRANSACTION: bellatrixForkRelevant,
273
+ MAX_TRANSACTIONS_PER_PAYLOAD: bellatrixForkRelevant,
274
+ BYTES_PER_LOGS_BLOOM: bellatrixForkRelevant,
275
+ MAX_EXTRA_DATA_BYTES: bellatrixForkRelevant,
276
+
277
+ // # CapellaPreset
278
+ /////////////////
279
+ MAX_BLS_TO_EXECUTION_CHANGES: capellaForkRelevant,
280
+ MAX_WITHDRAWALS_PER_PAYLOAD: capellaForkRelevant,
281
+ MAX_VALIDATORS_PER_WITHDRAWALS_SWEEP: capellaForkRelevant,
282
+
283
+ // # DenebPreset
284
+ /////////////////
285
+ FIELD_ELEMENTS_PER_BLOB: denebForkRelevant,
286
+ MAX_BLOB_COMMITMENTS_PER_BLOCK: denebForkRelevant,
287
+ KZG_COMMITMENT_INCLUSION_PROOF_DEPTH: denebForkRelevant,
288
+ MAX_BLOBS_PER_BLOCK: denebForkRelevant,
289
+
290
+ // ELECTRA
291
+ MAX_DEPOSIT_REQUESTS_PER_PAYLOAD: electraForkRelevant,
292
+ MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD: electraForkRelevant,
293
+ MAX_ATTESTER_SLASHINGS_ELECTRA: electraForkRelevant,
294
+ MAX_ATTESTATIONS_ELECTRA: electraForkRelevant,
295
+ MAX_PENDING_PARTIALS_PER_WITHDRAWALS_SWEEP: electraForkRelevant,
296
+ MAX_PENDING_DEPOSITS_PER_EPOCH: electraForkRelevant,
297
+ MAX_EFFECTIVE_BALANCE_ELECTRA: electraForkRelevant,
298
+ MIN_SLASHING_PENALTY_QUOTIENT_ELECTRA: electraForkRelevant,
299
+ MIN_ACTIVATION_BALANCE: electraForkRelevant,
300
+ PENDING_DEPOSITS_LIMIT: electraForkRelevant,
301
+ PENDING_PARTIAL_WITHDRAWALS_LIMIT: electraForkRelevant,
302
+ PENDING_CONSOLIDATIONS_LIMIT: electraForkRelevant,
303
+ MAX_CONSOLIDATION_REQUESTS_PER_PAYLOAD: electraForkRelevant,
304
+ WHISTLEBLOWER_REWARD_QUOTIENT_ELECTRA: electraForkRelevant,
305
+ MAX_PER_EPOCH_ACTIVATION_EXIT_CHURN_LIMIT: electraForkRelevant,
306
+ MIN_PER_EPOCH_CHURN_LIMIT_ELECTRA: electraForkRelevant,
307
+ MAX_BLOBS_PER_BLOCK_ELECTRA: electraForkRelevant,
308
+
309
+ // FULU
310
+ /////////////////
311
+ CELLS_PER_EXT_BLOB: fuluForkRelevant,
312
+ FIELD_ELEMENTS_PER_CELL: fuluForkRelevant,
313
+ FIELD_ELEMENTS_PER_EXT_BLOB: fuluForkRelevant,
314
+ KZG_COMMITMENTS_INCLUSION_PROOF_DEPTH: fuluForkRelevant,
315
+ NUMBER_OF_COLUMNS: fuluForkRelevant,
316
+ NUMBER_OF_CUSTODY_GROUPS: fuluForkRelevant,
317
+ SAMPLES_PER_SLOT: fuluForkRelevant,
318
+ CUSTODY_REQUIREMENT: fuluForkRelevant,
319
+ VALIDATOR_CUSTODY_REQUIREMENT: fuluForkRelevant,
320
+ BALANCE_PER_ADDITIONAL_CUSTODY_GROUP: fuluForkRelevant,
321
+ BLOB_SCHEDULE: fuluForkRelevant,
322
+
323
+ // GLOAS
324
+ ATTESTATION_DUE_BPS_GLOAS: gloasForkRelevant,
325
+ AGGREGATE_DUE_BPS_GLOAS: gloasForkRelevant,
326
+ SYNC_MESSAGE_DUE_BPS_GLOAS: gloasForkRelevant,
327
+ CONTRIBUTION_DUE_BPS_GLOAS: gloasForkRelevant,
328
+ PAYLOAD_ATTESTATION_DUE_BPS: gloasForkRelevant,
329
+ PAYLOAD_DUE_BPS: gloasForkRelevant,
330
+ PTC_SIZE: gloasForkRelevant,
331
+ MAX_PAYLOAD_ATTESTATIONS: gloasForkRelevant,
332
+ MAX_BUILDER_DEPOSIT_REQUESTS_PER_PAYLOAD: gloasForkRelevant,
333
+ MAX_BUILDER_EXIT_REQUESTS_PER_PAYLOAD: gloasForkRelevant,
334
+ MAX_BUILDERS_PER_WITHDRAWALS_SWEEP: gloasForkRelevant,
335
+ MAX_SIGNED_AGGREGATE_AND_PROOF_SIZE: false,
336
+ MAX_ATTESTER_SLASHING_SIZE: false,
337
+ MAX_DATA_COLUMN_SIDECAR_SIZE: false,
338
+ MAX_PARTIAL_DATA_COLUMN_SIDECAR_SIZE: false,
339
+ MAX_SIGNED_EXECUTION_PAYLOAD_BID_SIZE: false,
340
+ MIN_BUILDER_WITHDRAWABILITY_DELAY: gloasForkRelevant,
341
+
342
+ // HEZE
343
+ INCLUSION_LIST_DUE_BPS: hezeForkRelevant,
344
+ MAX_REQUEST_INCLUSION_LIST: hezeForkRelevant,
345
+ MIN_SLOTS_FOR_INCLUSION_LISTS_REQUESTS: false,
346
+ MAX_BYTES_PER_INCLUSION_LIST: hezeForkRelevant,
347
+ INCLUSION_LIST_COMMITTEE_SIZE: hezeForkRelevant,
348
+ MAX_SIGNED_EXECUTION_PAYLOAD_BID_SIZE_HEZE: false,
349
+ MAX_SIGNED_INCLUSION_LIST_SIZE: false,
350
+
351
+ // FastConfirmationRule
352
+ CONFIRMATION_BYZANTINE_THRESHOLD: false,
353
+
354
+ CHURN_LIMIT_QUOTIENT_GLOAS: gloasForkRelevant,
355
+ CONSOLIDATION_CHURN_LIMIT_QUOTIENT: gloasForkRelevant,
356
+ MAX_PER_EPOCH_ACTIVATION_CHURN_LIMIT_GLOAS: gloasForkRelevant,
357
+ };
358
+ }
@@ -50,6 +50,9 @@ export type ChainConfig = {
50
50
  // GLOAS
51
51
  GLOAS_FORK_VERSION: Uint8Array;
52
52
  GLOAS_FORK_EPOCH: number;
53
+ // HEZE
54
+ HEZE_FORK_VERSION: Uint8Array;
55
+ HEZE_FORK_EPOCH: number;
53
56
 
54
57
  // Time parameters
55
58
  /** @deprecated Use `SLOT_DURATION_MS` instead. */
@@ -74,6 +77,8 @@ export type ChainConfig = {
74
77
  PAYLOAD_ATTESTATION_DUE_BPS: number;
75
78
  PAYLOAD_DUE_BPS: number;
76
79
 
80
+ INCLUSION_LIST_DUE_BPS: number;
81
+
77
82
  // Validator cycle
78
83
  INACTIVITY_SCORE_BIAS: number;
79
84
  INACTIVITY_SCORE_RECOVERY_RATE: number;
@@ -133,6 +138,11 @@ export type ChainConfig = {
133
138
  // Blob Scheduling
134
139
  BLOB_SCHEDULE: BlobSchedule;
135
140
 
141
+ // HEZE
142
+ MAX_REQUEST_INCLUSION_LIST: number;
143
+ MIN_SLOTS_FOR_INCLUSION_LISTS_REQUESTS: number;
144
+ MAX_BYTES_PER_INCLUSION_LIST: number;
145
+
136
146
  // Fast Confirmation Rule
137
147
  CONFIRMATION_BYZANTINE_THRESHOLD: number;
138
148
  };
@@ -174,6 +184,9 @@ export const chainConfigTypes: SpecTypes<ChainConfig> = {
174
184
  // GLOAS
175
185
  GLOAS_FORK_VERSION: "bytes",
176
186
  GLOAS_FORK_EPOCH: "number",
187
+ // HEZE
188
+ HEZE_FORK_VERSION: "bytes",
189
+ HEZE_FORK_EPOCH: "number",
177
190
 
178
191
  // Time parameters
179
192
  SECONDS_PER_SLOT: "number",
@@ -197,6 +210,8 @@ export const chainConfigTypes: SpecTypes<ChainConfig> = {
197
210
  PAYLOAD_ATTESTATION_DUE_BPS: "number",
198
211
  PAYLOAD_DUE_BPS: "number",
199
212
 
213
+ INCLUSION_LIST_DUE_BPS: "number",
214
+
200
215
  // Validator cycle
201
216
  INACTIVITY_SCORE_BIAS: "number",
202
217
  INACTIVITY_SCORE_RECOVERY_RATE: "number",
@@ -250,6 +265,11 @@ export const chainConfigTypes: SpecTypes<ChainConfig> = {
250
265
  VALIDATOR_CUSTODY_REQUIREMENT: "number",
251
266
  BALANCE_PER_ADDITIONAL_CUSTODY_GROUP: "number",
252
267
 
268
+ // HEZE
269
+ MAX_REQUEST_INCLUSION_LIST: "number",
270
+ MIN_SLOTS_FOR_INCLUSION_LISTS_REQUESTS: "number",
271
+ MAX_BYTES_PER_INCLUSION_LIST: "number",
272
+
253
273
  // Gloas
254
274
  MAX_REQUEST_PAYLOADS: "number",
255
275
 
@@ -85,10 +85,18 @@ export function createForkConfig(config: ChainConfig): ForkConfig {
85
85
  prevVersion: config.FULU_FORK_VERSION,
86
86
  prevForkName: ForkName.fulu,
87
87
  };
88
+ const heze: ForkInfo = {
89
+ name: ForkName.heze,
90
+ seq: ForkSeq.heze,
91
+ epoch: config.HEZE_FORK_EPOCH,
92
+ version: config.HEZE_FORK_VERSION,
93
+ prevVersion: config.GLOAS_FORK_VERSION,
94
+ prevForkName: ForkName.gloas,
95
+ };
88
96
 
89
97
  /** Forks in order order of occurence, `phase0` first */
90
98
  // Note: Downstream code relies on proper ordering.
91
- const forks = {phase0, altair, bellatrix, capella, deneb, electra, fulu, gloas};
99
+ const forks = {phase0, altair, bellatrix, capella, deneb, electra, fulu, gloas, heze};
92
100
 
93
101
  // Prevents allocating an array on every getForkInfo() call
94
102
  const forksAscendingEpochOrder = Object.values(forks);
@@ -60,5 +60,17 @@ export function getConfig(fork: ForkName, forkEpoch = 0): ChainForkConfig {
60
60
  GLOAS_FORK_EPOCH: forkEpoch,
61
61
  BLOB_SCHEDULE: [],
62
62
  });
63
+ case ForkName.heze:
64
+ return createChainForkConfig({
65
+ ALTAIR_FORK_EPOCH: 0,
66
+ BELLATRIX_FORK_EPOCH: 0,
67
+ CAPELLA_FORK_EPOCH: 0,
68
+ DENEB_FORK_EPOCH: 0,
69
+ ELECTRA_FORK_EPOCH: 0,
70
+ FULU_FORK_EPOCH: 0,
71
+ GLOAS_FORK_EPOCH: 0,
72
+ HEZE_FORK_EPOCH: forkEpoch,
73
+ BLOB_SCHEDULE: [],
74
+ });
63
75
  }
64
76
  }