UNPKG

@lodestar/config

Version:

Chain configuration required for lodestar

209 lines 8.55 kB
import { BASIS_POINTS, ForkName, ForkSeq, GENESIS_EPOCH, SLOTS_PER_EPOCH, isForkPostAltair, isForkPostBellatrix, isForkPostDeneb, isForkPostGloas, } from "@lodestar/params"; import { sszTypesFor } from "@lodestar/types"; export * from "./types.js"; export function createForkConfig(config) { const phase0 = { name: ForkName.phase0, seq: ForkSeq.phase0, epoch: GENESIS_EPOCH, version: config.GENESIS_FORK_VERSION, // Will never be used prevVersion: config.GENESIS_FORK_VERSION, prevForkName: ForkName.phase0, }; const altair = { name: ForkName.altair, seq: ForkSeq.altair, epoch: config.ALTAIR_FORK_EPOCH, version: config.ALTAIR_FORK_VERSION, prevVersion: config.GENESIS_FORK_VERSION, prevForkName: ForkName.phase0, }; const bellatrix = { name: ForkName.bellatrix, seq: ForkSeq.bellatrix, epoch: config.BELLATRIX_FORK_EPOCH, version: config.BELLATRIX_FORK_VERSION, prevVersion: config.ALTAIR_FORK_VERSION, prevForkName: ForkName.altair, }; const capella = { name: ForkName.capella, seq: ForkSeq.capella, epoch: config.CAPELLA_FORK_EPOCH, version: config.CAPELLA_FORK_VERSION, prevVersion: config.BELLATRIX_FORK_VERSION, prevForkName: ForkName.bellatrix, }; const deneb = { name: ForkName.deneb, seq: ForkSeq.deneb, epoch: config.DENEB_FORK_EPOCH, version: config.DENEB_FORK_VERSION, prevVersion: config.CAPELLA_FORK_VERSION, prevForkName: ForkName.capella, }; const electra = { name: ForkName.electra, seq: ForkSeq.electra, epoch: config.ELECTRA_FORK_EPOCH, version: config.ELECTRA_FORK_VERSION, prevVersion: config.DENEB_FORK_VERSION, prevForkName: ForkName.deneb, }; const fulu = { name: ForkName.fulu, seq: ForkSeq.fulu, epoch: config.FULU_FORK_EPOCH, version: config.FULU_FORK_VERSION, prevVersion: config.ELECTRA_FORK_VERSION, prevForkName: ForkName.electra, }; const gloas = { 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, gloas }; // Prevents allocating an array on every getForkInfo() call const forksAscendingEpochOrder = Object.values(forks); const forksDescendingEpochOrder = Object.values(forks).reverse(); const blobScheduleDescendingEpochOrder = [...config.BLOB_SCHEDULE].sort((a, b) => b.EPOCH - a.EPOCH); const forkBoundariesAscendingEpochOrder = [ // Normal hard-forks (phase0, altair, etc.) ...forksAscendingEpochOrder.map((fork) => ({ fork: fork.name, epoch: fork.epoch, })), // Blob Parameter Only (BPO) forks // Note: Must be appended after normal hard-forks to have precedence if scheduled at the same epoch ...config.BLOB_SCHEDULE.map((entry) => ({ fork: forksDescendingEpochOrder.find((f) => entry.EPOCH >= f.epoch)?.name ?? phase0.name, epoch: entry.EPOCH, })), ] // Remove unscheduled fork boundaries .filter(({ epoch }) => epoch !== Infinity) // Sort by epoch in ascending order .sort((a, b) => a.epoch - b.epoch); const forkBoundariesDescendingEpochOrder = [...forkBoundariesAscendingEpochOrder].reverse(); return { forks, forksAscendingEpochOrder, forksDescendingEpochOrder, forkBoundariesAscendingEpochOrder, forkBoundariesDescendingEpochOrder, // Fork convenience methods getForkInfo(slot) { const epoch = Math.floor(Math.max(slot, 0) / SLOTS_PER_EPOCH); return this.getForkInfoAtEpoch(epoch); }, getForkInfoAtEpoch(epoch) { return forks[this.getForkBoundaryAtEpoch(epoch).fork]; }, getForkBoundaryAtEpoch(epoch) { if (epoch < 0) epoch = 0; // NOTE: fork boundaries must be sorted by descending epoch, latest first for (const boundary of forkBoundariesDescendingEpochOrder) { if (epoch >= boundary.epoch) return boundary; } throw Error("Unreachable as phase0 is scheduled at epoch 0"); }, getForkName(slot) { return this.getForkInfo(slot).name; }, getForkSeq(slot) { return this.getForkInfo(slot).seq; }, getForkSeqAtEpoch(epoch) { return this.getForkInfoAtEpoch(epoch).seq; }, getForkVersion(slot) { return this.getForkInfo(slot).version; }, getForkTypes(slot) { return sszTypesFor(this.getForkName(slot)); }, getPostBellatrixForkTypes(slot) { const forkName = this.getForkName(slot); if (!isForkPostBellatrix(forkName)) { throw Error(`Invalid slot=${slot} fork=${forkName} for post-bellatrix fork types`); } return sszTypesFor(forkName); }, getPostAltairForkTypes(slot) { const forkName = this.getForkName(slot); if (!isForkPostAltair(forkName)) { throw Error(`Invalid slot=${slot} fork=${forkName} for post-altair fork types`); } return sszTypesFor(forkName); }, getPostDenebForkTypes(slot) { const forkName = this.getForkName(slot); if (!isForkPostDeneb(forkName)) { throw Error(`Invalid slot=${slot} fork=${forkName} for post-deneb fork types`); } return sszTypesFor(forkName); }, getMaxBlobsPerBlock(epoch) { const fork = this.getForkInfoAtEpoch(epoch).name; switch (fork) { case ForkName.electra: return config.MAX_BLOBS_PER_BLOCK_ELECTRA; case ForkName.deneb: return config.MAX_BLOBS_PER_BLOCK; } return this.getBlobParameters(epoch).maxBlobsPerBlock; }, getBlobParameters(epoch) { if (epoch < config.FULU_FORK_EPOCH) { throw Error(`getBlobParameters is not available pre-fulu epoch=${epoch}`); } // Find the latest applicable value from blob schedule for (const entry of blobScheduleDescendingEpochOrder) { if (epoch >= entry.EPOCH) { return { epoch: entry.EPOCH, maxBlobsPerBlock: entry.MAX_BLOBS_PER_BLOCK }; } } return { epoch: config.ELECTRA_FORK_EPOCH, maxBlobsPerBlock: config.MAX_BLOBS_PER_BLOCK_ELECTRA }; }, getAttestationDueMs(fork) { if (isForkPostGloas(fork)) { return this.getSlotComponentDurationMs(config.ATTESTATION_DUE_BPS_GLOAS); } return this.getSlotComponentDurationMs(config.ATTESTATION_DUE_BPS); }, getAggregateDueMs(fork) { if (isForkPostGloas(fork)) { return this.getSlotComponentDurationMs(config.AGGREGATE_DUE_BPS_GLOAS); } return this.getSlotComponentDurationMs(config.AGGREGATE_DUE_BPS); }, getSyncMessageDueMs(fork) { if (isForkPostGloas(fork)) { return this.getSlotComponentDurationMs(config.SYNC_MESSAGE_DUE_BPS_GLOAS); } return this.getSlotComponentDurationMs(config.SYNC_MESSAGE_DUE_BPS); }, getSyncContributionDueMs(fork) { if (isForkPostGloas(fork)) { return this.getSlotComponentDurationMs(config.CONTRIBUTION_DUE_BPS_GLOAS); } return this.getSlotComponentDurationMs(config.CONTRIBUTION_DUE_BPS); }, getProposerReorgCutoffMs(_fork) { return this.getSlotComponentDurationMs(config.PROPOSER_REORG_CUTOFF_BPS); }, getSlotComponentDurationMs(basisPoints) { return Math.round((basisPoints * config.SLOT_DURATION_MS) / BASIS_POINTS); }, }; } //# sourceMappingURL=index.js.map