import { phase0 , Slot , RootHex } from "@chainsafe/lodestar-types" ; import { toHexString } from "@chainsafe/ssz" ; /**
 * Stores checkpoints in a hybrid format:
 * - Original checkpoint for fast consumption in Lodestar's side
 * - Root in string hex for fast comparisions inside the fork-choice
 */ export type CheckpointWithHex = phase0 . Checkpoint & { rootHex : RootHex ; } ; /**
 * Approximates the `Store` in "Ethereum 2.0 Phase 0 -- Beacon Chain Fork Choice":
 *
 * https://github.com/ethereum/eth2.0-specs/blob/v0.12.2/specs/phase0/fork-choice.md#store
 *
 * ## Detail
 *
 * This is only an approximation for two reasons:
 *
 * - The actual block DAG in `ProtoArray`.
 * - `time` is represented using `Slot` instead of UNIX epoch `u64`.
 */ export interface IForkChoiceStore { currentSlot : Slot ; justifiedCheckpoint : CheckpointWithHex ; finalizedCheckpoint : CheckpointWithHex ; bestJustifiedCheckpoint : CheckpointWithHex ; } /**
 * IForkChoiceStore implementer which emits forkChoice events on updated justified and finalized checkpoints.
 */ export class ForkChoiceStore implements IForkChoiceStore { bestJustifiedCheckpoint : CheckpointWithHex ; private _justifiedCheckpoint : CheckpointWithHex ; private _finalizedCheckpoint : CheckpointWithHex ; constructor ( public currentSlot , justifiedCheckpoint , finalizedCheckpoint , private readonly events ? ) { this . _justifiedCheckpoint = toCheckpointWithHex ( justifiedCheckpoint ) ; this . _finalizedCheckpoint = toCheckpointWithHex ( finalizedCheckpoint ) ; this . bestJustifiedCheckpoint = this . _justifiedCheckpoint ; } get justifiedCheckpoint ( ) : CheckpointWithHex { return this . _justifiedCheckpoint ; } set justifiedCheckpoint ( checkpoint ) { const cp = toCheckpointWithHex ( checkpoint ) ; this . _justifiedCheckpoint = cp ; this . events ?. onJustified ( cp ) ; } get finalizedCheckpoint ( ) : CheckpointWithHex { return this . _finalizedCheckpoint ; } set finalizedCheckpoint ( checkpoint ) { const cp = toCheckpointWithHex ( checkpoint ) ; this . _finalizedCheckpoint = cp ; this . events ?. onFinalized ( cp ) ; } } export function toCheckpointWithHex ( checkpoint ) { const root = checkpoint . root . valueOf ( ) as Uint8Array ; return { epoch : checkpoint . epoch , root , rootHex : toHexString ( root ) , } ; } export function equalCheckpointWithHex ( a , b ) { return a . epoch === b . epoch && a . rootHex === b . rootHex ; }