@lodestar/beacon-node
Version:
A Typescript implementation of the beacon chain
81 lines • 3.41 kB
JavaScript
/**
* Subscribe topics to the new fork N epochs before the fork. Remove all subscriptions N epochs after the fork
*
* This lookahead ensures a smooth fork transition. During `FORK_EPOCH_LOOKAHEAD` both forks will be active.
*
* ```
* phase0 phase0 phase0 -
* - altair altair altair
* |----------|----------|----------|----------|
* 0 fork-2 fork fork+2 oo
* ```
*
* It the fork epochs are very close to each other there may more than two active at once
*
* ```
* f0 f0 f0 f0 f0 -
* - fa fa fa fa fa -
* - - fb fb fb fb fb
*
* forka-2 forka forka+2
* | | | |
* |----------|----------|----------|----------|
* 0 forkb-2 forkb forkb+2 oo
* ```
*/
export const FORK_EPOCH_LOOKAHEAD = 2;
/**
* Return the list of `ForkBoundary`s meant to be active at `epoch`
* @see FORK_EPOCH_LOOKAHEAD for details on when fork boundaries are considered 'active'
*/
export function getActiveForkBoundaries(config, epoch) {
const activeBoundaries = [];
const { forkBoundariesAscendingEpochOrder } = config;
for (let i = 0; i < forkBoundariesAscendingEpochOrder.length; i++) {
const currentForkBoundary = forkBoundariesAscendingEpochOrder[i];
const nextForkBoundary = forkBoundariesAscendingEpochOrder[i + 1];
const currentEpoch = currentForkBoundary.epoch;
const nextEpoch = nextForkBoundary !== undefined ? nextForkBoundary.epoch : Infinity;
// Edge case: If multiple fork boundaries start at the same epoch, only consider the latest one
if (currentEpoch === nextEpoch) {
continue;
}
if (epoch >= currentEpoch - FORK_EPOCH_LOOKAHEAD && epoch <= nextEpoch + FORK_EPOCH_LOOKAHEAD) {
activeBoundaries.push(currentForkBoundary);
}
}
return activeBoundaries;
}
/**
* Return the currentBoundary and nextBoundary given a fork/BPO schedule and `epoch`
*/
export function getCurrentAndNextForkBoundary(config, epoch) {
if (epoch < 0) {
epoch = 0;
}
// NOTE: fork boundaries are sorted by ascending epoch
const boundaries = config.forkBoundariesAscendingEpochOrder;
let currentBoundaryIdx = -1;
// findLastIndex
for (let i = 0; i < boundaries.length; i++) {
if (epoch >= boundaries[i].epoch)
currentBoundaryIdx = i;
}
let nextBoundaryIdx = currentBoundaryIdx + 1;
const hasNextBoundary = boundaries[nextBoundaryIdx] !== undefined && boundaries[nextBoundaryIdx].epoch !== Infinity;
// Keep moving the needle of nextBoundaryIdx if there the higher boundary also exists on same epoch
// for e.g. altair and bellatrix are on same epoch 6, next boundary should be bellatrix
if (hasNextBoundary) {
for (let i = nextBoundaryIdx + 1; i < boundaries.length; i++) {
// If the boundary's epoch is same as nextBoundaryIdx (which is not equal to infinity),
// update nextBoundaryIdx to the same
if (boundaries[i].epoch === boundaries[nextBoundaryIdx].epoch)
nextBoundaryIdx = i;
}
}
return {
currentBoundary: boundaries[currentBoundaryIdx] || boundaries[0],
nextBoundary: hasNextBoundary ? boundaries[nextBoundaryIdx] : undefined,
};
}
//# sourceMappingURL=forks.js.map