Skip to content

Commit

Permalink
Use consensus constants from fetched consensus spec
Browse files Browse the repository at this point in the history
  • Loading branch information
sealer3 committed Apr 21, 2024
1 parent 217981d commit 7fcee8a
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 23 deletions.
4 changes: 2 additions & 2 deletions src/consensus/epoch/LoadingSlotItem.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { FC, memo } from "react";
import ContentLoader from "react-content-loader";
import { slot2Epoch, useProposerMap } from "../../useConsensus";
import { useProposerMap, useSlotToEpoch } from "../../useConsensus";
import CheckedValidatorLink from "../components/CheckedValidatorLink";
import SlotLink from "../components/SlotLink";
import { SlotAwareComponentProps } from "../types";
import SlotTimestamp from "./SlotTimestamp";

const LoadingSlotItem: FC<SlotAwareComponentProps> = ({ slotNumber }) => {
const epochNumber = slot2Epoch(slotNumber);
const epochNumber = useSlotToEpoch(slotNumber);
const proposers = useProposerMap(epochNumber);
const expectedProposer = proposers && parseInt(proposers?.[slotNumber]);

Expand Down
4 changes: 2 additions & 2 deletions src/consensus/epoch/ScheduledOrMissedSlotItem.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { FC, memo } from "react";
import ContentLoader from "react-content-loader";
import { slot2Epoch, useProposerMap } from "../../useConsensus";
import { useProposerMap, useSlotToEpoch } from "../../useConsensus";
import CheckedValidatorLink from "../components/CheckedValidatorLink";
import SlotLink from "../components/SlotLink";
import { SlotAwareComponentProps } from "../types";
Expand All @@ -18,7 +18,7 @@ const ScheduledOrMissedSlotItem: FC<ScheduledOrMissedSlotItemProps> = ({
scheduled,
isValidating,
}) => {
const epochNumber = slot2Epoch(slotNumber);
const epochNumber = useSlotToEpoch(slotNumber);
const proposers = useProposerMap(epochNumber);
const expectedProposer = proposers && parseInt(proposers?.[slotNumber]);

Expand Down
4 changes: 2 additions & 2 deletions src/consensus/slot/Overview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import StandardTBody from "../../components/StandardTBody";
import StandardTHead from "../../components/StandardTHead";
import StandardTable from "../../components/StandardTable";
import Timestamp from "../../components/Timestamp";
import { slot2Epoch, useSlot, useSlotTimestamp } from "../../useConsensus";
import { useSlot, useSlotTimestamp, useSlotToEpoch } from "../../useConsensus";
import { usePageTitle } from "../../useTitle";
import CheckedValidatorLink from "../components/CheckedValidatorLink";
import EpochLink from "../components/EpochLink";
Expand All @@ -34,7 +34,7 @@ const Overview: FC = () => {
const { slot, error, isLoading } = useSlot(slotAsNumber);
usePageTitle(slotNumber === undefined ? undefined : `Slot #${slotNumber}`);

const epoch = slot2Epoch(slotAsNumber);
const epoch = useSlotToEpoch(slotAsNumber);
const slotTimestamp = useSlotTimestamp(slotAsNumber);

const graffiti = useMemo(() => {
Expand Down
91 changes: 74 additions & 17 deletions src/useConsensus.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,19 @@ import useSWRImmutable from "swr/immutable";
import { jsonFetcher, jsonFetcherWithErrorHandling } from "./fetcher";
import { RuntimeContext } from "./useRuntime";

// TODO: get these from config
export const SLOTS_PER_EPOCH = 32;
export const SECONDS_PER_SLOT = 12;
const DEFAULT_SLOTS_PER_EPOCH = 32;
const DEFAULT_SECONDS_PER_SLOT = 12;
export const EPOCHS_AFTER_HEAD = 1;

export const HEAD_SLOT_REFRESH_INTERVAL = 12 * 1000;
export const HEAD_EPOCH_REFRESH_INTERVAL = 60 * 1000;
export const FINALIZED_SLOT_REFRESH_INTERVAL = 60 * 1000;

export const slot2Epoch = (slotNumber: number) =>
Math.floor(slotNumber / SLOTS_PER_EPOCH);
function toNumberWithDefault(item: any, defaultVal: number): number {
if (item === undefined || item === null) {
return defaultVal;
}
return Number(item);
}

const useGenesisURL = () => {
const { config } = useContext(RuntimeContext);
Expand All @@ -28,10 +30,7 @@ export const useGenesisTime = (): number | undefined => {
const url = useGenesisURL();
const { data, error } = useSWRImmutable(url, jsonFetcher);

if (!error && !data) {
return undefined;
}
if (error) {
if (error || !data) {
return undefined;
}

Expand All @@ -58,6 +57,37 @@ export const useGenesisTime = (): number | undefined => {
return genesisTime;
};

const useBeaconSpecURL = () => {
const { config } = useContext(RuntimeContext);
if (config?.beaconAPI === undefined) {
return null;
}
return `${config.beaconAPI}/eth/v1/config/spec`;
};

export const useBeaconSpec = (): Record<string, string> | undefined => {
const url = useBeaconSpecURL();
const { data, error } = useSWRImmutable(url, jsonFetcher);
if (
error ||
!data ||
typeof data !== "object" ||
!data.data ||
typeof data.data !== "object"
) {
return undefined;
}
return data.data as Record<string, string>;
};

export const useSlotToEpoch = (slotNumber: number): number => {
const slotsPerEpochStr = useBeaconSpec()?.SLOTS_PER_EPOCH;
const slotsPerEpoch: number = slotsPerEpochStr
? Number(slotsPerEpochStr)
: DEFAULT_SLOTS_PER_EPOCH;
return Math.floor(slotNumber / slotsPerEpoch);
};

const useBeaconHeaderURL = (tag: string) => {
const { config } = useContext(RuntimeContext);
if (config?.beaconAPI === undefined) {
Expand Down Expand Up @@ -181,9 +211,13 @@ export const useValidator = (validatorIndex: number | string) => {
};

export const useSlotsFromEpoch = (epochNumber: number): number[] => {
const slotsPerEpoch = toNumberWithDefault(
useBeaconSpec()?.SLOTS_PER_EPOCH,
DEFAULT_SLOTS_PER_EPOCH,
);
const slots = useMemo(() => {
const startSlot = epochNumber * SLOTS_PER_EPOCH;
const endSlot = startSlot + SLOTS_PER_EPOCH - 1;
const startSlot = epochNumber * slotsPerEpoch;
const endSlot = startSlot + slotsPerEpoch - 1;

const s: number[] = [];
for (let i = startSlot; i <= endSlot; i++) {
Expand Down Expand Up @@ -251,26 +285,40 @@ export const useProposerMap = (epochNumber: number) => {
const MAX_EPOCH = "18446744073709551615";

export const useEpochTimestamp = (epoch: any) => {
const beaconSpec = useBeaconSpec();
const slotsPerEpoch = toNumberWithDefault(
beaconSpec?.SLOTS_PER_EPOCH,
DEFAULT_SLOTS_PER_EPOCH,
);
const secondsPerSlot = toNumberWithDefault(
beaconSpec?.SECONDS_PER_SLOT,
DEFAULT_SECONDS_PER_SLOT,
);
const genesisTime = useGenesisTime();
if (epoch === undefined || genesisTime === undefined) {
return undefined;
}
if (epoch === MAX_EPOCH) {
return undefined;
}
return genesisTime + epoch * SLOTS_PER_EPOCH * SECONDS_PER_SLOT;
return genesisTime + epoch * slotsPerEpoch * secondsPerSlot;
};

export const useSlotTimestamp = (slot: number | undefined) => {
const genesisTime = useGenesisTime();
const beaconSpec = useBeaconSpec();
const secondsPerSlot = toNumberWithDefault(
beaconSpec?.SECONDS_PER_SLOT,
DEFAULT_SECONDS_PER_SLOT,
);
if (slot === undefined || genesisTime === undefined) {
return undefined;
}
return genesisTime + slot * SECONDS_PER_SLOT;
return genesisTime + slot * secondsPerSlot;
};

export const useCommittee = (slotNumber: number, committeeIndex: number) => {
const epochNumber = slot2Epoch(slotNumber);
const epochNumber = useSlotToEpoch(slotNumber);
const url = useCommitteeURL(epochNumber, slotNumber, committeeIndex);
const { data, error } = useSWRImmutable(url, jsonFetcherWithErrorHandling);
if (error) {
Expand Down Expand Up @@ -340,8 +388,17 @@ const parseSlotNumber = (slot: unknown): number | undefined => {

// TODO: useMemo
export const useHeadSlotNumber = (
refreshInterval: number = HEAD_SLOT_REFRESH_INTERVAL,
refreshInterval?: number,
): number | undefined => {
const beaconSpec = useBeaconSpec();
const defaultRefreshInterval =
toNumberWithDefault(
beaconSpec?.SECONDS_PER_SLOT,
DEFAULT_SECONDS_PER_SLOT,
) * 1000;
if (refreshInterval === undefined) {
refreshInterval = defaultRefreshInterval;
}
const slot = useDynamicHeader("head", refreshInterval);
return parseSlotNumber(slot);
};
Expand All @@ -360,5 +417,5 @@ export const useHeadEpochNumber = (
if (headSlot === undefined) {
return undefined;
}
return slot2Epoch(headSlot);
return useSlotToEpoch(headSlot);
};

0 comments on commit 7fcee8a

Please sign in to comment.