Skip to content

Commit

Permalink
Use enum for ForkName (#2428)
Browse files Browse the repository at this point in the history
* Use enum for ForkName

* Use groupByFork util to remove type castings to ForkName

* Update unit tests
  • Loading branch information
dapplion committed Apr 26, 2021
1 parent 822cf2d commit 8e1f5b0
Show file tree
Hide file tree
Showing 24 changed files with 141 additions and 154 deletions.
5 changes: 3 additions & 2 deletions packages/beacon-state-transition/src/fast/stateTransition.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import {ForkName} from "@chainsafe/lodestar-config";
import {allForks, phase0} from "@chainsafe/lodestar-types";
import {processBlock, processSlots} from "../phase0/fast";
import {verifyProposerSignature} from "./signatureSets";
Expand Down Expand Up @@ -27,7 +28,7 @@ export function fastStateTransition(

// process slots (including those with no blocks) since block
switch (preFork) {
case "phase0":
case ForkName.phase0:
processSlots(postState as CachedBeaconState<phase0.BeaconState>, block.slot);
break;
default:
Expand All @@ -46,7 +47,7 @@ export function fastStateTransition(

// process block
switch (blockFork) {
case "phase0":
case ForkName.phase0:
processBlock(postState as CachedBeaconState<phase0.BeaconState>, block as phase0.BeaconBlock, verifySignatures);
break;
default:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import {ForkName} from "@chainsafe/lodestar-config";
import {List, readonlyValues} from "@chainsafe/ssz";
import {Epoch, ValidatorIndex, Gwei, phase0, allForks} from "@chainsafe/lodestar-types";
import {intDiv} from "@chainsafe/lodestar-utils";
Expand Down Expand Up @@ -230,7 +231,7 @@ export function prepareEpochProcessState<T extends allForks.BeaconState>(state:
}
}
};
if (forkName === "phase0") {
if (forkName === ForkName.phase0) {
statusProcessEpoch(
out.statuses,
((state as unknown) as CachedBeaconState<phase0.BeaconState>).previousEpochAttestations,
Expand Down
4 changes: 2 additions & 2 deletions packages/beacon-state-transition/src/util/fork.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {Version, Root, phase0, ForkDigest} from "@chainsafe/lodestar-types";
import {IBeaconConfig, IForkName} from "@chainsafe/lodestar-config";
import {IBeaconConfig, ForkName} from "@chainsafe/lodestar-config";
import {byteArrayEquals, toHexString} from "@chainsafe/ssz";

/**
Expand All @@ -26,7 +26,7 @@ export function computeForkNameFromForkDigest(
config: IBeaconConfig,
genesisValidatorsRoot: Root,
forkDigest: ForkDigest
): IForkName {
): ForkName {
for (const {name, version} of Object.values(config.getForkInfoRecord())) {
if (
byteArrayEquals(forkDigest as Uint8Array, computeForkDigest(config, version, genesisValidatorsRoot) as Uint8Array)
Expand Down
14 changes: 7 additions & 7 deletions packages/config/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {GENESIS_SLOT, IBeaconParams} from "@chainsafe/lodestar-params";
import {createIBeaconSSZTypes, IAllForksSSZTypes, Slot, Version} from "@chainsafe/lodestar-types";

import {IBeaconConfig, IForkInfo, IForkName} from "./interface";
import {IBeaconConfig, IForkInfo, ForkName} from "./interface";

export * from "./interface";

Expand All @@ -10,25 +10,25 @@ export function createIBeaconConfig(params: IBeaconParams): IBeaconConfig {
return {
params,
types,
getForkInfoRecord(): Record<IForkName, IForkInfo> {
getForkInfoRecord(): Record<ForkName, IForkInfo> {
return {
phase0: {
name: "phase0",
name: ForkName.phase0,
slot: GENESIS_SLOT,
version: params.GENESIS_FORK_VERSION,
},
altair: {
name: "altair",
name: ForkName.altair,
slot: params.ALTAIR_FORK_SLOT,
version: params.ALTAIR_FORK_VERSION,
},
};
},
getForkName(slot: Slot): IForkName {
getForkName(slot: Slot): ForkName {
if (slot < params.ALTAIR_FORK_SLOT) {
return "phase0";
return ForkName.phase0;
} else {
return "altair";
return ForkName.altair;
}
},
getForkVersion(slot: Slot): Version {
Expand Down
11 changes: 7 additions & 4 deletions packages/config/src/interface.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,25 @@
import {IBeaconParams} from "@chainsafe/lodestar-params";
import {IAllForksSSZTypes, IBeaconSSZTypes, Slot, Version} from "@chainsafe/lodestar-types";

export type IForkName = "phase0" | "altair";
export enum ForkName {
phase0 = "phase0",
altair = "altair",
}

export interface IForkInfo {
name: IForkName;
name: ForkName;
slot: Slot;
version: Version;
}

export interface IBeaconConfig {
params: IBeaconParams;
types: IBeaconSSZTypes;
getForkInfoRecord(): Record<IForkName, IForkInfo>;
getForkInfoRecord(): Record<ForkName, IForkInfo>;
/**
* Get the hard-fork name at a given slot
*/
getForkName(slot: Slot): IForkName;
getForkName(slot: Slot): ForkName;
/**
* Get the hard-fork version at a given slot
*/
Expand Down
4 changes: 2 additions & 2 deletions packages/lodestar/src/chain/chain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
computeStartSlotAtEpoch,
} from "@chainsafe/lodestar-beacon-state-transition";
import {phase0} from "@chainsafe/lodestar-beacon-state-transition";
import {IBeaconConfig, IForkName} from "@chainsafe/lodestar-config";
import {IBeaconConfig, ForkName} from "@chainsafe/lodestar-config";
import {IForkChoice} from "@chainsafe/lodestar-fork-choice";
import {allForks, ForkDigest, Number64, Root, Slot} from "@chainsafe/lodestar-types";
import {ILogger} from "@chainsafe/lodestar-utils";
Expand Down Expand Up @@ -262,7 +262,7 @@ export class BeaconChain implements IBeaconChain {
return computeForkDigest(this.config, state.fork.currentVersion, this.genesisValidatorsRoot);
}

getForkName(): IForkName {
getForkName(): ForkName {
return computeForkNameFromForkDigest(this.config, this.genesisValidatorsRoot, this.getForkDigest());
}

Expand Down
4 changes: 2 additions & 2 deletions packages/lodestar/src/chain/emitter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import StrictEventEmitter from "strict-event-emitter-types";

import {phase0, Epoch, Slot, Version, allForks} from "@chainsafe/lodestar-types";
import {IBlockSummary} from "@chainsafe/lodestar-fork-choice";
import {IForkName} from "@chainsafe/lodestar-config";
import {ForkName} from "@chainsafe/lodestar-config";
import {IBlockJob} from "./interface";
import {AttestationError, BlockError} from "./errors";
import {CachedBeaconState} from "@chainsafe/lodestar-beacon-state-transition";
Expand Down Expand Up @@ -118,7 +118,7 @@ export interface IChainEvents {
[ChainEvent.checkpoint]: (checkpoint: phase0.Checkpoint, state: CachedBeaconState<allForks.BeaconState>) => void;
[ChainEvent.justified]: (checkpoint: phase0.Checkpoint, state: CachedBeaconState<allForks.BeaconState>) => void;
[ChainEvent.finalized]: (checkpoint: phase0.Checkpoint, state: CachedBeaconState<allForks.BeaconState>) => void;
[ChainEvent.forkVersion]: (version: Version, fork: IForkName) => void;
[ChainEvent.forkVersion]: (version: Version, fork: ForkName) => void;

[ChainEvent.clockSlot]: (slot: Slot) => void;
[ChainEvent.clockEpoch]: (epoch: Epoch) => void;
Expand Down
6 changes: 3 additions & 3 deletions packages/lodestar/src/chain/interface.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {allForks, Number64, Root, Slot} from "@chainsafe/lodestar-types";
import {IForkName} from "@chainsafe/lodestar-config";
import {ForkName} from "@chainsafe/lodestar-config";
import {phase0, CachedBeaconState} from "@chainsafe/lodestar-beacon-state-transition";
import {IForkChoice} from "@chainsafe/lodestar-fork-choice";

Expand Down Expand Up @@ -75,9 +75,9 @@ export interface IBeaconChain {
*/
getForkDigest(): phase0.ForkDigest;
/**
* Get the IForkName from the head state
* Get the ForkName from the head state
*/
getForkName(): IForkName;
getForkName(): ForkName;
/**
* Get ENRForkID from the head state
*/
Expand Down
23 changes: 9 additions & 14 deletions packages/lodestar/src/db/repositories/block/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import {ContainerType} from "@chainsafe/ssz";
import {IBeaconConfig, IForkName} from "@chainsafe/lodestar-config";
import {IBeaconConfig, ForkName} from "@chainsafe/lodestar-config";
import {Bucket, IDatabaseController, Repository} from "@chainsafe/lodestar-db";
import {allForks, Slot} from "@chainsafe/lodestar-types";
import {GenericBlockRepository} from "./abstract";
import {groupByFork} from "../../../util/forkName";

/**
* Blocks by root
Expand All @@ -13,14 +14,14 @@ export class BlockRepository {
protected config: IBeaconConfig;
protected db: IDatabaseController<Buffer, Buffer>;

protected repositories: Map<IForkName, Repository<Uint8Array, allForks.SignedBeaconBlock>>;
protected repositories: Map<ForkName, Repository<Uint8Array, allForks.SignedBeaconBlock>>;

constructor(config: IBeaconConfig, db: IDatabaseController<Buffer, Buffer>) {
this.config = config;
this.db = db;
this.repositories = new Map([
[
"phase0",
ForkName.phase0,
new GenericBlockRepository(
config,
db,
Expand All @@ -29,7 +30,7 @@ export class BlockRepository {
),
],
[
"altair",
ForkName.altair,
new GenericBlockRepository(
config,
db,
Expand Down Expand Up @@ -61,21 +62,15 @@ export class BlockRepository {
}

async batchDelete(ids: {root: Uint8Array; slot: Slot}[]): Promise<void> {
const idsByFork = {} as Record<IForkName, Uint8Array[]>;
for (const {root, slot} of ids) {
const forkName = this.config.getForkName(slot);
if (!idsByFork[forkName]) idsByFork[forkName] = [];

idsByFork[forkName].push(root);
}
const idsByFork = groupByFork(this.config, ids, (id) => id.slot);
await Promise.all(
Object.keys(idsByFork).map((forkName) =>
this.getRepositoryByForkName(forkName as IForkName).batchDelete(idsByFork[forkName as IForkName])
Array.from(idsByFork.entries()).map(([forkName, idsInFork]) =>
this.getRepositoryByForkName(forkName).batchDelete(idsInFork.map((id) => id.root))
)
);
}

private getRepositoryByForkName(forkName: IForkName): Repository<Uint8Array, allForks.SignedBeaconBlock> {
private getRepositoryByForkName(forkName: ForkName): Repository<Uint8Array, allForks.SignedBeaconBlock> {
const repo = this.repositories.get(forkName);
if (!repo) {
throw new Error("No supported block repository for fork: " + forkName);
Expand Down
55 changes: 19 additions & 36 deletions packages/lodestar/src/db/repositories/blockArchive/index.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import {IBeaconConfig, IForkName} from "@chainsafe/lodestar-config";
import all from "it-all";
import {IBeaconConfig, ForkName} from "@chainsafe/lodestar-config";
import {IDatabaseController, Repository, IKeyValue, IFilterOptions, Bucket} from "@chainsafe/lodestar-db";
import {IBlockSummary} from "@chainsafe/lodestar-fork-choice";
import {Slot, Root, allForks} from "@chainsafe/lodestar-types";
import {IKeyValueSummary, IBlockFilterOptions, GenericBlockArchiveRepository} from "./abstract";
import {getRootIndexKey, getParentRootIndexKey} from "./db-index";
import {bytesToInt} from "@chainsafe/lodestar-utils";
import all from "it-all";
import {ContainerType} from "@chainsafe/ssz";
import {IKeyValueSummary, IBlockFilterOptions, GenericBlockArchiveRepository} from "./abstract";
import {getRootIndexKey, getParentRootIndexKey} from "./db-index";
import {groupByFork} from "../../../util/forkName";

export {IBlockFilterOptions} from "./abstract";

Expand All @@ -17,14 +18,14 @@ export class BlockArchiveRepository {
protected config: IBeaconConfig;
protected db: IDatabaseController<Buffer, Buffer>;

protected repositories: Map<IForkName, Repository<Slot, allForks.SignedBeaconBlock>>;
protected repositories: Map<ForkName, Repository<Slot, allForks.SignedBeaconBlock>>;

constructor(config: IBeaconConfig, db: IDatabaseController<Buffer, Buffer>) {
this.config = config;
this.db = db;
this.repositories = new Map([
[
"phase0",
ForkName.phase0,
new GenericBlockArchiveRepository(
config,
db,
Expand All @@ -33,7 +34,7 @@ export class BlockArchiveRepository {
),
],
[
"altair",
ForkName.altair,
new GenericBlockArchiveRepository(
config,
db,
Expand Down Expand Up @@ -72,38 +73,36 @@ export class BlockArchiveRepository {

async batchPut(items: Array<IKeyValue<Slot, allForks.SignedBeaconBlock>>): Promise<void> {
await Promise.all(
Object.entries(this.groupItemsByFork(items)).map(([forkName, items]) =>
this.getRepositoryByForkName(forkName as IForkName).batchPut(items)
Array.from(this.groupItemsByFork(items).entries()).map(([forkName, items]) =>
this.getRepositoryByForkName(forkName).batchPut(items)
)
);
}

async batchAdd(values: allForks.SignedBeaconBlock[]): Promise<void> {
await Promise.all(
Object.entries(this.groupValuesByFork(values)).map(([forkName, values]) =>
this.getRepositoryByForkName(forkName as IForkName).batchAdd(values)
Array.from(groupByFork(this.config, values, (block) => block.message.slot).entries()).map(([forkName, values]) =>
this.getRepositoryByForkName(forkName).batchAdd(values)
)
);
}

async batchPutBinary(items: Array<IKeyValueSummary<Slot, Buffer, IBlockSummary>>): Promise<void> {
await Promise.all(
Object.entries(this.groupItemsByFork(items)).map(([forkName, items]) =>
this.getRepositoryByForkName(forkName as IForkName).batchPutBinary(items)
Array.from(this.groupItemsByFork(items).entries()).map(([forkName, items]) =>
this.getRepositoryByForkName(forkName).batchPutBinary(items)
)
);
}

async *keysStream(opts?: IFilterOptions<Slot>): AsyncIterable<Slot> {
const repos = this.repositories.values();
for (const repo of repos) {
for (const repo of this.repositories.values()) {
yield* repo.keysStream(opts);
}
}

async *valuesStream(opts?: IBlockFilterOptions): AsyncIterable<allForks.SignedBeaconBlock> {
const repos = this.repositories.values();
for (const repo of repos) {
for (const repo of this.repositories.values()) {
yield* repo.valuesStream(opts);
}
}
Expand All @@ -112,7 +111,7 @@ export class BlockArchiveRepository {
return all(this.valuesStream(opts));
}

private getRepositoryByForkName(forkName: IForkName): Repository<Slot, allForks.SignedBeaconBlock> {
private getRepositoryByForkName(forkName: ForkName): Repository<Slot, allForks.SignedBeaconBlock> {
const repo = this.repositories.get(forkName);
if (!repo) {
throw new Error("No supported block archive repository for fork: " + forkName);
Expand All @@ -124,24 +123,8 @@ export class BlockArchiveRepository {
return this.getRepositoryByForkName(this.config.getForkName(slot));
}

private groupValuesByFork(values: allForks.SignedBeaconBlock[]): Record<IForkName, allForks.SignedBeaconBlock[]> {
const valuesByFork = {} as Record<IForkName, allForks.SignedBeaconBlock[]>;
for (const value of values) {
const forkName = this.config.getForkName(value.message.slot);
if (!valuesByFork[forkName]) valuesByFork[forkName] = [];
valuesByFork[forkName].push(value);
}
return valuesByFork;
}

private groupItemsByFork<T>(items: Array<IKeyValue<Slot, T>>): Record<IForkName, IKeyValue<Slot, T>[]> {
const itemsByFork = {} as Record<IForkName, IKeyValue<Slot, T>[]>;
for (const kv of items) {
const forkName = this.config.getForkName(kv.key);
if (!itemsByFork[forkName]) itemsByFork[forkName] = [];
itemsByFork[forkName].push(kv);
}
return itemsByFork;
private groupItemsByFork<T>(items: Array<IKeyValue<Slot, T>>): Map<ForkName, IKeyValue<Slot, T>[]> {
return groupByFork(this.config, items, (item) => item.key);
}

private parseSlot(slotBytes: Buffer | null): Slot | null {
Expand Down

0 comments on commit 8e1f5b0

Please sign in to comment.