From d87e63729104bfb9d0925d936046ec4a057822e4 Mon Sep 17 00:00:00 2001 From: harkamal Date: Wed, 24 Jan 2024 17:38:11 +0530 Subject: [PATCH] feat: placeholder PR for electra add types stub and epoch config fix types --- .../beacon-node/src/chain/blocks/types.ts | 2 +- .../test/spec/presets/fork.test.ts | 2 + .../test/spec/presets/transition.test.ts | 8 + .../upgradeLightClientHeader.test.ts | 33 +++- .../test/unit/network/fork.test.ts | 13 +- packages/beacon-node/test/utils/config.ts | 8 + .../config/src/chainConfig/configs/mainnet.ts | 4 + .../config/src/chainConfig/configs/minimal.ts | 4 + packages/config/src/chainConfig/types.ts | 6 + packages/config/src/forkConfig/index.ts | 10 +- packages/light-client/src/spec/utils.ts | 4 + packages/params/src/forkName.ts | 2 + .../test/unit/upgradeState.test.ts | 8 + packages/types/src/electra/index.ts | 3 + packages/types/src/electra/sszTypes.ts | 148 ++++++++++++++++++ packages/types/src/electra/types.ts | 29 ++++ packages/types/src/sszTypes.ts | 4 +- packages/types/src/types.ts | 36 +++++ packages/validator/src/util/params.ts | 5 + 19 files changed, 323 insertions(+), 6 deletions(-) create mode 100644 packages/types/src/electra/index.ts create mode 100644 packages/types/src/electra/sszTypes.ts create mode 100644 packages/types/src/electra/types.ts diff --git a/packages/beacon-node/src/chain/blocks/types.ts b/packages/beacon-node/src/chain/blocks/types.ts index da573bb76334..5eb5eebc7840 100644 --- a/packages/beacon-node/src/chain/blocks/types.ts +++ b/packages/beacon-node/src/chain/blocks/types.ts @@ -36,7 +36,7 @@ export enum GossipedInputType { type BlobsCacheMap = Map; -type ForkBlobsInfo = {fork: ForkName.deneb}; +type ForkBlobsInfo = {fork: ForkName.deneb | ForkName.electra}; type BlobsData = {blobs: deneb.BlobSidecars; blobsBytes: (Uint8Array | null)[]; blobsSource: BlobsSource}; export type BlockInputDataBlobs = ForkBlobsInfo & BlobsData; export type BlockInputData = BlockInputDataBlobs; diff --git a/packages/beacon-node/test/spec/presets/fork.test.ts b/packages/beacon-node/test/spec/presets/fork.test.ts index 228ab6a38935..c880d24bbbe3 100644 --- a/packages/beacon-node/test/spec/presets/fork.test.ts +++ b/packages/beacon-node/test/spec/presets/fork.test.ts @@ -35,6 +35,8 @@ const fork: TestRunnerFn = (forkNext) => { return slotFns.upgradeStateToCapella(preState as CachedBeaconStateBellatrix); case ForkName.deneb: return slotFns.upgradeStateToDeneb(preState as CachedBeaconStateCapella); + case ForkName.electra: + throw Error("not Implemented"); } }, options: { diff --git a/packages/beacon-node/test/spec/presets/transition.test.ts b/packages/beacon-node/test/spec/presets/transition.test.ts index d9925f292677..cae7c667b590 100644 --- a/packages/beacon-node/test/spec/presets/transition.test.ts +++ b/packages/beacon-node/test/spec/presets/transition.test.ts @@ -102,6 +102,14 @@ function getTransitionConfig(fork: ForkName, forkEpoch: number): Partial${toFork}`, function () { + lcHeaderByFork[fromFork].beacon.slot = testSlots[fromFork]; + lcHeaderByFork[toFork].beacon.slot = testSlots[fromFork]; + + expect(() => { + upgradeLightClientHeader(config, toFork, lcHeaderByFork[fromFork]); + }).toThrow("Not Implemented"); + }); + } + + // Since electra is not implemented for loop is till deneb (Object.values(ForkName).length-1) + // Once electra is implemnted run for loop till Object.values(ForkName).length + + // for (let i = ForkSeq.altair; i < Object.values(ForkName).length; i++) { + + for (let i = ForkSeq.altair; i < Object.values(ForkName).length - 1; i++) { for (let j = i; j > 0; j--) { const fromFork = ForkName[ForkSeq[i] as ForkName]; const toFork = ForkName[ForkSeq[j] as ForkName]; diff --git a/packages/beacon-node/test/unit/network/fork.test.ts b/packages/beacon-node/test/unit/network/fork.test.ts index be748d2e8185..bbe1c0870d30 100644 --- a/packages/beacon-node/test/unit/network/fork.test.ts +++ b/packages/beacon-node/test/unit/network/fork.test.ts @@ -9,12 +9,14 @@ function getForkConfig({ bellatrix, capella, deneb, + electra, }: { phase0: number; altair: number; bellatrix: number; capella: number; deneb: number; + electra: number; }): BeaconConfig { const forks: Record = { phase0: { @@ -57,6 +59,14 @@ function getForkConfig({ prevVersion: Buffer.from([0, 0, 0, 3]), prevForkName: ForkName.capella, }, + electra: { + name: ForkName.electra, + seq: ForkSeq.electra, + epoch: electra, + version: Buffer.from([0, 0, 0, 5]), + prevVersion: Buffer.from([0, 0, 0, 4]), + prevForkName: ForkName.deneb, + }, }; const forksAscendingEpochOrder = Object.values(forks); const forksDescendingEpochOrder = Object.values(forks).reverse(); @@ -133,9 +143,10 @@ const testScenarios = [ for (const testScenario of testScenarios) { const {phase0, altair, bellatrix, capella, testCases} = testScenario; const deneb = Infinity; + const electra = Infinity; describe(`network / fork: phase0: ${phase0}, altair: ${altair}, bellatrix: ${bellatrix} capella: ${capella}`, () => { - const forkConfig = getForkConfig({phase0, altair, bellatrix, capella, deneb}); + const forkConfig = getForkConfig({phase0, altair, bellatrix, capella, deneb, electra}); const forks = forkConfig.forks; for (const testCase of testCases) { const {epoch, currentFork, nextFork, activeForks} = testCase; diff --git a/packages/beacon-node/test/utils/config.ts b/packages/beacon-node/test/utils/config.ts index 54c058d30722..2aad1c14c03e 100644 --- a/packages/beacon-node/test/utils/config.ts +++ b/packages/beacon-node/test/utils/config.ts @@ -31,5 +31,13 @@ export function getConfig(fork: ForkName, forkEpoch = 0): ChainForkConfig { CAPELLA_FORK_EPOCH: 0, DENEB_FORK_EPOCH: forkEpoch, }); + case ForkName.electra: + return createChainForkConfig({ + ALTAIR_FORK_EPOCH: 0, + BELLATRIX_FORK_EPOCH: 0, + CAPELLA_FORK_EPOCH: 0, + DENEB_FORK_EPOCH: 0, + ELECTRA_FORK_EPOCH: forkEpoch, + }); } } diff --git a/packages/config/src/chainConfig/configs/mainnet.ts b/packages/config/src/chainConfig/configs/mainnet.ts index 883688ca821b..0de1bee666ec 100644 --- a/packages/config/src/chainConfig/configs/mainnet.ts +++ b/packages/config/src/chainConfig/configs/mainnet.ts @@ -49,6 +49,10 @@ export const chainConfig: ChainConfig = { DENEB_FORK_VERSION: b("0x04000000"), DENEB_FORK_EPOCH: 269568, // March 13, 2024, 01:55:35pm UTC + // Electra + ELECTRA_FORK_VERSION: b("0x05000000"), + ELECTRA_FORK_EPOCH: Infinity, + // Time parameters // --------------------------------------------------------------- // 12 seconds diff --git a/packages/config/src/chainConfig/configs/minimal.ts b/packages/config/src/chainConfig/configs/minimal.ts index 23cd14e763ec..c99a76d1ee40 100644 --- a/packages/config/src/chainConfig/configs/minimal.ts +++ b/packages/config/src/chainConfig/configs/minimal.ts @@ -46,6 +46,10 @@ export const chainConfig: ChainConfig = { DENEB_FORK_VERSION: b("0x04000001"), DENEB_FORK_EPOCH: Infinity, + // Electra + ELECTRA_FORK_VERSION: b("0x05000001"), + ELECTRA_FORK_EPOCH: Infinity, + // Time parameters // --------------------------------------------------------------- // [customized] Faster for testing purposes diff --git a/packages/config/src/chainConfig/types.ts b/packages/config/src/chainConfig/types.ts index 45f05bfaa724..234a08558be5 100644 --- a/packages/config/src/chainConfig/types.ts +++ b/packages/config/src/chainConfig/types.ts @@ -40,6 +40,9 @@ export type ChainConfig = { // DENEB DENEB_FORK_VERSION: Uint8Array; DENEB_FORK_EPOCH: number; + // ELECTRA + ELECTRA_FORK_VERSION: Uint8Array; + ELECTRA_FORK_EPOCH: number; // Time parameters SECONDS_PER_SLOT: number; @@ -99,6 +102,9 @@ export const chainConfigTypes: SpecTypes = { // DENEB DENEB_FORK_VERSION: "bytes", DENEB_FORK_EPOCH: "number", + // ELECTRA + ELECTRA_FORK_VERSION: "bytes", + ELECTRA_FORK_EPOCH: "number", // Time parameters SECONDS_PER_SLOT: "number", diff --git a/packages/config/src/forkConfig/index.ts b/packages/config/src/forkConfig/index.ts index 16d8952548b8..54edc8b618e0 100644 --- a/packages/config/src/forkConfig/index.ts +++ b/packages/config/src/forkConfig/index.ts @@ -59,10 +59,18 @@ export function createForkConfig(config: ChainConfig): ForkConfig { prevVersion: config.CAPELLA_FORK_VERSION, prevForkName: ForkName.capella, }; + const electra: ForkInfo = { + name: ForkName.electra, + seq: ForkSeq.electra, + epoch: config.ELECTRA_FORK_EPOCH, + version: config.ELECTRA_FORK_VERSION, + prevVersion: config.DENEB_FORK_VERSION, + prevForkName: ForkName.deneb, + }; /** Forks in order order of occurence, `phase0` first */ // Note: Downstream code relies on proper ordering. - const forks = {phase0, altair, bellatrix, capella, deneb}; + const forks = {phase0, altair, bellatrix, capella, deneb, electra}; // Prevents allocating an array on every getForkInfo() call const forksAscendingEpochOrder = Object.values(forks); diff --git a/packages/light-client/src/spec/utils.ts b/packages/light-client/src/spec/utils.ts index 65d6f3e84c59..aafd81c9250a 100644 --- a/packages/light-client/src/spec/utils.ts +++ b/packages/light-client/src/spec/utils.ts @@ -112,6 +112,10 @@ export function upgradeLightClientHeader( // Break if no further upgradation is required else fall through if (ForkSeq[targetFork] <= ForkSeq.deneb) break; + + // eslint-disable-next-line no-fallthrough + case ForkName.electra: + throw Error("Not Implemented"); } return upgradedHeader; } diff --git a/packages/params/src/forkName.ts b/packages/params/src/forkName.ts index a5f6d49d1cef..e1f1b2eda73a 100644 --- a/packages/params/src/forkName.ts +++ b/packages/params/src/forkName.ts @@ -7,6 +7,7 @@ export enum ForkName { bellatrix = "bellatrix", capella = "capella", deneb = "deneb", + electra = "electra", } /** @@ -18,6 +19,7 @@ export enum ForkSeq { bellatrix = 2, capella = 3, deneb = 4, + electra = 5, } function exclude(coll: T[], val: U[]): Exclude[] { diff --git a/packages/state-transition/test/unit/upgradeState.test.ts b/packages/state-transition/test/unit/upgradeState.test.ts index 2ea8eef182ac..75ba415c1bea 100644 --- a/packages/state-transition/test/unit/upgradeState.test.ts +++ b/packages/state-transition/test/unit/upgradeState.test.ts @@ -55,5 +55,13 @@ function getConfig(fork: ForkName, forkEpoch = 0): ChainForkConfig { CAPELLA_FORK_EPOCH: 0, DENEB_FORK_EPOCH: forkEpoch, }); + case ForkName.electra: + return createChainForkConfig({ + ALTAIR_FORK_EPOCH: 0, + BELLATRIX_FORK_EPOCH: 0, + CAPELLA_FORK_EPOCH: 0, + DENEB_FORK_EPOCH: 0, + ELECTRA_FORK_EPOCH: forkEpoch, + }); } } diff --git a/packages/types/src/electra/index.ts b/packages/types/src/electra/index.ts new file mode 100644 index 000000000000..7856cd729620 --- /dev/null +++ b/packages/types/src/electra/index.ts @@ -0,0 +1,3 @@ +export * from "./types.js"; +export * as ts from "./types.js"; +export * as ssz from "./sszTypes.js"; diff --git a/packages/types/src/electra/sszTypes.ts b/packages/types/src/electra/sszTypes.ts new file mode 100644 index 000000000000..30690a499845 --- /dev/null +++ b/packages/types/src/electra/sszTypes.ts @@ -0,0 +1,148 @@ +import {ContainerType} from "@chainsafe/ssz"; +import {ssz as primitiveSsz} from "../primitive/index.js"; +import {ssz as denebSsz} from "../deneb/index.js"; + +const {BLSSignature} = primitiveSsz; + +export const ExecutionPayload = new ContainerType( + { + ...denebSsz.ExecutionPayload.fields, + }, + {typeName: "ExecutionPayload", jsonCase: "eth2"} +); + +export const ExecutionPayloadHeader = new ContainerType( + { + ...denebSsz.ExecutionPayloadHeader.fields, + }, + {typeName: "ExecutionPayloadHeader", jsonCase: "eth2"} +); + +export const BeaconBlockBody = new ContainerType( + { + ...denebSsz.BeaconBlockBody.fields, + }, + {typeName: "BeaconBlockBody", jsonCase: "eth2", cachePermanentRootStruct: true} +); + +export const BeaconBlock = new ContainerType( + { + ...denebSsz.BeaconBlock.fields, + }, + {typeName: "BeaconBlock", jsonCase: "eth2", cachePermanentRootStruct: true} +); + +export const SignedBeaconBlock = new ContainerType( + { + message: BeaconBlock, + signature: BLSSignature, + }, + {typeName: "SignedBeaconBlock", jsonCase: "eth2"} +); + +export const BlobSidecar = new ContainerType( + { + ...denebSsz.BlobSidecar.fields, + }, + {typeName: "BlobSidecar", jsonCase: "eth2"} +); + +export const BlindedBeaconBlockBody = new ContainerType( + { + ...denebSsz.BlindedBeaconBlockBody.fields, + }, + {typeName: "BlindedBeaconBlockBody", jsonCase: "eth2", cachePermanentRootStruct: true} +); + +export const BlindedBeaconBlock = new ContainerType( + { + ...denebSsz.BlindedBeaconBlock.fields, + }, + {typeName: "BlindedBeaconBlock", jsonCase: "eth2", cachePermanentRootStruct: true} +); + +export const SignedBlindedBeaconBlock = new ContainerType( + { + message: BlindedBeaconBlock, + signature: BLSSignature, + }, + {typeName: "SignedBlindedBeaconBlock", jsonCase: "eth2"} +); + +export const BuilderBid = new ContainerType( + { + ...denebSsz.BuilderBid.fields, + }, + {typeName: "BuilderBid", jsonCase: "eth2"} +); + +export const SignedBuilderBid = new ContainerType( + { + message: BuilderBid, + signature: BLSSignature, + }, + {typeName: "SignedBuilderBid", jsonCase: "eth2"} +); + +export const ExecutionPayloadAndBlobsBundle = new ContainerType( + { + ...denebSsz.ExecutionPayloadAndBlobsBundle.fields, + }, + {typeName: "ExecutionPayloadAndBlobsBundle", jsonCase: "eth2"} +); + +export const BeaconState = new ContainerType( + { + ...denebSsz.BeaconState.fields, + }, + {typeName: "BeaconState", jsonCase: "eth2"} +); + +export const LightClientHeader = new ContainerType( + { + ...denebSsz.LightClientHeader.fields, + }, + {typeName: "LightClientHeader", jsonCase: "eth2"} +); + +export const LightClientBootstrap = new ContainerType( + { + ...denebSsz.LightClientBootstrap.fields, + }, + {typeName: "LightClientBootstrap", jsonCase: "eth2"} +); + +export const LightClientUpdate = new ContainerType( + { + ...denebSsz.LightClientUpdate.fields, + }, + {typeName: "LightClientUpdate", jsonCase: "eth2"} +); + +export const LightClientFinalityUpdate = new ContainerType( + { + ...denebSsz.LightClientFinalityUpdate.fields, + }, + {typeName: "LightClientFinalityUpdate", jsonCase: "eth2"} +); + +export const LightClientOptimisticUpdate = new ContainerType( + { + ...denebSsz.LightClientOptimisticUpdate.fields, + }, + {typeName: "LightClientOptimisticUpdate", jsonCase: "eth2"} +); + +export const LightClientStore = new ContainerType( + { + ...denebSsz.LightClientStore.fields, + }, + {typeName: "LightClientStore", jsonCase: "eth2"} +); + +export const SSEPayloadAttributes = new ContainerType( + { + ...denebSsz.SSEPayloadAttributes.fields, + }, + {typeName: "SSEPayloadAttributes", jsonCase: "eth2"} +); diff --git a/packages/types/src/electra/types.ts b/packages/types/src/electra/types.ts new file mode 100644 index 000000000000..198259eed1dd --- /dev/null +++ b/packages/types/src/electra/types.ts @@ -0,0 +1,29 @@ +import {ValueOf} from "@chainsafe/ssz"; +import * as ssz from "./sszTypes.js"; + +export type BlobSidecar = ValueOf; +export type ExecutionPayloadAndBlobsBundle = ValueOf; + +export type ExecutionPayload = ValueOf; +export type ExecutionPayloadHeader = ValueOf; + +export type BeaconBlockBody = ValueOf; +export type BeaconBlock = ValueOf; +export type SignedBeaconBlock = ValueOf; + +export type BeaconState = ValueOf; + +export type BlindedBeaconBlockBody = ValueOf; +export type BlindedBeaconBlock = ValueOf; +export type SignedBlindedBeaconBlock = ValueOf; + +export type BuilderBid = ValueOf; +export type SignedBuilderBid = ValueOf; +export type SSEPayloadAttributes = ValueOf; + +export type LightClientHeader = ValueOf; +export type LightClientBootstrap = ValueOf; +export type LightClientUpdate = ValueOf; +export type LightClientFinalityUpdate = ValueOf; +export type LightClientOptimisticUpdate = ValueOf; +export type LightClientStore = ValueOf; diff --git a/packages/types/src/sszTypes.ts b/packages/types/src/sszTypes.ts index 60980fa0822a..c2044edb5e98 100644 --- a/packages/types/src/sszTypes.ts +++ b/packages/types/src/sszTypes.ts @@ -5,9 +5,10 @@ import {ssz as altair} from "./altair/index.js"; import {ssz as bellatrix} from "./bellatrix/index.js"; import {ssz as capella} from "./capella/index.js"; import {ssz as deneb} from "./deneb/index.js"; +import {ssz as electra} from "./electra/index.js"; export * from "./primitive/sszTypes.js"; -export {phase0, altair, bellatrix, capella, deneb}; +export {phase0, altair, bellatrix, capella, deneb, electra}; /** * Index the ssz types that differ by fork @@ -19,6 +20,7 @@ const typesByFork = { [ForkName.bellatrix]: {...phase0, ...altair, ...bellatrix}, [ForkName.capella]: {...phase0, ...altair, ...bellatrix, ...capella}, [ForkName.deneb]: {...phase0, ...altair, ...bellatrix, ...capella, ...deneb}, + [ForkName.deneb]: {...phase0, ...altair, ...bellatrix, ...capella, ...deneb, ...electra}, }; /** diff --git a/packages/types/src/types.ts b/packages/types/src/types.ts index 3602299ae5e1..c0cc6591dd56 100644 --- a/packages/types/src/types.ts +++ b/packages/types/src/types.ts @@ -4,6 +4,7 @@ import {ts as altair} from "./altair/index.js"; import {ts as bellatrix} from "./bellatrix/index.js"; import {ts as capella} from "./capella/index.js"; import {ts as deneb} from "./deneb/index.js"; +import {ts as electra} from "./electra/index.js"; import {Slot} from "./primitive/types.js"; export * from "./primitive/types.js"; @@ -12,6 +13,7 @@ export {ts as altair} from "./altair/index.js"; export {ts as bellatrix} from "./bellatrix/index.js"; export {ts as capella} from "./capella/index.js"; export {ts as deneb} from "./deneb/index.js"; +export {ts as electra} from "./electra/index.js"; /** Common non-spec type to represent roots as strings */ export type RootHex = string; @@ -132,6 +134,40 @@ type TypesByFork = { SyncCommittee: altair.SyncCommittee; SyncAggregate: altair.SyncAggregate; }; + [ForkName.electra]: { + BeaconBlockHeader: phase0.BeaconBlockHeader; + SignedBeaconBlockHeader: phase0.SignedBeaconBlockHeader; + BeaconBlock: electra.BeaconBlock; + BeaconBlockBody: electra.BeaconBlockBody; + BeaconState: electra.BeaconState; + SignedBeaconBlock: electra.SignedBeaconBlock; + Metadata: altair.Metadata; + LightClientHeader: electra.LightClientHeader; + LightClientBootstrap: electra.LightClientBootstrap; + LightClientUpdate: electra.LightClientUpdate; + LightClientFinalityUpdate: electra.LightClientFinalityUpdate; + LightClientOptimisticUpdate: electra.LightClientOptimisticUpdate; + LightClientStore: electra.LightClientStore; + BlindedBeaconBlock: electra.BlindedBeaconBlock; + BlindedBeaconBlockBody: electra.BlindedBeaconBlockBody; + SignedBlindedBeaconBlock: electra.SignedBlindedBeaconBlock; + ExecutionPayload: electra.ExecutionPayload; + ExecutionPayloadHeader: electra.ExecutionPayloadHeader; + BuilderBid: electra.BuilderBid; + SignedBuilderBid: electra.SignedBuilderBid; + SSEPayloadAttributes: electra.SSEPayloadAttributes; + BlockContents: {block: BeaconBlock; kzgProofs: deneb.KZGProofs; blobs: deneb.Blobs}; + SignedBlockContents: { + signedBlock: SignedBeaconBlock; + kzgProofs: deneb.KZGProofs; + blobs: deneb.Blobs; + }; + ExecutionPayloadAndBlobsBundle: deneb.ExecutionPayloadAndBlobsBundle; + BlobsBundle: deneb.BlobsBundle; + Contents: deneb.Contents; + SyncCommittee: altair.SyncCommittee; + SyncAggregate: altair.SyncAggregate; + }; }; export type TypesFor = K extends void diff --git a/packages/validator/src/util/params.ts b/packages/validator/src/util/params.ts index 8ccaf9fe75ba..0afede39b951 100644 --- a/packages/validator/src/util/params.ts +++ b/packages/validator/src/util/params.ts @@ -73,6 +73,7 @@ function getSpecCriticalParams(localConfig: ChainConfig): Record