Skip to content

Commit

Permalink
Add spec v2 types
Browse files Browse the repository at this point in the history
  • Loading branch information
dapplion committed Dec 24, 2021
1 parent dbd68cf commit f83802f
Show file tree
Hide file tree
Showing 24 changed files with 1,658 additions and 6 deletions.
4 changes: 0 additions & 4 deletions packages/ssz/src/v2/boolean.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,6 @@ export class BooleanType extends BasicType<boolean> {
readonly minLen = 1;
readonly maxLen = 1;

constructor() {
super();
}

get defaultValue(): boolean {
return false;
}
Expand Down
9 changes: 8 additions & 1 deletion packages/ssz/src/v2/container.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {Node, getNodesAtDepth, subtreeFillToContents, Tree} from "@chainsafe/persistent-merkle-tree";
import {IJsonOptions} from "../types";
import {SszErrorPath} from "../util/errorPath";
import {CompositeType, TreeView, Type, ValueOf} from "./abstract";
import {getContainerTreeViewClass} from "./containerTreeView";
Expand All @@ -20,6 +21,12 @@ type ContainerTreeViewTypeConstructor<Fields extends Record<string, Type<any>>>
new (type: ContainerType<Fields>, tree: Tree, inMutableMode?: boolean): ContainerTreeViewType<Fields>;
};

export interface IContainerOptions {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
casingMap?: Record<string, string>;
expectedCase?: IJsonOptions["case"];
}

