feat: add gloas fork definition (#8222)

Add boilerplate code for gloas
This commit is contained in:
NC
2025-08-19 01:57:04 -07:00
committed by GitHub
parent 1968319c71
commit 8d743ffafc
29 changed files with 231 additions and 3 deletions

View File

@@ -8,6 +8,7 @@ import {
CachedBeaconStateCapella,
CachedBeaconStateDeneb,
CachedBeaconStateElectra,
CachedBeaconStateFulu,
CachedBeaconStatePhase0,
} from "@lodestar/state-transition";
import * as slotFns from "@lodestar/state-transition/slot";
@@ -41,6 +42,8 @@ const fork: TestRunnerFn<ForkStateCase, BeaconStateAllForks> = (forkNext) => {
return slotFns.upgradeStateToElectra(preState as CachedBeaconStateDeneb);
case ForkName.fulu:
return slotFns.upgradeStateToFulu(preState as CachedBeaconStateElectra);
case ForkName.gloas:
return slotFns.upgradeStateToGloas(preState as CachedBeaconStateFulu);
}
},
options: {

View File

@@ -117,6 +117,16 @@ function getTransitionConfig(fork: ForkName, forkEpoch: number): Partial<ChainCo
ELECTRA_FORK_EPOCH: 0,
FULU_FORK_EPOCH: forkEpoch,
};
case ForkName.gloas:
return {
ALTAIR_FORK_EPOCH: 0,
BELLATRIX_FORK_EPOCH: 0,
CAPELLA_FORK_EPOCH: 0,
DENEB_FORK_EPOCH: 0,
ELECTRA_FORK_EPOCH: 0,
FULU_FORK_EPOCH: 0,
GLOAS_FORK_EPOCH: forkEpoch,
};
}
}

View File

