diff --git a/packages/beacon-node/src/chain/blocks/utils/elephantWithWings.ts b/packages/beacon-node/src/chain/blocks/utils/elephantWithWings.ts new file mode 100644 index 000000000000..dbdcf108a968 --- /dev/null +++ b/packages/beacon-node/src/chain/blocks/utils/elephantWithWings.ts @@ -0,0 +1,20 @@ +export const VERKLE_ELEPHANTWITHWINGS_BANNER = String.raw` + :~~. + :!:^::^^!!^ + :!^^ !:J. + .!!:! .^7^ + .?7~: ^#! !!!^!~. + :!^ GP~..^^?^ ^!: + !^ Y5 #7: + .:^^~7~. ! ~~6800~~^ ^6800^ ~~6800 68 00 68~~ 00~ || + .~! 55J ~~6800~~ :! !^ .YP :JP 7B. ^7# + ^7 :: 5 #:::^::~~6800~~^^?!?.~:: :! !^ 6800 .^PJ JG ~!B + :G ^7 ^ !^68 00^ ~~6800~~ :! !: .&~ ^#! ^!55~~~6800~~7G~ !7B + 7G ~!5J ^? !.----. ~! ~~6800~~ .7#: 6800 ~ + ?G :^?G. ...... ^?^.!G. ?G :^?G. ...... ^?^.!G. ! + ~! ~~6800~~ .7#: 6800 G~ 7G ~!5J ^? !.----. :: + :! !: .&~ ^#! ^!55~~~6800~~7G~ !7B :G ^7 ^ !^68 00^ ~~6800~~ :: + :! !^ 6800 .^PJ JG ~!B ^7 :: 5 ^^ !!!! #:::^::~~6800~~^^?!?.~ + :! !^ .YP :JP 7B. ^7# .~!~ ~~6800 ^6800^ ~~6800~~ + 6800 68 00 68~~ 00~ 6800 +`; diff --git a/packages/beacon-node/src/chain/blocks/verifyBlock.ts b/packages/beacon-node/src/chain/blocks/verifyBlock.ts index 4d21342bd8cc..f3ce54809779 100644 --- a/packages/beacon-node/src/chain/blocks/verifyBlock.ts +++ b/packages/beacon-node/src/chain/blocks/verifyBlock.ts @@ -17,6 +17,7 @@ import {BlockInput, ImportBlockOpts, BlockInputType} from "./types.js"; import {POS_PANDA_MERGE_TRANSITION_BANNER} from "./utils/pandaMergeTransitionBanner.js"; import {CAPELLA_OWL_BANNER} from "./utils/ownBanner.js"; import {DENEB_BLOWFISH_BANNER} from "./utils/blowfishBanner.js"; +import {VERKLE_ELEPHANTWITHWINGS_BANNER} from "./utils/elephantWithWings.js"; import {verifyBlocksStateTransitionOnly} from "./verifyBlocksStateTransitionOnly.js"; import {verifyBlocksSignatures} from "./verifyBlocksSignatures.js"; import {verifyBlocksExecutionPayload, SegmentExecStatus} from "./verifyBlocksExecutionPayloads.js"; @@ -152,6 +153,11 @@ export async function verifyBlocksInEpoch( this.logger.info("Activating withdrawals", {epoch: this.config.CAPELLA_FORK_EPOCH}); break; + case ForkName.verkle: + this.logger.info(VERKLE_ELEPHANTWITHWINGS_BANNER); + this.logger.info("Activating verkle", {epoch: this.config.VERKLE_FORK_EPOCH}); + break; + case ForkName.deneb: this.logger.info(DENEB_BLOWFISH_BANNER); this.logger.info("Activating blobs", {epoch: this.config.DENEB_FORK_EPOCH}); diff --git a/packages/beacon-node/src/execution/engine/types.ts b/packages/beacon-node/src/execution/engine/types.ts index 63cb4da88b6c..9d824a08a822 100644 --- a/packages/beacon-node/src/execution/engine/types.ts +++ b/packages/beacon-node/src/execution/engine/types.ts @@ -1,4 +1,4 @@ -import {capella, deneb, electra, Wei, bellatrix, Root, ExecutionPayload} from "@lodestar/types"; +import {capella, deneb, Wei, bellatrix, Root, verkle, electra, ExecutionPayload, ssz} from "@lodestar/types"; import { BYTES_PER_LOGS_BLOOM, FIELD_ELEMENTS_PER_BLOB, @@ -166,6 +166,7 @@ export type ExecutionPayloadRpc = { depositRequests?: DepositRequestRpc[]; // ELECTRA withdrawalRequests?: WithdrawalRequestRpc[]; // ELECTRA consolidationRequests?: ConsolidationRequestRpc[]; // ELECTRA + executionWitness?: Record; // DENEB }; export type WithdrawalRpc = { @@ -234,6 +235,20 @@ export function serializeExecutionPayload(fork: ForkName, data: ExecutionPayload payload.withdrawals = withdrawals.map(serializeWithdrawal); } + // VERKLE adds executionWitness to the ExecutionPayload + if (ForkSeq[fork] >= ForkSeq.verkle) { + const {executionWitness} = data as verkle.ExecutionPayload; + // right now the caseMap of ssz ExecutionWitness is camel cased and can + // directly be used to serialize tojson + payload.executionWitness = ssz.verkle.ExecutionWitness.toJson(executionWitness); + // serialization with ssz serialize suffix diff's suffix to a string while geth expects num + (payload.executionWitness as verkle.ExecutionWitness).stateDiff.forEach((sDiff) => { + sDiff.suffixDiffs.forEach((sfDiff) => { + sfDiff.suffix = Number(sfDiff.suffix); + }); + }); + } + // DENEB adds blobGasUsed & excessBlobGas to the ExecutionPayload if (ForkSeq[fork] >= ForkSeq.deneb) { const {blobGasUsed, excessBlobGas} = data as deneb.ExecutionPayload; @@ -315,6 +330,15 @@ export function parseExecutionPayload( (executionPayload as capella.ExecutionPayload).withdrawals = withdrawals.map((w) => deserializeWithdrawal(w)); } + // VERKLE adds execution witness to the payload + if (ForkSeq[fork] >= ForkSeq.verkle) { + // right now the casing of executionWitness is camel case in the ssz caseMap + // we can directly use fromJson to read the serialized data from payload + const {executionWitness} = data; + (executionPayload as verkle.ExecutionPayload).executionWitness = + ssz.verkle.ExecutionWitness.fromJson(executionWitness); + } + // DENEB adds excessBlobGas to the ExecutionPayload if (ForkSeq[fork] >= ForkSeq.deneb) { const {blobGasUsed, excessBlobGas} = data; diff --git a/packages/beacon-node/test/sim/electra-interop.test.ts b/packages/beacon-node/test/sim/electra-interop.test.ts index d0c00e75fd59..d696f7313427 100644 --- a/packages/beacon-node/test/sim/electra-interop.test.ts +++ b/packages/beacon-node/test/sim/electra-interop.test.ts @@ -311,6 +311,7 @@ describe("executionEngine / ExecutionEngineHttp", function () { ALTAIR_FORK_EPOCH: 0, BELLATRIX_FORK_EPOCH: 0, CAPELLA_FORK_EPOCH: 0, + VERKLE_FORK_EPOCH: 0, DENEB_FORK_EPOCH: 0, ELECTRA_FORK_EPOCH: electraEpoch, TERMINAL_TOTAL_DIFFICULTY: ttd, diff --git a/packages/beacon-node/test/spec/presets/fork.test.ts b/packages/beacon-node/test/spec/presets/fork.test.ts index c121e651fcea..e40fd23014ae 100644 --- a/packages/beacon-node/test/spec/presets/fork.test.ts +++ b/packages/beacon-node/test/spec/presets/fork.test.ts @@ -5,6 +5,7 @@ import { CachedBeaconStateAltair, CachedBeaconStatePhase0, CachedBeaconStateCapella, + CachedBeaconStateVerkle, CachedBeaconStateDeneb, } from "@lodestar/state-transition"; import * as slotFns from "@lodestar/state-transition/slot"; @@ -34,8 +35,10 @@ const fork: TestRunnerFn = (forkNext) => { return slotFns.upgradeStateToBellatrix(preState as CachedBeaconStateAltair); case ForkName.capella: return slotFns.upgradeStateToCapella(preState as CachedBeaconStateBellatrix); + case ForkName.verkle: + return slotFns.upgradeStateToVerkle(preState as CachedBeaconStateCapella); case ForkName.deneb: - return slotFns.upgradeStateToDeneb(preState as CachedBeaconStateCapella); + return slotFns.upgradeStateToDeneb(preState as CachedBeaconStateVerkle); case ForkName.electra: return slotFns.upgradeStateToElectra(preState as CachedBeaconStateDeneb); } diff --git a/packages/beacon-node/test/spec/presets/transition.test.ts b/packages/beacon-node/test/spec/presets/transition.test.ts index cae7c667b590..91070b62a394 100644 --- a/packages/beacon-node/test/spec/presets/transition.test.ts +++ b/packages/beacon-node/test/spec/presets/transition.test.ts @@ -100,13 +100,28 @@ function getTransitionConfig(fork: ForkName, forkEpoch: number): Partial { - const forkConfig = getForkConfig({phase0, altair, bellatrix, capella, deneb, electra}); + const forkConfig = getForkConfig({phase0, altair, bellatrix, capella, verkle, 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 2aad1c14c03e..cf92584560c1 100644 --- a/packages/beacon-node/test/utils/config.ts +++ b/packages/beacon-node/test/utils/config.ts @@ -24,11 +24,19 @@ export function getConfig(fork: ForkName, forkEpoch = 0): ChainForkConfig { BELLATRIX_FORK_EPOCH: 0, CAPELLA_FORK_EPOCH: forkEpoch, }); + case ForkName.verkle: + return createChainForkConfig({ + ALTAIR_FORK_EPOCH: 0, + BELLATRIX_FORK_EPOCH: 0, + CAPELLA_FORK_EPOCH: 0, + VERKLE_FORK_EPOCH: forkEpoch, + }); case ForkName.deneb: return createChainForkConfig({ ALTAIR_FORK_EPOCH: 0, BELLATRIX_FORK_EPOCH: 0, CAPELLA_FORK_EPOCH: 0, + VERKLE_FORK_EPOCH: 0, DENEB_FORK_EPOCH: forkEpoch, }); case ForkName.electra: @@ -36,6 +44,7 @@ export function getConfig(fork: ForkName, forkEpoch = 0): ChainForkConfig { ALTAIR_FORK_EPOCH: 0, BELLATRIX_FORK_EPOCH: 0, CAPELLA_FORK_EPOCH: 0, + VERKLE_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 741ddc99f8cd..789c300663cc 100644 --- a/packages/config/src/chainConfig/configs/mainnet.ts +++ b/packages/config/src/chainConfig/configs/mainnet.ts @@ -45,12 +45,16 @@ export const chainConfig: ChainConfig = { CAPELLA_FORK_VERSION: b("0x03000000"), CAPELLA_FORK_EPOCH: 194048, // April 12 (epoch: 194048 slot: 6209536 UTC: 4/12/2023, 10:27:35 PM) + // VERKLE + VERKLE_FORK_VERSION: b("0x04000000"), + VERKLE_FORK_EPOCH: Infinity, + // Deneb - DENEB_FORK_VERSION: b("0x04000000"), - DENEB_FORK_EPOCH: 269568, // March 13, 2024, 01:55:35pm UTC + DENEB_FORK_VERSION: b("0x05000000"), + DENEB_FORK_EPOCH: Infinity, // ELECTRA - ELECTRA_FORK_VERSION: b("0x05000000"), + ELECTRA_FORK_VERSION: b("0x06000000"), ELECTRA_FORK_EPOCH: Infinity, // Time parameters diff --git a/packages/config/src/chainConfig/configs/minimal.ts b/packages/config/src/chainConfig/configs/minimal.ts index 26f49cc3e47d..49e8823a4d34 100644 --- a/packages/config/src/chainConfig/configs/minimal.ts +++ b/packages/config/src/chainConfig/configs/minimal.ts @@ -42,11 +42,14 @@ export const chainConfig: ChainConfig = { // Capella CAPELLA_FORK_VERSION: b("0x03000001"), CAPELLA_FORK_EPOCH: Infinity, + // Verkle + VERKLE_FORK_VERSION: b("0x04000001"), + VERKLE_FORK_EPOCH: Infinity, // Deneb - DENEB_FORK_VERSION: b("0x04000001"), + DENEB_FORK_VERSION: b("0x05000001"), DENEB_FORK_EPOCH: Infinity, // ELECTRA - ELECTRA_FORK_VERSION: b("0x05000001"), + ELECTRA_FORK_VERSION: b("0x06000001"), ELECTRA_FORK_EPOCH: Infinity, // Time parameters diff --git a/packages/config/src/chainConfig/types.ts b/packages/config/src/chainConfig/types.ts index 05fff02f2eaf..b2b06c54cfcb 100644 --- a/packages/config/src/chainConfig/types.ts +++ b/packages/config/src/chainConfig/types.ts @@ -37,6 +37,9 @@ export type ChainConfig = { // Capella CAPELLA_FORK_VERSION: Uint8Array; CAPELLA_FORK_EPOCH: number; + // VERKLE + VERKLE_FORK_VERSION: Uint8Array; + VERKLE_FORK_EPOCH: number; // DENEB DENEB_FORK_VERSION: Uint8Array; DENEB_FORK_EPOCH: number; @@ -101,6 +104,9 @@ export const chainConfigTypes: SpecTypes = { // Capella CAPELLA_FORK_VERSION: "bytes", CAPELLA_FORK_EPOCH: "number", + // VERKLE + VERKLE_FORK_VERSION: "bytes", + VERKLE_FORK_EPOCH: "number", // DENEB DENEB_FORK_VERSION: "bytes", DENEB_FORK_EPOCH: "number", diff --git a/packages/config/src/forkConfig/index.ts b/packages/config/src/forkConfig/index.ts index 513cd7559ee3..4572cd703614 100644 --- a/packages/config/src/forkConfig/index.ts +++ b/packages/config/src/forkConfig/index.ts @@ -51,13 +51,21 @@ export function createForkConfig(config: ChainConfig): ForkConfig { prevVersion: config.BELLATRIX_FORK_VERSION, prevForkName: ForkName.bellatrix, }; + const verkle: ForkInfo = { + name: ForkName.verkle, + seq: ForkSeq.verkle, + epoch: config.VERKLE_FORK_EPOCH, + version: config.VERKLE_FORK_VERSION, + prevVersion: config.CAPELLA_FORK_VERSION, + prevForkName: ForkName.capella, + }; const deneb: ForkInfo = { name: ForkName.deneb, seq: ForkSeq.deneb, epoch: config.DENEB_FORK_EPOCH, version: config.DENEB_FORK_VERSION, - prevVersion: config.CAPELLA_FORK_VERSION, - prevForkName: ForkName.capella, + prevVersion: config.VERKLE_FORK_VERSION, + prevForkName: ForkName.verkle, }; const electra: ForkInfo = { name: ForkName.electra, @@ -70,7 +78,7 @@ export function createForkConfig(config: ChainConfig): ForkConfig { /** Forks in order order of occurence, `phase0` first */ // Note: Downstream code relies on proper ordering. - const forks = {phase0, altair, bellatrix, capella, deneb, electra}; + const forks = {phase0, altair, bellatrix, capella, verkle, deneb, electra}; // Prevents allocating an array on every getForkInfo() call const forksAscendingEpochOrder = Object.values(forks); diff --git a/packages/params/src/forkName.ts b/packages/params/src/forkName.ts index 42e8917942d2..2e06fafd6ccb 100644 --- a/packages/params/src/forkName.ts +++ b/packages/params/src/forkName.ts @@ -6,6 +6,7 @@ export enum ForkName { altair = "altair", bellatrix = "bellatrix", capella = "capella", + verkle = "verkle", deneb = "deneb", electra = "electra", } @@ -18,8 +19,10 @@ export enum ForkSeq { altair = 1, bellatrix = 2, capella = 3, - deneb = 4, - electra = 5, + // Verkle is scheduled after capella for now + verkle = 4, + deneb = 5, + electra = 6, } function exclude(coll: T[], val: U[]): Exclude[] { @@ -74,11 +77,24 @@ export function isForkWithdrawals(fork: ForkName): fork is ForkWithdrawals { return isForkExecution(fork) && fork !== ForkName.bellatrix; } -export type ForkPreBlobs = ForkPreWithdrawals | ForkName.capella; +export type ForkPreVerge = ForkPreWithdrawals | ForkName.capella; +export type ForkVerge = Exclude; +export const forkVerge = exclude(forkAll, [ForkName.phase0, ForkName.altair, ForkName.bellatrix, ForkName.capella]); +export function isForkVerge(fork: ForkName): fork is ForkVerge { + return isForkWithdrawals(fork) && fork !== ForkName.capella; +} + +export type ForkPreBlobs = ForkPreVerge | ForkName.verkle; export type ForkBlobs = Exclude; -export const forkBlobs = exclude(forkAll, [ForkName.phase0, ForkName.altair, ForkName.bellatrix, ForkName.capella]); +export const forkBlobs = exclude(forkAll, [ + ForkName.phase0, + ForkName.altair, + ForkName.bellatrix, + ForkName.capella, + ForkName.verkle, +]); export function isForkBlobs(fork: ForkName): fork is ForkBlobs { - return isForkWithdrawals(fork) && fork !== ForkName.capella; + return isForkVerge(fork) && fork !== ForkName.verkle; } export type ForkPreElectra = ForkPreBlobs | ForkName.deneb; @@ -88,6 +104,7 @@ export const forkPostElectra = exclude(forkAll, [ ForkName.altair, ForkName.bellatrix, ForkName.capella, + ForkName.verkle, ForkName.deneb, ]); export function isForkPostElectra(fork: ForkName): fork is ForkPostElectra { diff --git a/packages/params/src/index.ts b/packages/params/src/index.ts index e7fd5b976336..22d988b18bb9 100644 --- a/packages/params/src/index.ts +++ b/packages/params/src/index.ts @@ -261,6 +261,13 @@ export const KZG_COMMITMENT_SUBTREE_INDEX0 = KZG_COMMITMENT_GINDEX0 - 2 ** KZG_C // ssz.deneb.BlobSidecars.elementType.fixedSize export const BLOBSIDECAR_FIXED_SIZE = ACTIVE_PRESET === PresetName.minimal ? 131672 : 131928; +// TODO: Verkle spec notes these as preset but there's only one value +// https://github.com/ethereum/consensus-specs/blob/db74090c1e8dc1fb2c052bae268e22dc63061e32/specs/verge/beacon-chain.md#preset +export const MAX_STEMS = 2 ** 16; +export const MAX_COMMITMENTS_PER_STEM = 33; +export const VERKLE_WIDTH = 256; +export const IPA_PROOF_DEPTH = 8; + // Electra Misc export const UNSET_DEPOSIT_REQUESTS_START_INDEX = 2n ** 64n - 1n; export const FULL_EXIT_REQUEST_AMOUNT = 0; diff --git a/packages/state-transition/src/cache/stateCache.ts b/packages/state-transition/src/cache/stateCache.ts index 0435e8829d21..c7407bd003d1 100644 --- a/packages/state-transition/src/cache/stateCache.ts +++ b/packages/state-transition/src/cache/stateCache.ts @@ -9,6 +9,7 @@ import { BeaconStateAltair, BeaconStateBellatrix, BeaconStateCapella, + BeaconStateVerkle, BeaconStateDeneb, BeaconStateElectra, } from "./types.js"; @@ -130,9 +131,9 @@ export type CachedBeaconStatePhase0 = CachedBeaconState; export type CachedBeaconStateAltair = CachedBeaconState; export type CachedBeaconStateBellatrix = CachedBeaconState; export type CachedBeaconStateCapella = CachedBeaconState; +export type CachedBeaconStateVerkle = CachedBeaconState; export type CachedBeaconStateDeneb = CachedBeaconState; export type CachedBeaconStateElectra = CachedBeaconState; - export type CachedBeaconStateAllForks = CachedBeaconState; export type CachedBeaconStateExecutions = CachedBeaconState; /** diff --git a/packages/state-transition/src/cache/types.ts b/packages/state-transition/src/cache/types.ts index b3fe6fc8ed5b..8e2887109353 100644 --- a/packages/state-transition/src/cache/types.ts +++ b/packages/state-transition/src/cache/types.ts @@ -7,6 +7,7 @@ export type BeaconStatePhase0 = CompositeViewDU>; export type BeaconStateBellatrix = CompositeViewDU>; export type BeaconStateCapella = CompositeViewDU>; +export type BeaconStateVerkle = CompositeViewDU>; export type BeaconStateDeneb = CompositeViewDU>; export type BeaconStateElectra = CompositeViewDU>; diff --git a/packages/state-transition/src/index.ts b/packages/state-transition/src/index.ts index 4ed801e3c490..9f2dccfc6f38 100644 --- a/packages/state-transition/src/index.ts +++ b/packages/state-transition/src/index.ts @@ -10,6 +10,7 @@ export type { CachedBeaconStateAltair, CachedBeaconStateBellatrix, CachedBeaconStateCapella, + CachedBeaconStateVerkle, CachedBeaconStateDeneb, CachedBeaconStateElectra, CachedBeaconStateAllForks, @@ -19,6 +20,7 @@ export type { BeaconStateAltair, BeaconStateBellatrix, BeaconStateCapella, + BeaconStateVerkle, BeaconStateDeneb, BeaconStateElectra, BeaconStateAllForks, diff --git a/packages/state-transition/src/slot/index.ts b/packages/state-transition/src/slot/index.ts index b05bd7ac93f2..8140b5e230a1 100644 --- a/packages/state-transition/src/slot/index.ts +++ b/packages/state-transition/src/slot/index.ts @@ -6,6 +6,7 @@ import {ZERO_HASH} from "../constants/index.js"; export {upgradeStateToAltair} from "./upgradeStateToAltair.js"; export {upgradeStateToBellatrix} from "./upgradeStateToBellatrix.js"; export {upgradeStateToCapella} from "./upgradeStateToCapella.js"; +export {upgradeStateToVerkle} from "./upgradeStateToVerkle.js"; export {upgradeStateToDeneb} from "./upgradeStateToDeneb.js"; export {upgradeStateToElectra} from "./upgradeStateToElectra.js"; diff --git a/packages/state-transition/src/slot/upgradeStateToDeneb.ts b/packages/state-transition/src/slot/upgradeStateToDeneb.ts index 53be75f72ad8..7d56e25c242e 100644 --- a/packages/state-transition/src/slot/upgradeStateToDeneb.ts +++ b/packages/state-transition/src/slot/upgradeStateToDeneb.ts @@ -1,23 +1,23 @@ import {ssz} from "@lodestar/types"; import {CachedBeaconStateDeneb} from "../types.js"; import {getCachedBeaconState} from "../cache/stateCache.js"; -import {CachedBeaconStateCapella} from "../types.js"; +import {CachedBeaconStateVerkle} from "../types.js"; /** - * Upgrade a state from Capella to Deneb. + * Upgrade a state from Verkle to Deneb. */ -export function upgradeStateToDeneb(stateCapella: CachedBeaconStateCapella): CachedBeaconStateDeneb { - const {config} = stateCapella; +export function upgradeStateToDeneb(stateVerkle: CachedBeaconStateVerkle): CachedBeaconStateDeneb { + const {config} = stateVerkle; - const stateCapellaNode = ssz.capella.BeaconState.commitViewDU(stateCapella); - const stateDenebView = ssz.deneb.BeaconState.getViewDU(stateCapellaNode); + const stateVerkleNode = ssz.verkle.BeaconState.commitViewDU(stateVerkle); + const stateDenebView = ssz.deneb.BeaconState.getViewDU(stateVerkleNode); - const stateDeneb = getCachedBeaconState(stateDenebView, stateCapella); + const stateDeneb = getCachedBeaconState(stateDenebView, stateVerkle); stateDeneb.fork = ssz.phase0.Fork.toViewDU({ - previousVersion: stateCapella.fork.currentVersion, + previousVersion: stateVerkle.fork.currentVersion, currentVersion: config.DENEB_FORK_VERSION, - epoch: stateCapella.epochCtx.epoch, + epoch: stateVerkle.epochCtx.epoch, }); // Since excessBlobGas and blobGasUsed are appened in the end to latestExecutionPayloadHeader so they should @@ -27,13 +27,13 @@ export function upgradeStateToDeneb(stateCapella: CachedBeaconStateCapella): Cac // // TODO DENEB: Debug and remove the following cloning stateDeneb.latestExecutionPayloadHeader = ssz.deneb.BeaconState.fields.latestExecutionPayloadHeader.toViewDU({ - ...stateCapella.latestExecutionPayloadHeader.toValue(), + ...stateVerkle.latestExecutionPayloadHeader.toValue(), excessBlobGas: BigInt(0), blobGasUsed: BigInt(0), }); stateDeneb.commit(); - // Clear cache to ensure the cache of capella fields is not used by new deneb fields + // Clear cache to ensure the cache of verkle fields is not used by new deneb fields stateDeneb["clearCache"](); return stateDeneb; diff --git a/packages/state-transition/src/slot/upgradeStateToVerkle.ts b/packages/state-transition/src/slot/upgradeStateToVerkle.ts new file mode 100644 index 000000000000..04cd3b8deb29 --- /dev/null +++ b/packages/state-transition/src/slot/upgradeStateToVerkle.ts @@ -0,0 +1,26 @@ +import {ssz} from "@lodestar/types"; +import {CachedBeaconStateCapella, CachedBeaconStateVerkle} from "../types.js"; +import {getCachedBeaconState} from "../cache/stateCache.js"; + +/** + * Upgrade a state from Capella (Eventualy DENEB) to Verkle. + */ +export function upgradeStateToVerkle(stateCapella: CachedBeaconStateCapella): CachedBeaconStateVerkle { + const {config} = stateCapella; + + const stateCapellaNode = ssz.capella.BeaconState.commitViewDU(stateCapella); + const stateVerkleView = ssz.verkle.BeaconState.getViewDU(stateCapellaNode); + + const stateVerkle = getCachedBeaconState(stateVerkleView, stateCapella); + + stateVerkle.fork = ssz.phase0.Fork.toViewDU({ + previousVersion: stateCapella.fork.currentVersion, + currentVersion: config.VERKLE_FORK_VERSION, + epoch: stateCapella.epochCtx.epoch, + }); + + // latestExecutionPayloadHeader's executionWitnessRoot will have default zero root + + stateVerkle.commit(); + return stateVerkle; +} diff --git a/packages/state-transition/src/stateTransition.ts b/packages/state-transition/src/stateTransition.ts index 3b97f19282a4..9da302bccc03 100644 --- a/packages/state-transition/src/stateTransition.ts +++ b/packages/state-transition/src/stateTransition.ts @@ -9,6 +9,7 @@ import { CachedBeaconStateAltair, CachedBeaconStateBellatrix, CachedBeaconStateCapella, + CachedBeaconStateVerkle, CachedBeaconStateDeneb, } from "./types.js"; import {computeEpochAtSlot} from "./util/index.js"; @@ -25,6 +26,7 @@ import {processBlock} from "./block/index.js"; import {EpochTransitionStep, processEpoch} from "./epoch/index.js"; import {BlockExternalData, DataAvailableStatus, ExecutionPayloadStatus} from "./block/externalData.js"; import {ProcessBlockOpts} from "./block/types.js"; +import {upgradeStateToVerkle} from "./slot/upgradeStateToVerkle.js"; // Multifork capable state transition @@ -239,8 +241,11 @@ function processSlotsWithTransientCache( if (stateEpoch === config.CAPELLA_FORK_EPOCH) { postState = upgradeStateToCapella(postState as CachedBeaconStateBellatrix) as CachedBeaconStateAllForks; } + if (stateEpoch === config.VERKLE_FORK_EPOCH) { + postState = upgradeStateToVerkle(postState as CachedBeaconStateCapella) as CachedBeaconStateAllForks; + } if (stateEpoch === config.DENEB_FORK_EPOCH) { - postState = upgradeStateToDeneb(postState as CachedBeaconStateCapella) as CachedBeaconStateAllForks; + postState = upgradeStateToDeneb(postState as CachedBeaconStateVerkle) as CachedBeaconStateAllForks; } if (stateEpoch === config.ELECTRA_FORK_EPOCH) { postState = upgradeStateToElectra(postState as CachedBeaconStateDeneb) as CachedBeaconStateAllForks; diff --git a/packages/state-transition/src/types.ts b/packages/state-transition/src/types.ts index d3a1ed69a7a9..cb4be38c7459 100644 --- a/packages/state-transition/src/types.ts +++ b/packages/state-transition/src/types.ts @@ -8,6 +8,7 @@ export type { CachedBeaconStateAltair, CachedBeaconStateBellatrix, CachedBeaconStateCapella, + CachedBeaconStateVerkle, CachedBeaconStateDeneb, CachedBeaconStateElectra, } from "./cache/stateCache.js"; @@ -19,6 +20,7 @@ export type { BeaconStateAltair, BeaconStateBellatrix, BeaconStateCapella, + BeaconStateVerkle, BeaconStateDeneb, BeaconStateElectra, } from "./cache/types.js"; diff --git a/packages/state-transition/src/util/execution.ts b/packages/state-transition/src/util/execution.ts index 06e654f9f1d2..5f0959228b5e 100644 --- a/packages/state-transition/src/util/execution.ts +++ b/packages/state-transition/src/util/execution.ts @@ -1,6 +1,7 @@ import { bellatrix, capella, + verkle, deneb, electra, isBlindedBeaconBlockBody, @@ -161,6 +162,12 @@ export function executionPayloadToPayloadHeader(fork: ForkSeq, payload: Executio ); } + if (fork >= ForkSeq.verkle) { + // https://github.com/ethereum/consensus-specs/blob/db74090c1e8dc1fb2c052bae268e22dc63061e32/specs/verge/beacon-chain.md#process_execution_payload + (bellatrixPayloadFields as verkle.ExecutionPayloadHeader).executionWitnessRoot = + ssz.verkle.ExecutionWitness.hashTreeRoot((payload as verkle.ExecutionPayload).executionWitness); + } + if (fork >= ForkSeq.deneb) { // https://github.com/ethereum/consensus-specs/blob/dev/specs/eip4844/beacon-chain.md#process_execution_payload (bellatrixPayloadFields as deneb.ExecutionPayloadHeader).blobGasUsed = ( diff --git a/packages/state-transition/src/util/genesis.ts b/packages/state-transition/src/util/genesis.ts index 02bcef00bb55..00e41a9b9154 100644 --- a/packages/state-transition/src/util/genesis.ts +++ b/packages/state-transition/src/util/genesis.ts @@ -230,6 +230,7 @@ export function initializeBeaconStateFromEth1( executionPayloadHeader?: CompositeViewDU< | typeof ssz.bellatrix.ExecutionPayloadHeader | typeof ssz.capella.ExecutionPayloadHeader + | typeof ssz.verkle.ExecutionPayloadHeader | typeof ssz.deneb.ExecutionPayloadHeader | typeof ssz.electra.ExecutionPayloadHeader > @@ -296,6 +297,15 @@ export function initializeBeaconStateFromEth1( ssz.capella.ExecutionPayloadHeader.defaultViewDU(); } + if (GENESIS_SLOT >= config.VERKLE_FORK_EPOCH) { + const stateVerkle = state as CompositeViewDU; + stateVerkle.fork.previousVersion = config.VERKLE_FORK_VERSION; + stateVerkle.fork.currentVersion = config.VERKLE_FORK_VERSION; + stateVerkle.latestExecutionPayloadHeader = + (executionPayloadHeader as CompositeViewDU) ?? + ssz.verkle.ExecutionPayloadHeader.defaultViewDU(); + } + if (fork >= ForkSeq.deneb) { const stateDeneb = state as CompositeViewDU; stateDeneb.fork.previousVersion = config.DENEB_FORK_VERSION; diff --git a/packages/state-transition/test/unit/upgradeState.test.ts b/packages/state-transition/test/unit/upgradeState.test.ts index df9b052542f9..ef39b63254a9 100644 --- a/packages/state-transition/test/unit/upgradeState.test.ts +++ b/packages/state-transition/test/unit/upgradeState.test.ts @@ -11,12 +11,12 @@ import {PubkeyIndexMap} from "../../src/cache/pubkeyCache.js"; describe("upgradeState", () => { it("upgradeStateToDeneb", () => { - const capellaState = ssz.capella.BeaconState.defaultViewDU(); - const config = getConfig(ForkName.capella); + const verkleState = ssz.verkle.BeaconState.defaultViewDU(); + const config = getConfig(ForkName.verkle); const stateView = createCachedBeaconState( - capellaState, + verkleState, { - config: createBeaconConfig(config, capellaState.genesisValidatorsRoot), + config: createBeaconConfig(config, verkleState.genesisValidatorsRoot), pubkey2index: new PubkeyIndexMap(), index2pubkey: [], }, @@ -64,11 +64,19 @@ function getConfig(fork: ForkName, forkEpoch = 0): ChainForkConfig { BELLATRIX_FORK_EPOCH: 0, CAPELLA_FORK_EPOCH: forkEpoch, }); + case ForkName.verkle: + return createChainForkConfig({ + ALTAIR_FORK_EPOCH: 0, + BELLATRIX_FORK_EPOCH: 0, + CAPELLA_FORK_EPOCH: 0, + VERKLE_FORK_EPOCH: forkEpoch, + }); case ForkName.deneb: return createChainForkConfig({ ALTAIR_FORK_EPOCH: 0, BELLATRIX_FORK_EPOCH: 0, CAPELLA_FORK_EPOCH: 0, + VERKLE_FORK_EPOCH: 0, DENEB_FORK_EPOCH: forkEpoch, }); case ForkName.electra: @@ -76,6 +84,7 @@ function getConfig(fork: ForkName, forkEpoch = 0): ChainForkConfig { ALTAIR_FORK_EPOCH: 0, BELLATRIX_FORK_EPOCH: 0, CAPELLA_FORK_EPOCH: 0, + VERKLE_FORK_EPOCH: 0, DENEB_FORK_EPOCH: 0, ELECTRA_FORK_EPOCH: forkEpoch, }); diff --git a/packages/types/src/sszTypes.ts b/packages/types/src/sszTypes.ts index 4399904a94bc..e1a880706505 100644 --- a/packages/types/src/sszTypes.ts +++ b/packages/types/src/sszTypes.ts @@ -4,11 +4,12 @@ import {ssz as phase0} from "./phase0/index.js"; 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 verkle} from "./verkle/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, electra}; +export {phase0, altair, bellatrix, capella, verkle, deneb, electra}; /** * Index the ssz types that differ by fork @@ -19,8 +20,9 @@ const typesByFork = { [ForkName.altair]: {...phase0, ...altair}, [ForkName.bellatrix]: {...phase0, ...altair, ...bellatrix}, [ForkName.capella]: {...phase0, ...altair, ...bellatrix, ...capella}, - [ForkName.deneb]: {...phase0, ...altair, ...bellatrix, ...capella, ...deneb}, - [ForkName.electra]: {...phase0, ...altair, ...bellatrix, ...capella, ...deneb, ...electra}, + [ForkName.verkle]: {...phase0, ...altair, ...bellatrix, ...capella, ...verkle}, + [ForkName.deneb]: {...phase0, ...altair, ...bellatrix, ...capella, ...verkle, ...deneb}, + [ForkName.electra]: {...phase0, ...altair, ...bellatrix, ...capella, ...verkle, ...deneb, ...electra}, }; /** diff --git a/packages/types/src/types.ts b/packages/types/src/types.ts index 1071eed79a10..faa64fb8015b 100644 --- a/packages/types/src/types.ts +++ b/packages/types/src/types.ts @@ -6,12 +6,14 @@ 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"; +import {verkle} from "./types.js"; export * from "./primitive/types.js"; export {ts as phase0} from "./phase0/index.js"; 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 verkle} from "./verkle/index.js"; export {ts as deneb} from "./deneb/index.js"; export {ts as electra} from "./electra/index.js"; @@ -128,6 +130,37 @@ type TypesByFork = { AggregateAndProof: phase0.AggregateAndProof; SignedAggregateAndProof: phase0.SignedAggregateAndProof; }; + [ForkName.verkle]: { + BeaconBlockHeader: phase0.BeaconBlockHeader; + SignedBeaconBlockHeader: phase0.SignedBeaconBlockHeader; + BeaconBlock: verkle.BeaconBlock; + BeaconBlockBody: verkle.BeaconBlockBody; + BeaconState: verkle.BeaconState; + SignedBeaconBlock: verkle.SignedBeaconBlock; + Metadata: altair.Metadata; + LightClientHeader: verkle.LightClientHeader; + LightClientBootstrap: verkle.LightClientBootstrap; + LightClientUpdate: verkle.LightClientUpdate; + LightClientFinalityUpdate: verkle.LightClientFinalityUpdate; + LightClientOptimisticUpdate: verkle.LightClientOptimisticUpdate; + LightClientStore: verkle.LightClientStore; + BlindedBeaconBlock: verkle.BlindedBeaconBlock; + BlindedBeaconBlockBody: verkle.BlindedBeaconBlockBody; + SignedBlindedBeaconBlock: verkle.SignedBlindedBeaconBlock; + ExecutionPayload: verkle.ExecutionPayload; + ExecutionPayloadHeader: verkle.ExecutionPayloadHeader; + BuilderBid: verkle.BuilderBid; + SignedBuilderBid: verkle.SignedBuilderBid; + SSEPayloadAttributes: capella.SSEPayloadAttributes; + SyncCommittee: altair.SyncCommittee; + SyncAggregate: altair.SyncAggregate; + Attestation: phase0.Attestation; + IndexedAttestation: phase0.IndexedAttestation; + IndexedAttestationBigint: phase0.IndexedAttestationBigint; + AttesterSlashing: phase0.AttesterSlashing; + AggregateAndProof: phase0.AggregateAndProof; + SignedAggregateAndProof: phase0.SignedAggregateAndProof; + }; [ForkName.deneb]: { BeaconBlockHeader: phase0.BeaconBlockHeader; SignedBeaconBlockHeader: phase0.SignedBeaconBlockHeader; diff --git a/packages/types/src/verkle/index.ts b/packages/types/src/verkle/index.ts new file mode 100644 index 000000000000..7856cd729620 --- /dev/null +++ b/packages/types/src/verkle/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/verkle/sszTypes.ts b/packages/types/src/verkle/sszTypes.ts new file mode 100644 index 000000000000..13ff67f0c198 --- /dev/null +++ b/packages/types/src/verkle/sszTypes.ts @@ -0,0 +1,304 @@ +import { + ContainerType, + ListCompositeType, + ByteVectorType, + VectorCompositeType, + ByteListType, + OptionalType, +} from "@chainsafe/ssz"; +import { + HISTORICAL_ROOTS_LIMIT, + VERKLE_WIDTH, + MAX_STEMS, + IPA_PROOF_DEPTH, + MAX_COMMITMENTS_PER_STEM, + BLOCK_BODY_EXECUTION_PAYLOAD_DEPTH as EXECUTION_PAYLOAD_DEPTH, + EPOCHS_PER_SYNC_COMMITTEE_PERIOD, + SLOTS_PER_EPOCH, +} from "@lodestar/params"; +import {ssz as primitiveSsz} from "../primitive/index.js"; +import {ssz as phase0Ssz} from "../phase0/index.js"; +import {ssz as altairSsz} from "../altair/index.js"; +import {ssz as bellatrixSsz} from "../bellatrix/index.js"; +import {ssz as capellaSsz} from "../capella/index.js"; +// import {ssz as denebSsz} from "../deneb/index.js"; + +const {UintNum64, Root, BLSSignature, Slot, Bytes32, UintBn256, BLSPubkey} = primitiveSsz; + +// Spec: https://github.com/ethereum/consensus-specs/blob/db74090c1e8dc1fb2c052bae268e22dc63061e32/specs/verge/beacon-chain.md + +// Custom types + +export const Bytes31 = new ByteVectorType(31); +export const BanderwagonGroupElement = new ByteVectorType(32); +export const BanderwagonFieldElement = new ByteVectorType(32); +export const Stem = new ByteVectorType(31); + +// Beacon chain + +export const SuffixStateDiff = new ContainerType( + { + suffix: primitiveSsz.Byte, + // Null means not currently present + currentValue: new OptionalType(primitiveSsz.Bytes32), + // Null means value not updated + newValue: new OptionalType(primitiveSsz.Bytes32), + }, + { + typeName: "SuffixStateDiff", + casingMap: { + suffix: "suffix", + currentValue: "currentValue", + newValue: "newValue", + }, + } +); + +export const StemStateDiff = new ContainerType( + { + stem: Stem, + // Valid only if list is sorted by suffixes + suffixDiffs: new ListCompositeType(SuffixStateDiff, VERKLE_WIDTH), + }, + {typeName: "StemStateDiff", casingMap: {stem: "stem", suffixDiffs: "suffixDiffs"}} +); + +// Valid only if list is sorted by stems +export const StateDiff = new ListCompositeType(StemStateDiff, MAX_STEMS); + +export const IpaProof = new ContainerType( + { + cl: new VectorCompositeType(BanderwagonGroupElement, IPA_PROOF_DEPTH), + cr: new VectorCompositeType(BanderwagonGroupElement, IPA_PROOF_DEPTH), + finalEvaluation: BanderwagonFieldElement, + }, + {typeName: "IpaProof", casingMap: {cl: "cl", cr: "cr", finalEvaluation: "finalEvaluation"}} +); + +export const VerkleProof = new ContainerType( + { + otherStems: new ListCompositeType(Bytes31, MAX_STEMS), + depthExtensionPresent: new ByteListType(MAX_STEMS), + commitmentsByPath: new ListCompositeType(BanderwagonGroupElement, MAX_STEMS * MAX_COMMITMENTS_PER_STEM), + d: BanderwagonGroupElement, + ipaProof: IpaProof, + }, + { + typeName: "VerkleProof", + casingMap: { + otherStems: "otherStems", + depthExtensionPresent: "depthExtensionPresent", + commitmentsByPath: "commitmentsByPath", + d: "d", + ipaProof: "ipaProof", + }, + } +); + +export const ExecutionWitness = new ContainerType( + { + stateDiff: StateDiff, + verkleProof: VerkleProof, + parentStateRoot: Root, + }, + { + typeName: "ExecutionWitness", + casingMap: {stateDiff: "stateDiff", verkleProof: "verkleProof", parentStateRoot: "parentStateRoot"}, + } +); + +// Beacon Chain types +// https://github.com/ethereum/consensus-specs/blob/dev/specs/eip4844/beacon-chain.md#containers + +export const ExecutionPayload = new ContainerType( + { + ...capellaSsz.ExecutionPayload.fields, + executionWitness: ExecutionWitness, // New in verkle + }, + {typeName: "ExecutionPayload", jsonCase: "eth2"} +); + +export const ExecutionPayloadHeader = new ContainerType( + { + ...capellaSsz.ExecutionPayloadHeader.fields, + executionWitnessRoot: Root, // New in verkle + }, + {typeName: "ExecutionPayloadHeader", jsonCase: "eth2"} +); + +// We have to preserve Fields ordering while changing the type of ExecutionPayload +export const BeaconBlockBody = new ContainerType( + { + ...altairSsz.BeaconBlockBody.fields, + executionPayload: ExecutionPayload, // Modified in verkle + blsToExecutionChanges: capellaSsz.BeaconBlockBody.fields.blsToExecutionChanges, + // blobKzgCommitments: denebSsz.BlobKzgCommitments, + }, + {typeName: "BeaconBlockBody", jsonCase: "eth2", cachePermanentRootStruct: true} +); + +export const BeaconBlock = new ContainerType( + { + ...capellaSsz.BeaconBlock.fields, + body: BeaconBlockBody, // Modified in verkle + }, + {typeName: "BeaconBlock", jsonCase: "eth2", cachePermanentRootStruct: true} +); + +export const SignedBeaconBlock = new ContainerType( + { + message: BeaconBlock, // Modified in verkle + signature: BLSSignature, + }, + {typeName: "SignedBeaconBlock", jsonCase: "eth2"} +); + +export const BuilderBid = new ContainerType( + { + header: ExecutionPayloadHeader, + value: UintBn256, + pubkey: BLSPubkey, + }, + {typeName: "BuilderBid", jsonCase: "eth2"} +); + +export const SignedBuilderBid = new ContainerType( + { + message: BuilderBid, + signature: BLSSignature, + }, + {typeName: "SignedBuilderBid", jsonCase: "eth2"} +); + +export const BlindedBeaconBlockBody = new ContainerType( + { + ...altairSsz.BeaconBlockBody.fields, + executionPayloadHeader: ExecutionPayloadHeader, // Modified in verkle + blsToExecutionChanges: capellaSsz.BeaconBlockBody.fields.blsToExecutionChanges, + // blobKzgCommitments: denebSsz.BlobKzgCommitments, + }, + {typeName: "BlindedBeaconBlockBody", jsonCase: "eth2", cachePermanentRootStruct: true} +); + +export const BlindedBeaconBlock = new ContainerType( + { + ...bellatrixSsz.BlindedBeaconBlock.fields, + body: BlindedBeaconBlockBody, // Modified in DENEB + }, + {typeName: "BlindedBeaconBlock", jsonCase: "eth2", cachePermanentRootStruct: true} +); + +export const SignedBlindedBeaconBlock = new ContainerType( + { + message: BlindedBeaconBlock, // Modified in DENEB + signature: BLSSignature, + }, + {typeName: "SignedBlindedBeaconBlock", jsonCase: "eth2"} +); + +// We don't spread capella.BeaconState fields since we need to replace +// latestExecutionPayloadHeader and we cannot keep order doing that +export const BeaconState = new ContainerType( + { + genesisTime: UintNum64, + genesisValidatorsRoot: Root, + slot: primitiveSsz.Slot, + fork: phase0Ssz.Fork, + // History + latestBlockHeader: phase0Ssz.BeaconBlockHeader, + blockRoots: phase0Ssz.HistoricalBlockRoots, + stateRoots: phase0Ssz.HistoricalStateRoots, + // historical_roots Frozen in Capella, replaced by historical_summaries + historicalRoots: new ListCompositeType(Root, HISTORICAL_ROOTS_LIMIT), + // Eth1 + eth1Data: phase0Ssz.Eth1Data, + eth1DataVotes: phase0Ssz.Eth1DataVotes, + eth1DepositIndex: UintNum64, + // Registry + validators: phase0Ssz.Validators, + balances: phase0Ssz.Balances, + randaoMixes: phase0Ssz.RandaoMixes, + // Slashings + slashings: phase0Ssz.Slashings, + // Participation + previousEpochParticipation: altairSsz.EpochParticipation, + currentEpochParticipation: altairSsz.EpochParticipation, + // Finality + justificationBits: phase0Ssz.JustificationBits, + previousJustifiedCheckpoint: phase0Ssz.Checkpoint, + currentJustifiedCheckpoint: phase0Ssz.Checkpoint, + finalizedCheckpoint: phase0Ssz.Checkpoint, + // Inactivity + inactivityScores: altairSsz.InactivityScores, + // Sync + currentSyncCommittee: altairSsz.SyncCommittee, + nextSyncCommittee: altairSsz.SyncCommittee, + // Execution + latestExecutionPayloadHeader: ExecutionPayloadHeader, // Modified in verkle + // Withdrawals + nextWithdrawalIndex: capellaSsz.BeaconState.fields.nextWithdrawalIndex, + nextWithdrawalValidatorIndex: capellaSsz.BeaconState.fields.nextWithdrawalValidatorIndex, + // Deep history valid from Capella onwards + historicalSummaries: capellaSsz.BeaconState.fields.historicalSummaries, + }, + {typeName: "BeaconState", jsonCase: "eth2"} +); + +export const LightClientHeader = new ContainerType( + { + beacon: phase0Ssz.BeaconBlockHeader, + execution: ExecutionPayloadHeader, + executionBranch: new VectorCompositeType(Bytes32, EXECUTION_PAYLOAD_DEPTH), + }, + {typeName: "LightClientHeader", jsonCase: "eth2"} +); + +export const LightClientBootstrap = new ContainerType( + { + header: LightClientHeader, + currentSyncCommittee: altairSsz.SyncCommittee, + currentSyncCommitteeBranch: altairSsz.LightClientBootstrap.fields.currentSyncCommitteeBranch, + }, + {typeName: "LightClientBootstrap", jsonCase: "eth2"} +); + +export const LightClientUpdate = new ContainerType( + { + attestedHeader: LightClientHeader, + nextSyncCommittee: altairSsz.SyncCommittee, + nextSyncCommitteeBranch: altairSsz.LightClientUpdate.fields.nextSyncCommitteeBranch, + finalizedHeader: LightClientHeader, + finalityBranch: altairSsz.LightClientUpdate.fields.finalityBranch, + syncAggregate: altairSsz.SyncAggregate, + signatureSlot: Slot, + }, + {typeName: "LightClientUpdate", jsonCase: "eth2"} +); + +export const LightClientFinalityUpdate = new ContainerType( + { + attestedHeader: LightClientHeader, + finalizedHeader: LightClientHeader, + finalityBranch: altairSsz.LightClientFinalityUpdate.fields.finalityBranch, + syncAggregate: altairSsz.SyncAggregate, + signatureSlot: Slot, + }, + {typeName: "LightClientFinalityUpdate", jsonCase: "eth2"} +); + +export const LightClientOptimisticUpdate = new ContainerType( + { + attestedHeader: LightClientHeader, + syncAggregate: altairSsz.SyncAggregate, + signatureSlot: Slot, + }, + {typeName: "LightClientOptimisticUpdate", jsonCase: "eth2"} +); + +export const LightClientStore = new ContainerType( + { + snapshot: LightClientBootstrap, + validUpdates: new ListCompositeType(LightClientUpdate, EPOCHS_PER_SYNC_COMMITTEE_PERIOD * SLOTS_PER_EPOCH), + }, + {typeName: "LightClientStore", jsonCase: "eth2"} +); diff --git a/packages/types/src/verkle/types.ts b/packages/types/src/verkle/types.ts new file mode 100644 index 000000000000..41e43a8c6d07 --- /dev/null +++ b/packages/types/src/verkle/types.ts @@ -0,0 +1,39 @@ +import {ValueOf} from "@chainsafe/ssz"; +import * as ssz from "./sszTypes.js"; + +export type Bytes31 = ValueOf; +export type BanderwagonGroupElement = ValueOf; +export type BanderwagonFieldElement = ValueOf; +export type Stem = ValueOf; + +export type SuffixStateDiff = ValueOf; +export type StemStateDiff = ValueOf; +export type StateDiff = ValueOf; +export type IpaProof = ValueOf; +export type VerkleProof = ValueOf; +export type ExecutionWitness = 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 FullOrBlindedExecutionPayload = ExecutionPayload | ExecutionPayloadHeader; + +export type BuilderBid = ValueOf; +export type SignedBuilderBid = 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/validator/src/util/params.ts b/packages/validator/src/util/params.ts index 6d6705f512df..e413618d5bbc 100644 --- a/packages/validator/src/util/params.ts +++ b/packages/validator/src/util/params.ts @@ -72,6 +72,7 @@ function getSpecCriticalParams(localConfig: ChainConfig): Record