export class ContainerType<Fields extends Record<string, Type<any>>> extends CompositeType<ValueOfFields<Fields>> {
// Immutable characteristics
readonly depth: number;
Expand All @@ -43,7 +50,7 @@ export class ContainerType<Fields extends Record<string, Type<any>>> extends Com
/** Cached TreeView constuctor with custom prototype for this Type's properties */
readonly TreeView: ContainerTreeViewTypeConstructor<Fields>;

constructor(readonly fields: Fields) {
constructor(readonly fields: Fields, opts?: IContainerOptions) {
super();

this.maxChunkCount = Object.keys(fields).length;
Expand Down
2 changes: 1 addition & 1 deletion packages/ssz/src/v2/uint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import {BasicType} from "./abstract";

/* eslint-disable @typescript-eslint/member-ordering */

export class UintType extends BasicType<number> {
export class NumberUintType extends BasicType<number> {
// Immutable characteristics
readonly byteLength: number;
readonly itemsPerChunk: number;
Expand Down
2 changes: 2 additions & 0 deletions packages/ssz/test/lodestarTypesV2/allForks/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * as ts from "./types";
export * as ssz from "./sszTypes";
33 changes: 33 additions & 0 deletions packages/ssz/test/lodestarTypesV2/allForks/sszTypes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/* eslint-disable @typescript-eslint/naming-convention */

import {ssz as phase0} from "../phase0";
import {ssz as altair} from "../altair";
import {ssz as merge} from "../merge";

/**
* Index the ssz types that differ by fork
* A record of AllForksSSZTypes indexed by fork
*/
export const allForks = {
phase0: {
BeaconBlockBody: phase0.BeaconBlockBody,
BeaconBlock: phase0.BeaconBlock,
SignedBeaconBlock: phase0.SignedBeaconBlock,
BeaconState: phase0.BeaconState,
Metadata: phase0.Metadata,
},
altair: {
BeaconBlockBody: altair.BeaconBlockBody,
BeaconBlock: altair.BeaconBlock,
SignedBeaconBlock: altair.SignedBeaconBlock,
BeaconState: altair.BeaconState,
Metadata: altair.Metadata,
},
merge: {
BeaconBlockBody: merge.BeaconBlockBody,
BeaconBlock: merge.BeaconBlock,
SignedBeaconBlock: merge.SignedBeaconBlock,
BeaconState: merge.BeaconState,
Metadata: altair.Metadata,
},
};
35 changes: 35 additions & 0 deletions packages/ssz/test/lodestarTypesV2/allForks/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import {ContainerType} from "../../../src";

import {ts as phase0} from "../phase0";
import {ts as altair} from "../altair";
import {ts as merge} from "../merge";

// Re-export union types for types that are _known_ to differ

export type BeaconBlockBody = phase0.BeaconBlockBody | altair.BeaconBlockBody | merge.BeaconBlockBody;
export type BeaconBlock = phase0.BeaconBlock | altair.BeaconBlock | merge.BeaconBlock;
export type SignedBeaconBlock = phase0.SignedBeaconBlock | altair.SignedBeaconBlock | merge.SignedBeaconBlock;
export type BeaconState = phase0.BeaconState | altair.BeaconState | merge.BeaconState;
export type Metadata = phase0.Metadata | altair.Metadata;

/**
* Types known to change between forks
*/
export type AllForksTypes = {
BeaconBlockBody: BeaconBlockBody;
BeaconBlock: BeaconBlock;
SignedBeaconBlock: SignedBeaconBlock;
BeaconState: BeaconState;
Metadata: Metadata;
};

/**
* SSZ Types known to change between forks
*/
export type AllForksSSZTypes = {
BeaconBlockBody: ContainerType<BeaconBlockBody>;
BeaconBlock: ContainerType<BeaconBlock>;
SignedBeaconBlock: ContainerType<SignedBeaconBlock>;
BeaconState: ContainerType<BeaconState>;
Metadata: ContainerType<Metadata>;
};
2 changes: 2 additions & 0 deletions packages/ssz/test/lodestarTypesV2/altair/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * as ts from "./types";
export * as ssz from "./sszTypes";
182 changes: 182 additions & 0 deletions packages/ssz/test/lodestarTypesV2/altair/sszTypes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
import {BitVectorType} from "../../../src/v2/bitVector";
import {ContainerType} from "../../../src/v2/container";
import {ListBasicType} from "../../../src/v2/listBasic";
import {ListCompositeType} from "../../../src/v2/listComposite";
import {VectorCompositeType} from "../../../src/v2/vectorComposite";
import {
FINALIZED_ROOT_INDEX_FLOORLOG2,
NEXT_SYNC_COMMITTEE_INDEX_FLOORLOG2,
SYNC_COMMITTEE_SUBNET_COUNT,
SYNC_COMMITTEE_SIZE,
SLOTS_PER_HISTORICAL_ROOT,
HISTORICAL_ROOTS_LIMIT,
SLOTS_PER_EPOCH,
VALIDATOR_REGISTRY_LIMIT,
EPOCHS_PER_SYNC_COMMITTEE_PERIOD,
} from "@chainsafe/lodestar-params";
import {Root} from "../primitive/types";
import {ssz as phase0Ssz} from "../phase0";
import {ssz as primitiveSsz} from "../primitive";
import {LazyVariable} from "../utils/lazyVar";

const {
Bytes32,
Number64,
Uint64,
Slot,
SubCommitteeIndex,
ValidatorIndex,
Root,
Version,
BLSPubkey,
BLSSignature,
ParticipationFlags,
} = primitiveSsz;

// So the expandedRoots can be referenced, and break the circular dependency
const typesRef = new LazyVariable<{
BeaconBlock: ContainerType<any>;
BeaconState: ContainerType<any>;
}>();

export const SyncSubnets = new BitVectorType(SYNC_COMMITTEE_SUBNET_COUNT);

export const Metadata = new ContainerType({
seqNumber: Uint64,
attnets: phase0Ssz.AttestationSubnets,
syncnets: SyncSubnets,
});

export const SyncCommittee = new ContainerType({
pubkeys: new VectorCompositeType(BLSPubkey, SYNC_COMMITTEE_SIZE),
aggregatePubkey: BLSPubkey,
});

export const SyncCommitteeMessage = new ContainerType({
slot: Slot,
beaconBlockRoot: Root,
validatorIndex: ValidatorIndex,
signature: BLSSignature,
});

export const SyncCommitteeContribution = new ContainerType({
slot: Slot,
beaconBlockRoot: Root,
subCommitteeIndex: SubCommitteeIndex,
aggregationBits: new BitVectorType(SYNC_COMMITTEE_SIZE / SYNC_COMMITTEE_SUBNET_COUNT),
signature: BLSSignature,
});

export const ContributionAndProof = new ContainerType({
aggregatorIndex: ValidatorIndex,
contribution: SyncCommitteeContribution,
selectionProof: BLSSignature,
});

export const SignedContributionAndProof = new ContainerType({
message: ContributionAndProof,
signature: BLSSignature,
});

export const SyncAggregatorSelectionData = new ContainerType({
slot: Slot,
subCommitteeIndex: SubCommitteeIndex,
});

export const SyncCommitteeBits = new BitVectorType(SYNC_COMMITTEE_SIZE);

export const SyncAggregate = new ContainerType({
syncCommitteeBits: SyncCommitteeBits,
syncCommitteeSignature: BLSSignature,
});

export const HistoricalBlockRoots = new VectorCompositeType(Root, SLOTS_PER_HISTORICAL_ROOT);
export const HistoricalStateRoots = new VectorCompositeType(Root, SLOTS_PER_HISTORICAL_ROOT);

export const HistoricalBatch = new ContainerType({
blockRoots: Root,
stateRoots: Root,
});

export const BeaconBlockBody = new ContainerType({
...phase0Ssz.BeaconBlockBody.fields,
syncAggregate: SyncAggregate,
});

export const BeaconBlock = new ContainerType({
slot: Slot,
proposerIndex: ValidatorIndex,
parentRoot: Root,
stateRoot: Root,
body: BeaconBlockBody,
});

export const SignedBeaconBlock = new ContainerType({
message: BeaconBlock,
signature: BLSSignature,
});

export const EpochParticipation = new ListBasicType(ParticipationFlags, VALIDATOR_REGISTRY_LIMIT);
export const InactivityScores = new ListBasicType(Number64, VALIDATOR_REGISTRY_LIMIT);

// we don't reuse phase0.BeaconState fields since we need to replace some keys
// and we cannot keep order doing that
export const BeaconState = new ContainerType({
genesisTime: Number64,
genesisValidatorsRoot: Root,
slot: Slot,
fork: phase0Ssz.Fork,
// History
latestBlockHeader: phase0Ssz.BeaconBlockHeader,
blockRoots: HistoricalBlockRoots,
stateRoots: HistoricalStateRoots,
historicalRoots: new ListCompositeType(Root, HISTORICAL_ROOTS_LIMIT),
// Eth1
eth1Data: phase0Ssz.Eth1Data,
eth1DataVotes: phase0Ssz.Eth1DataVotes,
eth1DepositIndex: Number64,
// Registry
validators: phase0Ssz.Validators,
balances: phase0Ssz.Balances,
randaoMixes: phase0Ssz.RandaoMixes,
// Slashings
slashings: phase0Ssz.Slashings,
// Participation
previousEpochParticipation: EpochParticipation,
currentEpochParticipation: EpochParticipation,
// Finality
justificationBits: phase0Ssz.JustificationBits,
previousJustifiedCheckpoint: phase0Ssz.Checkpoint,
currentJustifiedCheckpoint: phase0Ssz.Checkpoint,
finalizedCheckpoint: phase0Ssz.Checkpoint,
// Inactivity
inactivityScores: InactivityScores,
// Sync
currentSyncCommittee: SyncCommittee,
nextSyncCommittee: SyncCommittee,
});

export const LightClientSnapshot = new ContainerType({
header: phase0Ssz.BeaconBlockHeader,
nextSyncCommittee: SyncCommittee,
currentSyncCommittee: SyncCommittee,
});

export const LightClientUpdate = new ContainerType({
header: phase0Ssz.BeaconBlockHeader,
nextSyncCommittee: SyncCommittee,
nextSyncCommitteeBranch: new VectorCompositeType(Bytes32, NEXT_SYNC_COMMITTEE_INDEX_FLOORLOG2),
finalityHeader: phase0Ssz.BeaconBlockHeader,
finalityBranch: new VectorCompositeType(Bytes32, FINALIZED_ROOT_INDEX_FLOORLOG2),
syncCommitteeBits: new BitVectorType(SYNC_COMMITTEE_SIZE),
syncCommitteeSignature: BLSSignature,
forkVersion: Version,
});

export const LightClientStore = new ContainerType({
snapshot: LightClientSnapshot,
validUpdates: new ListCompositeType(LightClientUpdate, EPOCHS_PER_SYNC_COMMITTEE_PERIOD * SLOTS_PER_EPOCH),
});

// MUST set typesRef here, otherwise expandedType() calls will throw
typesRef.set({BeaconBlock, BeaconState});
Loading

0 comments on commit f83802f

Please sign in to comment.