@@ -17,12 +17,14 @@ const CAPELLA_FORK_EPOCH = 0;
const DENEB_FORK_EPOCH = 1;
const ELECTRA_FORK_EPOCH = 2;
const FULU_FORK_EPOCH = 3;
const GLOAS_FORK_EPOCH = 4;
const config = createChainForkConfig({
...defaultChainConfig,
CAPELLA_FORK_EPOCH,
DENEB_FORK_EPOCH,
ELECTRA_FORK_EPOCH,
FULU_FORK_EPOCH,
GLOAS_FORK_EPOCH,
});
const slots: Record<ForkPostCapella, number> = {
@@ -30,6 +32,7 @@ const slots: Record<ForkPostCapella, number> = {
deneb: computeStartSlotAtEpoch(DENEB_FORK_EPOCH),
electra: computeStartSlotAtEpoch(ELECTRA_FORK_EPOCH),
fulu: computeStartSlotAtEpoch(FULU_FORK_EPOCH),
gloas: computeStartSlotAtEpoch(GLOAS_FORK_EPOCH),
};
type BlockTestSet<F extends ForkPostCapella> = {

View File

@@ -16,6 +16,7 @@ describe("UpgradeLightClientHeader", () => {
DENEB_FORK_EPOCH: 4,
ELECTRA_FORK_EPOCH: 5,
FULU_FORK_EPOCH: 6,
GLOAS_FORK_EPOCH: 7,
});
const genesisValidatorsRoot = Buffer.alloc(32, 0xaa);
@@ -30,6 +31,7 @@ describe("UpgradeLightClientHeader", () => {
deneb: ssz.deneb.LightClientHeader.defaultValue(),
electra: ssz.deneb.LightClientHeader.defaultValue(),
fulu: ssz.deneb.LightClientHeader.defaultValue(),
gloas: ssz.deneb.LightClientHeader.defaultValue(),
};
testSlots = {
@@ -40,6 +42,7 @@ describe("UpgradeLightClientHeader", () => {
deneb: 132,
electra: 164,
fulu: 216,
gloas: 235,
};
});

View File

@@ -24,12 +24,14 @@ describe("SeenBlockInputCache", () => {
const DENEB_FORK_EPOCH = 1;
const ELECTRA_FORK_EPOCH = 2;
const FULU_FORK_EPOCH = 3;
const GLOAS_FORK_EPOCH = 4;
const config = createChainForkConfig({
...defaultChainConfig,
CAPELLA_FORK_EPOCH,
DENEB_FORK_EPOCH,
ELECTRA_FORK_EPOCH,
FULU_FORK_EPOCH,
GLOAS_FORK_EPOCH,
});
const slots: Record<ForkPostCapella, number> = {
@@ -37,6 +39,7 @@ describe("SeenBlockInputCache", () => {
deneb: computeStartSlotAtEpoch(DENEB_FORK_EPOCH),
electra: computeStartSlotAtEpoch(ELECTRA_FORK_EPOCH),
fulu: computeStartSlotAtEpoch(FULU_FORK_EPOCH),
gloas: computeStartSlotAtEpoch(GLOAS_FORK_EPOCH),
};
type BlockTestSet<F extends ForkPostCapella> = {

View File

@@ -11,6 +11,7 @@ function getForkConfig({
deneb,
electra,
fulu,
gloas,
}: {
phase0: number;
altair: number;
@@ -19,6 +20,7 @@ function getForkConfig({
deneb: number;
electra: number;
fulu: number;
gloas: number;
}): BeaconConfig {
const forks: Record<ForkName, ForkInfo> = {
phase0: {
@@ -77,6 +79,14 @@ function getForkConfig({
prevVersion: Buffer.from([0, 0, 0, 5]),
prevForkName: ForkName.electra,
},
gloas: {
name: ForkName.gloas,
seq: ForkSeq.gloas,
epoch: gloas,
version: Buffer.from([0, 0, 0, 7]),
prevVersion: Buffer.from([0, 0, 0, 6]),
prevForkName: ForkName.fulu,
},
};
const forksAscendingEpochOrder = Object.values(forks);
const forksDescendingEpochOrder = Object.values(forks).reverse();
@@ -160,9 +170,10 @@ for (const testScenario of testScenarios) {
const deneb = Infinity;
const electra = Infinity;
const fulu = Infinity;
const gloas = Infinity;
describe(`network / fork: phase0: ${phase0}, altair: ${altair}, bellatrix: ${bellatrix} capella: ${capella}`, () => {
const forkConfig = getForkConfig({phase0, altair, bellatrix, capella, deneb, electra, fulu});
const forkConfig = getForkConfig({phase0, altair, bellatrix, capella, deneb, electra, fulu, gloas});
const forks = forkConfig.forks;
for (const testCase of testCases) {
const {epoch, currentFork, nextFork, activeForks} = testCase;

View File

@@ -48,5 +48,16 @@ export function getConfig(fork: ForkName, forkEpoch = 0): ChainForkConfig {
FULU_FORK_EPOCH: forkEpoch,
BLOB_SCHEDULE: [],
});
case ForkName.gloas:
return createChainForkConfig({
ALTAIR_FORK_EPOCH: 0,
BELLATRIX_FORK_EPOCH: 0,
CAPELLA_FORK_EPOCH: 0,
DENEB_FORK_EPOCH: 0,
ELECTRA_FORK_EPOCH: 0,
FULU_FORK_EPOCH: 0,
GLOAS_FORK_EPOCH: forkEpoch,
BLOB_SCHEDULE: [],
});
}
}

View File

@@ -56,6 +56,10 @@ export const chainConfig: ChainConfig = {
FULU_FORK_VERSION: b("0x06000000"),
FULU_FORK_EPOCH: Infinity,
// GLOAS
GLOAS_FORK_VERSION: b("0x07000000"),
GLOAS_FORK_EPOCH: Infinity,
// Time parameters
// ---------------------------------------------------------------
// 12 seconds

View File

@@ -50,6 +50,9 @@ export const chainConfig: ChainConfig = {
// FULU
FULU_FORK_VERSION: b("0x06000001"),
FULU_FORK_EPOCH: Infinity,
// GLOAS
GLOAS_FORK_VERSION: b("0x07000001"),
GLOAS_FORK_EPOCH: Infinity,
// Time parameters
// ---------------------------------------------------------------

View File

@@ -44,6 +44,9 @@ export type ChainConfig = {
// FULU
FULU_FORK_VERSION: Uint8Array;
FULU_FORK_EPOCH: number;
// GLOAS
GLOAS_FORK_VERSION: Uint8Array;
GLOAS_FORK_EPOCH: number;
// Time parameters
SECONDS_PER_SLOT: number;
@@ -131,6 +134,9 @@ export const chainConfigTypes: SpecTypes<ChainConfig> = {
// FULU
FULU_FORK_VERSION: "bytes",
FULU_FORK_EPOCH: "number",
// GLOAS
GLOAS_FORK_VERSION: "bytes",
GLOAS_FORK_EPOCH: "number",
// Time parameters
SECONDS_PER_SLOT: "number",

View File

@@ -76,10 +76,18 @@ export function createForkConfig(config: ChainConfig): ForkConfig {
prevVersion: config.ELECTRA_FORK_VERSION,
prevForkName: ForkName.electra,
};
const gloas: ForkInfo = {
name: ForkName.gloas,
seq: ForkSeq.gloas,
epoch: config.GLOAS_FORK_EPOCH,
version: config.GLOAS_FORK_VERSION,
prevVersion: config.FULU_FORK_VERSION,
prevForkName: ForkName.fulu,
};
/** Forks in order order of occurence, `phase0` first */
// Note: Downstream code relies on proper ordering.
const forks = {phase0, altair, bellatrix, capella, deneb, electra, fulu};
const forks = {phase0, altair, bellatrix, capella, deneb, electra, fulu, gloas};
// Prevents allocating an array on every getForkInfo() call
const forksAscendingEpochOrder = Object.values(forks);

View File

@@ -141,11 +141,18 @@ export function upgradeLightClientHeader(
// Break if no further upgrades is required else fall through
if (ForkSeq[targetFork] <= ForkSeq.electra) break;
// biome-ignore lint/suspicious/noFallthroughSwitchClause: We need fall-through behavior here
case ForkName.fulu:
// No changes to LightClientHeader in Electra
// No changes to LightClientHeader in Fulu
// Break if no further upgrades is required else fall through
if (ForkSeq[targetFork] <= ForkSeq.fulu) break;
case ForkName.gloas:
// No changes to LightClientHeader in Gloas
// Break if no further upgrades is required else fall through
if (ForkSeq[targetFork] <= ForkSeq.gloas) break;
}
return upgradedHeader;
}

View File

@@ -9,6 +9,7 @@ export enum ForkName {
deneb = "deneb",
electra = "electra",
fulu = "fulu",
gloas = "gloas",
}
/**
@@ -22,6 +23,7 @@ export enum ForkSeq {
deneb = 4,
electra = 5,
fulu = 6,
gloas = 7,
}
function exclude<T extends ForkName, U extends T>(coll: T[], val: U[]): Exclude<T, U>[] {
@@ -110,6 +112,21 @@ export function isForkPostFulu(fork: ForkName): fork is ForkPostFulu {
return isForkPostElectra(fork) && fork !== ForkName.electra;
}
export type ForkPreGloas = ForkPreFulu | ForkName.fulu;
export type ForkPostGloas = Exclude<ForkName, ForkPreGloas>;
export const forkPostGloas = exclude(forkAll, [
ForkName.phase0,
ForkName.altair,
ForkName.bellatrix,
ForkName.capella,
ForkName.deneb,
ForkName.electra,
ForkName.fulu,
]);
export function isForkPostGloas(fork: ForkName): fork is ForkPostGloas {
return isForkPostFulu(fork) && fork !== ForkName.fulu;
}
/*
* Aliases only exported for backwards compatibility. This will be removed in
* lodestar v2.0. The types and guards above should be used in all places as

View File

@@ -55,6 +55,10 @@ async function downloadRemoteConfig(preset: "mainnet" | "minimal", commit: strin
const downloadedParams: Record<string, unknown>[] = [];
for (const forkName of Object.values(ForkName)) {
// TODO GLOAS: Remove this when gloas spec is available
if (forkName === ForkName.gloas) {
continue;
}
const response = await axios({
url: `https://raw.githubusercontent.com/ethereum/consensus-specs/${commit}/presets/${preset}/${forkName}.yaml`,
timeout: 30 * 1000,

View File

@@ -9,6 +9,7 @@ exports[`forkName > should have valid allForks 1`] = `
"deneb",
"electra",
"fulu",
"gloas",
]
`;
@@ -20,6 +21,7 @@ exports[`forkName > should have valid post-altair forks 1`] = `
"deneb",
"electra",
"fulu",
"gloas",
]
`;
@@ -30,6 +32,7 @@ exports[`forkName > should have valid post-bellatrix forks 1`] = `
"deneb",
"electra",
"fulu",
"gloas",
]
`;
@@ -39,6 +42,7 @@ exports[`forkName > should have valid post-capella forks 1`] = `
"deneb",
"electra",
"fulu",
"gloas",
]
`;
@@ -47,5 +51,6 @@ exports[`forkName > should have valid post-deneb forks 1`] = `
"deneb",
"electra",
"fulu",
"gloas",
]
`;

View File

@@ -12,6 +12,7 @@ import {
BeaconStateElectra,
BeaconStateExecutions,
BeaconStateFulu,
BeaconStateGloas,
BeaconStatePhase0,
} from "./types.js";
@@ -134,6 +135,7 @@ export type CachedBeaconStateCapella = CachedBeaconState<BeaconStateCapella>;
export type CachedBeaconStateDeneb = CachedBeaconState<BeaconStateDeneb>;
export type CachedBeaconStateElectra = CachedBeaconState<BeaconStateElectra>;
export type CachedBeaconStateFulu = CachedBeaconState<BeaconStateFulu>;
export type CachedBeaconStateGloas = CachedBeaconState<BeaconStateGloas>;
export type CachedBeaconStateAllForks = CachedBeaconState<BeaconStateAllForks>;
export type CachedBeaconStateExecutions = CachedBeaconState<BeaconStateExecutions>;

View File

@@ -10,6 +10,7 @@ export type BeaconStateCapella = CompositeViewDU<SSZTypesFor<ForkName.capella, "
export type BeaconStateDeneb = CompositeViewDU<SSZTypesFor<ForkName.deneb, "BeaconState">>;
export type BeaconStateElectra = CompositeViewDU<SSZTypesFor<ForkName.electra, "BeaconState">>;
export type BeaconStateFulu = CompositeViewDU<SSZTypesFor<ForkName.fulu, "BeaconState">>;
export type BeaconStateGloas = CompositeViewDU<SSZTypesFor<ForkName.gloas, "BeaconState">>;
export type BeaconStateAllForks = CompositeViewDU<SSZTypesFor<ForkAll, "BeaconState">>;
export type BeaconStateExecutions = CompositeViewDU<SSZTypesFor<ForkPostBellatrix, "BeaconState">>;

View File

@@ -9,6 +9,7 @@ export {upgradeStateToCapella} from "./upgradeStateToCapella.js";
export {upgradeStateToDeneb} from "./upgradeStateToDeneb.js";
export {upgradeStateToElectra} from "./upgradeStateToElectra.js";
export {upgradeStateToFulu} from "./upgradeStateToFulu.js";
export {upgradeStateToGloas} from "./upgradeStateToGloas.js";
/**
* Dial state to next slot. Common for all forks

View File

@@ -0,0 +1,29 @@
import {ssz} from "@lodestar/types";
import {getCachedBeaconState} from "../cache/stateCache.js";
import {CachedBeaconStateFulu, CachedBeaconStateGloas} from "../types.js";
/**
* Upgrade a state from Fulu to Gloas.
* TODO GLOAS: Implement this
*/
export function upgradeStateToGloas(stateFulu: CachedBeaconStateFulu): CachedBeaconStateGloas {
const {config} = stateFulu;
const stateFuluNode = ssz.fulu.BeaconState.commitViewDU(stateFulu);
const stateGloasView = ssz.fulu.BeaconState.getViewDU(stateFuluNode);
const stateGloas = getCachedBeaconState(stateGloasView, stateFulu);
stateGloas.fork = ssz.phase0.Fork.toViewDU({
previousVersion: stateFulu.fork.currentVersion,
currentVersion: config.GLOAS_FORK_VERSION,
epoch: stateFulu.epochCtx.epoch,
});
stateGloas.commit();
// Clear cache to ensure the cache of electra fields is not used by new fulu fields
// biome-ignore lint/complexity/useLiteralKeys: It is a protected attribute
stateGloas["clearCache"]();
return stateGloas;
}

View File

@@ -15,6 +15,7 @@ import {
upgradeStateToCapella,
upgradeStateToDeneb,
upgradeStateToElectra,
upgradeStateToGloas,
} from "./slot/index.js";
import {upgradeStateToFulu} from "./slot/upgradeStateToFulu.js";
import {
@@ -24,6 +25,7 @@ import {
CachedBeaconStateCapella,
CachedBeaconStateDeneb,
CachedBeaconStateElectra,
CachedBeaconStateFulu,
CachedBeaconStatePhase0,
} from "./types.js";
import {computeEpochAtSlot} from "./util/index.js";
@@ -273,6 +275,9 @@ function processSlotsWithTransientCache(
if (stateEpoch === config.FULU_FORK_EPOCH) {
postState = upgradeStateToFulu(postState as CachedBeaconStateElectra) as CachedBeaconStateAllForks;
}
if (stateEpoch === config.GLOAS_FORK_EPOCH) {
postState = upgradeStateToGloas(postState as CachedBeaconStateFulu) as CachedBeaconStateAllForks;
}
{
const timer = metrics?.epochTransitionStepTime.startTimer({step: EpochTransitionStep.finalProcessEpoch});

View File

@@ -11,6 +11,7 @@ export type {
CachedBeaconStateDeneb,
CachedBeaconStateElectra,
CachedBeaconStateFulu,
CachedBeaconStateGloas,
} from "./cache/stateCache.js";
export type {
@@ -23,4 +24,5 @@ export type {
BeaconStateDeneb,
BeaconStateElectra,
BeaconStateFulu,
BeaconStateGloas,
} from "./cache/types.js";

View File

@@ -329,6 +329,15 @@ export function initializeBeaconStateFromEth1(
ssz.fulu.ExecutionPayloadHeader.defaultViewDU();
}
if (fork >= ForkSeq.gloas) {
const stateFulu = state as CompositeViewDU<typeof ssz.gloas.BeaconState>;
stateFulu.fork.previousVersion = config.GLOAS_FORK_VERSION;
stateFulu.fork.currentVersion = config.GLOAS_FORK_VERSION;
stateFulu.latestExecutionPayloadHeader =
(executionPayloadHeader as CompositeViewDU<typeof ssz.gloas.ExecutionPayloadHeader>) ??
ssz.gloas.ExecutionPayloadHeader.defaultViewDU();
}
state.commit();
return state;

View File

@@ -87,5 +87,15 @@ function getConfig(fork: ForkName, forkEpoch = 0): ChainForkConfig {
ELECTRA_FORK_EPOCH: 0,
FULU_FORK_EPOCH: forkEpoch,
});
case ForkName.gloas:
return createChainForkConfig({
ALTAIR_FORK_EPOCH: 0,
BELLATRIX_FORK_EPOCH: 0,
CAPELLA_FORK_EPOCH: 0,
DENEB_FORK_EPOCH: 0,
ELECTRA_FORK_EPOCH: 0,
FULU_FORK_EPOCH: 0,
GLOAS_FORK_EPOCH: forkEpoch,
});
}
}

View File

@@ -0,0 +1,4 @@
export * from "./types.js";
import * as ssz from "./sszTypes.js";
import * as ts from "./types.js";
export {ts, ssz};

View File

@@ -0,0 +1,5 @@
import {ssz as fuluSsz} from "../fulu/index.js";
export const BeaconState = fuluSsz.BeaconState;
export const BeaconBlock = fuluSsz.BeaconBlock;
export const SignedBeaconBlock = fuluSsz.SignedBeaconBlock;

View File

@@ -0,0 +1,6 @@
import {ValueOf} from "@chainsafe/ssz";
import * as ssz from "./sszTypes.js";
export type BeaconBlock = ValueOf<typeof ssz.BeaconBlock>;
export type SignedBeaconBlock = ValueOf<typeof ssz.SignedBeaconBlock>;
export type BeaconState = ValueOf<typeof ssz.BeaconState>;

View File

@@ -6,6 +6,7 @@ import {ssz as capellaSsz} from "./capella/index.js";
import {ssz as denebSsz} from "./deneb/index.js";
import {ssz as electraSsz} from "./electra/index.js";
import {ssz as fuluSsz} from "./fulu/index.js";
import {ssz as gloasSsz} from "./gloas/index.js";
import {ssz as phase0Ssz} from "./phase0/index.js";
export * from "./primitive/sszTypes.js";
@@ -22,6 +23,16 @@ const typesByFork = {
[ForkName.deneb]: {...phase0Ssz, ...altairSsz, ...bellatrixSsz, ...capellaSsz, ...denebSsz},
[ForkName.electra]: {...phase0Ssz, ...altairSsz, ...bellatrixSsz, ...capellaSsz, ...denebSsz, ...electraSsz},
[ForkName.fulu]: {...phase0Ssz, ...altairSsz, ...bellatrixSsz, ...capellaSsz, ...denebSsz, ...electraSsz, ...fuluSsz},
[ForkName.gloas]: {
...phase0Ssz,
...altairSsz,
...bellatrixSsz,
...capellaSsz,
...denebSsz,
...electraSsz,
...fuluSsz,
...gloasSsz,
},
};
// Export these types to ensure that each fork is a superset of the previous one (with overridden types obviously)
@@ -34,6 +45,7 @@ export const capella = typesByFork[ForkName.capella];
export const deneb = typesByFork[ForkName.deneb];
export const electra = typesByFork[ForkName.electra];
export const fulu = typesByFork[ForkName.fulu];
export const gloas = typesByFork[ForkName.gloas];
/**
* A type of union of forks must accept as any parameter the UNION of all fork types.

View File

@@ -5,6 +5,7 @@ import {ts as capella} from "./capella/index.js";
import {ts as deneb} from "./deneb/index.js";
import {ts as electra} from "./electra/index.js";
import {ts as fulu} from "./fulu/index.js";
import {ts as gloas} from "./gloas/index.js";
import {ts as phase0} from "./phase0/index.js";
import {Slot} from "./primitive/types.js";
@@ -16,6 +17,7 @@ export {ts as capella} from "./capella/index.js";
export {ts as deneb} from "./deneb/index.js";
export {ts as electra} from "./electra/index.js";
export {ts as fulu} from "./fulu/index.js";
export {ts as gloas} from "./gloas/index.js";
/** Common non-spec type to represent roots as strings */
export type RootHex = string;
@@ -271,6 +273,44 @@ type TypesByFork = {
SignedAggregateAndProof: electra.SignedAggregateAndProof;
ExecutionRequests: electra.ExecutionRequests;
};
[ForkName.gloas]: {
BeaconBlockHeader: phase0.BeaconBlockHeader;
SignedBeaconBlockHeader: phase0.SignedBeaconBlockHeader;
BeaconBlock: gloas.BeaconBlock;
BeaconBlockBody: electra.BeaconBlockBody;
BeaconState: gloas.BeaconState;
SignedBeaconBlock: gloas.SignedBeaconBlock;
Metadata: fulu.Metadata;
Status: fulu.Status;
LightClientHeader: deneb.LightClientHeader;
LightClientBootstrap: electra.LightClientBootstrap;
LightClientUpdate: electra.LightClientUpdate;
LightClientFinalityUpdate: electra.LightClientFinalityUpdate;
LightClientOptimisticUpdate: electra.LightClientOptimisticUpdate;
LightClientStore: electra.LightClientStore;
BlindedBeaconBlock: electra.BlindedBeaconBlock;
BlindedBeaconBlockBody: electra.BlindedBeaconBlockBody;
SignedBlindedBeaconBlock: electra.SignedBlindedBeaconBlock;
ExecutionPayload: deneb.ExecutionPayload;
ExecutionPayloadHeader: deneb.ExecutionPayloadHeader;
BuilderBid: electra.BuilderBid;
SignedBuilderBid: electra.SignedBuilderBid;
SSEPayloadAttributes: electra.SSEPayloadAttributes;
BlockContents: fulu.BlockContents;
SignedBlockContents: fulu.SignedBlockContents;
ExecutionPayloadAndBlobsBundle: deneb.ExecutionPayloadAndBlobsBundle;
BlobsBundle: fulu.BlobsBundle;
SyncCommittee: altair.SyncCommittee;
SyncAggregate: altair.SyncAggregate;
SingleAttestation: electra.SingleAttestation;
Attestation: electra.Attestation;
IndexedAttestation: electra.IndexedAttestation;
IndexedAttestationBigint: electra.IndexedAttestationBigint;
AttesterSlashing: electra.AttesterSlashing;
AggregateAndProof: electra.AggregateAndProof;
SignedAggregateAndProof: electra.SignedAggregateAndProof;
ExecutionRequests: electra.ExecutionRequests;
};
};
export type TypesFor<F extends ForkName, K extends keyof TypesByFork[F] | void = void> = K extends void

View File

@@ -102,6 +102,7 @@ function getSpecCriticalParams(localConfig: ChainConfig): Record<keyof ConfigWit
const denebForkRelevant = localConfig.DENEB_FORK_EPOCH < Infinity;
const electraForkRelevant = localConfig.ELECTRA_FORK_EPOCH < Infinity;
const fuluForkRelevant = localConfig.FULU_FORK_EPOCH < Infinity;
const gloasForkRelevant = localConfig.GLOAS_FORK_EPOCH < Infinity;
return {
// # Config
@@ -140,6 +141,9 @@ function getSpecCriticalParams(localConfig: ChainConfig): Record<keyof ConfigWit
// fulu
FULU_FORK_VERSION: fuluForkRelevant,
FULU_FORK_EPOCH: fuluForkRelevant,
// gloas
GLOAS_FORK_VERSION: gloasForkRelevant,
GLOAS_FORK_EPOCH: gloasForkRelevant,
// Time parameters
SECONDS_PER_SLOT: true,