diff --git a/packages/beacon-node/src/execution/engine/http.ts b/packages/beacon-node/src/execution/engine/http.ts index a69a5b94bd65..71df07293e10 100644 --- a/packages/beacon-node/src/execution/engine/http.ts +++ b/packages/beacon-node/src/execution/engine/http.ts @@ -1,5 +1,5 @@ -import {ExecutionPayload, Root, RootHex, Wei} from "@lodestar/types"; -import {SLOTS_PER_EPOCH, ForkName, ForkSeq} from "@lodestar/params"; +import {ExecutionPayload, ExecutionRequests, Root, RootHex, Wei} from "@lodestar/types"; +import {SLOTS_PER_EPOCH, ForkName, ForkSeq, isForkPostElectra} from "@lodestar/params"; import {Logger} from "@lodestar/logger"; import { ErrorJsonRpcResponse, @@ -37,6 +37,7 @@ import { ExecutionPayloadBody, assertReqSizeLimit, deserializeExecutionPayloadBody, + serializeExecutionRequests, } from "./types.js"; import {getExecutionEngineState} from "./utils.js"; @@ -195,7 +196,8 @@ export class ExecutionEngineHttp implements IExecutionEngine { fork: ForkName, executionPayload: ExecutionPayload, versionedHashes?: VersionedHashes, - parentBlockRoot?: Root + parentBlockRoot?: Root, + executionRequests?: ExecutionRequests ): Promise { const method = ForkSeq[fork] >= ForkSeq.electra @@ -220,12 +222,28 @@ export class ExecutionEngineHttp implements IExecutionEngine { const serializedVersionedHashes = serializeVersionedHashes(versionedHashes); const parentBeaconBlockRoot = serializeBeaconBlockRoot(parentBlockRoot); - const method = ForkSeq[fork] >= ForkSeq.electra ? "engine_newPayloadV4" : "engine_newPayloadV3"; - engineRequest = { - method, - params: [serializedExecutionPayload, serializedVersionedHashes, parentBeaconBlockRoot], - methodOpts: notifyNewPayloadOpts, - }; + if (ForkSeq[fork] >= ForkSeq.electra) { + if (executionRequests === undefined) { + throw Error(`executionRequests required in notifyNewPayload for fork=${fork}`); + } + const serializedExecutionRequests = serializeExecutionRequests(executionRequests); + engineRequest = { + method: "engine_newPayloadV4", + params: [ + serializedExecutionPayload, + serializedVersionedHashes, + parentBeaconBlockRoot, + serializedExecutionRequests, + ], + methodOpts: notifyNewPayloadOpts, + }; + } else { + engineRequest = { + method: "engine_newPayloadV3", + params: [serializedExecutionPayload, serializedVersionedHashes, parentBeaconBlockRoot], + methodOpts: notifyNewPayloadOpts, + }; + } } else { const method = ForkSeq[fork] >= ForkSeq.capella ? "engine_newPayloadV2" : "engine_newPayloadV1"; engineRequest = { diff --git a/packages/beacon-node/src/execution/engine/interface.ts b/packages/beacon-node/src/execution/engine/interface.ts index 5226a46ac720..53df1ae87c46 100644 --- a/packages/beacon-node/src/execution/engine/interface.ts +++ b/packages/beacon-node/src/execution/engine/interface.ts @@ -3,10 +3,10 @@ import {KZGCommitment, Blob, KZGProof} from "@lodestar/types/deneb"; import {Root, RootHex, capella, Wei, ExecutionPayload} from "@lodestar/types"; import {DATA} from "../../eth1/provider/utils.js"; -import {PayloadIdCache, PayloadId, WithdrawalV1, DepositRequestV1} from "./payloadIdCache.js"; +import {PayloadIdCache, PayloadId, WithdrawalV1} from "./payloadIdCache.js"; import {ExecutionPayloadBody} from "./types.js"; -export {PayloadIdCache, type PayloadId, type WithdrawalV1, type DepositRequestV1}; +export {PayloadIdCache, type PayloadId, type WithdrawalV1}; export enum ExecutionPayloadStatus { /** given payload is valid */ diff --git a/packages/beacon-node/src/execution/engine/payloadIdCache.ts b/packages/beacon-node/src/execution/engine/payloadIdCache.ts index 005a1ef14322..ea37e0922e9c 100644 --- a/packages/beacon-node/src/execution/engine/payloadIdCache.ts +++ b/packages/beacon-node/src/execution/engine/payloadIdCache.ts @@ -18,26 +18,6 @@ export type WithdrawalV1 = { amount: QUANTITY; }; -export type DepositRequestV1 = { - pubkey: DATA; - withdrawalCredentials: DATA; - amount: QUANTITY; - signature: DATA; - index: QUANTITY; -}; - -export type WithdrawalRequestV1 = { - sourceAddress: DATA; - validatorPubkey: DATA; - amount: QUANTITY; -}; - -export type ConsolidationRequestV1 = { - sourceAddress: DATA; - sourcePubkey: DATA; - targetPubkey: DATA; -}; - type FcuAttributes = {headBlockHash: DATA; finalizedBlockHash: DATA} & Omit; export class PayloadIdCache { diff --git a/packages/beacon-node/src/execution/engine/types.ts b/packages/beacon-node/src/execution/engine/types.ts index 139fc6822780..2d590616c379 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, electra, Wei, bellatrix, Root, ExecutionPayload, ExecutionRequests} from "@lodestar/types"; import { BYTES_PER_LOGS_BLOOM, FIELD_ELEMENTS_PER_BLOB, @@ -17,7 +17,7 @@ import { quantityToBigint, } from "../../eth1/provider/utils.js"; import {ExecutionPayloadStatus, BlobsBundle, PayloadAttributes, VersionedHashes} from "./interface.js"; -import {WithdrawalV1, DepositRequestV1, WithdrawalRequestV1, ConsolidationRequestV1} from "./payloadIdCache.js"; +import {WithdrawalV1} from "./payloadIdCache.js"; /* eslint-disable @typescript-eslint/naming-convention */ @@ -28,7 +28,7 @@ export type EngineApiRpcParamTypes = { engine_newPayloadV1: [ExecutionPayloadRpc]; engine_newPayloadV2: [ExecutionPayloadRpc]; engine_newPayloadV3: [ExecutionPayloadRpc, VersionedHashesRpc, DATA]; - engine_newPayloadV4: [ExecutionPayloadRpc, VersionedHashesRpc, DATA]; + engine_newPayloadV4: [ExecutionPayloadRpc, VersionedHashesRpc, DATA, ExecutionRequestsRpc]; /** * 1. Object - Payload validity status with respect to the consensus rules: * - blockHash: DATA, 32 Bytes - block hash value of the payload @@ -131,9 +131,9 @@ export type ExecutionPayloadBodyRpc = { withdrawals: WithdrawalV1[] | null | undefined; // currently there is a discepancy between EL and CL field name references for deposit requests // its likely CL receipt will be renamed to requests - depositRequests: DepositRequestV1[] | null | undefined; - withdrawalRequests: WithdrawalRequestV1[] | null | undefined; - consolidationRequests: ConsolidationRequestV1[] | null | undefined; + depositRequests: DepositRequestRpc[] | null | undefined; + withdrawalRequests: WithdrawalRequestRpc[] | null | undefined; + consolidationRequests: ConsolidationRequestRpc[] | null | undefined; }; export type ExecutionPayloadBody = { @@ -175,9 +175,29 @@ export type WithdrawalRpc = { amount: QUANTITY; }; -export type DepositRequestRpc = DepositRequestV1; -export type WithdrawalRequestRpc = WithdrawalRequestV1; -export type ConsolidationRequestRpc = ConsolidationRequestV1; +export type ExecutionRequestsRpc = { + deposits: DepositRequestRpc[]; + withdrawals: WithdrawalRequestRpc[]; + consolidations: ConsolidationRequestRpc[]; +}; + +export type DepositRequestRpc = { + pubkey: DATA; + withdrawalCredentials: DATA; + amount: QUANTITY; + signature: DATA; + index: QUANTITY; +}; +export type WithdrawalRequestRpc = { + sourceAddress: DATA; + validatorPubkey: DATA; + amount: QUANTITY; +}; +export type ConsolidationRequestRpc = { + sourceAddress: DATA; + sourcePubkey: DATA; + targetPubkey: DATA; +}; export type VersionedHashesRpc = DATA[]; @@ -241,12 +261,8 @@ export function serializeExecutionPayload(fork: ForkName, data: ExecutionPayload payload.excessBlobGas = numToQuantity(excessBlobGas); } - // ELECTRA adds depositRequests/depositRequests to the ExecutionPayload + // No changes in Electra if (ForkSeq[fork] >= ForkSeq.electra) { - const {depositRequests, withdrawalRequests, consolidationRequests} = data as electra.ExecutionPayload; - payload.depositRequests = depositRequests.map(serializeDepositRequest); - payload.withdrawalRequests = withdrawalRequests.map(serializeWithdrawalRequest); - payload.consolidationRequests = consolidationRequests.map(serializeConsolidationRequest); } return payload; @@ -334,33 +350,32 @@ export function parseExecutionPayload( (executionPayload as deneb.ExecutionPayload).excessBlobGas = quantityToBigint(excessBlobGas); } + // No changes in Electra if (ForkSeq[fork] >= ForkSeq.electra) { - // electra adds depositRequests/depositRequests - const {depositRequests, withdrawalRequests, consolidationRequests} = data; - // Geth can also reply with null - if (depositRequests == null) { - throw Error( - `depositRequests missing for ${fork} >= electra executionPayload number=${executionPayload.blockNumber} hash=${data.blockHash}` - ); - } - (executionPayload as electra.ExecutionPayload).depositRequests = depositRequests.map(deserializeDepositRequest); - - if (withdrawalRequests == null) { - throw Error( - `withdrawalRequests missing for ${fork} >= electra executionPayload number=${executionPayload.blockNumber} hash=${data.blockHash}` - ); - } - (executionPayload as electra.ExecutionPayload).withdrawalRequests = - withdrawalRequests.map(deserializeWithdrawalRequest); - - if (consolidationRequests == null) { - throw Error( - `consolidationRequests missing for ${fork} >= electra executionPayload number=${executionPayload.blockNumber} hash=${data.blockHash}` - ); - } - (executionPayload as electra.ExecutionPayload).consolidationRequests = consolidationRequests.map( - deserializeConsolidationRequest - ); + // // electra adds depositRequests/depositRequests + // const {depositRequests, withdrawalRequests, consolidationRequests} = data; + // // Geth can also reply with null + // if (depositRequests == null) { + // throw Error( + // `depositRequests missing for ${fork} >= electra executionPayload number=${executionPayload.blockNumber} hash=${data.blockHash}` + // ); + // } + // (executionPayload as electra.ExecutionPayload).depositRequests = depositRequests.map(deserializeDepositRequest); + // if (withdrawalRequests == null) { + // throw Error( + // `withdrawalRequests missing for ${fork} >= electra executionPayload number=${executionPayload.blockNumber} hash=${data.blockHash}` + // ); + // } + // (executionPayload as electra.ExecutionPayload).withdrawalRequests = + // withdrawalRequests.map(deserializeWithdrawalRequest); + // if (consolidationRequests == null) { + // throw Error( + // `consolidationRequests missing for ${fork} >= electra executionPayload number=${executionPayload.blockNumber} hash=${data.blockHash}` + // ); + // } + // (executionPayload as electra.ExecutionPayload).consolidationRequests = consolidationRequests.map( + // deserializeConsolidationRequest + // ); } return {executionPayload, executionPayloadValue, blobsBundle, shouldOverrideBuilder}; @@ -429,7 +444,7 @@ export function deserializeWithdrawal(serialized: WithdrawalRpc): capella.Withdr } as capella.Withdrawal; } -export function serializeDepositRequest(depositRequest: electra.DepositRequest): DepositRequestRpc { +function serializeDepositRequest(depositRequest: electra.DepositRequest): DepositRequestRpc { return { pubkey: bytesToData(depositRequest.pubkey), withdrawalCredentials: bytesToData(depositRequest.withdrawalCredentials), @@ -439,7 +454,7 @@ export function serializeDepositRequest(depositRequest: electra.DepositRequest): }; } -export function deserializeDepositRequest(serialized: DepositRequestRpc): electra.DepositRequest { +function deserializeDepositRequest(serialized: DepositRequestRpc): electra.DepositRequest { return { pubkey: dataToBytes(serialized.pubkey, 48), withdrawalCredentials: dataToBytes(serialized.withdrawalCredentials, 32), @@ -449,7 +464,7 @@ export function deserializeDepositRequest(serialized: DepositRequestRpc): electr } as electra.DepositRequest; } -export function serializeWithdrawalRequest(withdrawalRequest: electra.WithdrawalRequest): WithdrawalRequestRpc { +function serializeWithdrawalRequest(withdrawalRequest: electra.WithdrawalRequest): WithdrawalRequestRpc { return { sourceAddress: bytesToData(withdrawalRequest.sourceAddress), validatorPubkey: bytesToData(withdrawalRequest.validatorPubkey), @@ -457,7 +472,7 @@ export function serializeWithdrawalRequest(withdrawalRequest: electra.Withdrawal }; } -export function deserializeWithdrawalRequest(withdrawalRequest: WithdrawalRequestRpc): electra.WithdrawalRequest { +function deserializeWithdrawalRequest(withdrawalRequest: WithdrawalRequestRpc): electra.WithdrawalRequest { return { sourceAddress: dataToBytes(withdrawalRequest.sourceAddress, 20), validatorPubkey: dataToBytes(withdrawalRequest.validatorPubkey, 48), @@ -465,9 +480,7 @@ export function deserializeWithdrawalRequest(withdrawalRequest: WithdrawalReques }; } -export function serializeConsolidationRequest( - consolidationRequest: electra.ConsolidationRequest -): ConsolidationRequestRpc { +function serializeConsolidationRequest(consolidationRequest: electra.ConsolidationRequest): ConsolidationRequestRpc { return { sourceAddress: bytesToData(consolidationRequest.sourceAddress), sourcePubkey: bytesToData(consolidationRequest.sourcePubkey), @@ -475,9 +488,7 @@ export function serializeConsolidationRequest( }; } -export function deserializeConsolidationRequest( - consolidationRequest: ConsolidationRequestRpc -): electra.ConsolidationRequest { +function deserializeConsolidationRequest(consolidationRequest: ConsolidationRequestRpc): electra.ConsolidationRequest { return { sourceAddress: dataToBytes(consolidationRequest.sourceAddress, 20), sourcePubkey: dataToBytes(consolidationRequest.sourcePubkey, 48), @@ -485,6 +496,25 @@ export function deserializeConsolidationRequest( }; } +export function serializeExecutionRequests(executionRequests: ExecutionRequests): ExecutionRequestsRpc { + const {deposits, withdrawals, consolidations} = executionRequests; + return { + deposits: deposits.map(serializeDepositRequest), + withdrawals: withdrawals.map(serializeWithdrawalRequest), + consolidations: consolidations.map(serializeConsolidationRequest), + }; +} + +export function deserializeExecutionRequests(executionRequests: ExecutionRequestsRpc): ExecutionRequests { + const {deposits, withdrawals, consolidations} = executionRequests; + return { + deposits: deposits.map(deserializeDepositRequest), + withdrawals: withdrawals.map(deserializeWithdrawalRequest), + consolidations: consolidations.map(deserializeConsolidationRequest), + }; +} + +// TODO ELectra: remove requests field export function deserializeExecutionPayloadBody(data: ExecutionPayloadBodyRpc | null): ExecutionPayloadBody | null { return data ? { diff --git a/packages/beacon-node/test/unit/chain/lightclient/upgradeLightClientHeader.test.ts b/packages/beacon-node/test/unit/chain/lightclient/upgradeLightClientHeader.test.ts index abb520bddafb..6da728be46e9 100644 --- a/packages/beacon-node/test/unit/chain/lightclient/upgradeLightClientHeader.test.ts +++ b/packages/beacon-node/test/unit/chain/lightclient/upgradeLightClientHeader.test.ts @@ -28,7 +28,7 @@ describe("UpgradeLightClientHeader", function () { capella: ssz.capella.LightClientHeader.defaultValue(), bellatrix: ssz.altair.LightClientHeader.defaultValue(), deneb: ssz.deneb.LightClientHeader.defaultValue(), - electra: ssz.electra.LightClientHeader.defaultValue(), + electra: ssz.deneb.LightClientHeader.defaultValue(), }; testSlots = { diff --git a/packages/light-client/src/spec/utils.ts b/packages/light-client/src/spec/utils.ts index 872aa5d9f910..408412464606 100644 --- a/packages/light-client/src/spec/utils.ts +++ b/packages/light-client/src/spec/utils.ts @@ -128,12 +128,7 @@ export function upgradeLightClientHeader( // eslint-disable-next-line no-fallthrough case ForkName.electra: - (upgradedHeader as LightClientHeader).execution.depositRequestsRoot = - ssz.electra.LightClientHeader.fields.execution.fields.depositRequestsRoot.defaultValue(); - (upgradedHeader as LightClientHeader).execution.withdrawalRequestsRoot = - ssz.electra.LightClientHeader.fields.execution.fields.withdrawalRequestsRoot.defaultValue(); - (upgradedHeader as LightClientHeader).execution.consolidationRequestsRoot = - ssz.electra.LightClientHeader.fields.execution.fields.consolidationRequestsRoot.defaultValue(); + // No changes to LightClientHeader in Electra // Break if no further upgrades is required else fall through if (ForkSeq[targetFork] <= ForkSeq.electra) break; @@ -170,16 +165,6 @@ export function isValidLightClientHeader(config: ChainForkConfig, header: LightC } } - if (epoch < config.ELECTRA_FORK_EPOCH) { - if ( - (header as LightClientHeader).execution.depositRequestsRoot !== undefined || - (header as LightClientHeader).execution.withdrawalRequestsRoot !== undefined || - (header as LightClientHeader).execution.consolidationRequestsRoot !== undefined - ) { - return false; - } - } - return isValidMerkleBranch( config .getExecutionForkTypes(header.beacon.slot) diff --git a/packages/state-transition/src/block/processOperations.ts b/packages/state-transition/src/block/processOperations.ts index 6f61e7c242fb..bb52af14ba32 100644 --- a/packages/state-transition/src/block/processOperations.ts +++ b/packages/state-transition/src/block/processOperations.ts @@ -67,15 +67,15 @@ export function processOperations( const stateElectra = state as CachedBeaconStateElectra; const bodyElectra = body as electra.BeaconBlockBody; - for (const depositRequest of bodyElectra.executionPayload.depositRequests) { + for (const depositRequest of bodyElectra.executionRequests.deposits) { processDepositRequest(fork, stateElectra, depositRequest); } - for (const elWithdrawalRequest of bodyElectra.executionPayload.withdrawalRequests) { + for (const elWithdrawalRequest of bodyElectra.executionRequests.withdrawals) { processWithdrawalRequest(fork, stateElectra, elWithdrawalRequest); } - for (const elConsolidationRequest of bodyElectra.executionPayload.consolidationRequests) { + for (const elConsolidationRequest of bodyElectra.executionRequests.consolidations) { processConsolidationRequest(stateElectra, elConsolidationRequest); } } diff --git a/packages/state-transition/src/slot/upgradeStateToElectra.ts b/packages/state-transition/src/slot/upgradeStateToElectra.ts index 6600ad98e80a..87aee5727470 100644 --- a/packages/state-transition/src/slot/upgradeStateToElectra.ts +++ b/packages/state-transition/src/slot/upgradeStateToElectra.ts @@ -48,17 +48,11 @@ export function upgradeStateToElectra(stateDeneb: CachedBeaconStateDeneb): Cache stateElectraView.inactivityScores = stateElectraCloned.inactivityScores; stateElectraView.currentSyncCommittee = stateElectraCloned.currentSyncCommittee; stateElectraView.nextSyncCommittee = stateElectraCloned.nextSyncCommittee; - stateElectraView.latestExecutionPayloadHeader = ssz.electra.BeaconState.fields.latestExecutionPayloadHeader.toViewDU({ - ...stateElectraCloned.latestExecutionPayloadHeader.toValue(), - depositRequestsRoot: ssz.Root.defaultValue(), - withdrawalRequestsRoot: ssz.Root.defaultValue(), - consolidationRequestsRoot: ssz.Root.defaultValue(), - }); + stateElectraView.latestExecutionPayloadHeader = stateElectraCloned.latestExecutionPayloadHeader; stateElectraView.nextWithdrawalIndex = stateDeneb.nextWithdrawalIndex; stateElectraView.nextWithdrawalValidatorIndex = stateDeneb.nextWithdrawalValidatorIndex; stateElectraView.historicalSummaries = stateElectraCloned.historicalSummaries; - // latestExecutionPayloadHeader's depositRequestsRoot and withdrawalRequestsRoot set to zeros by default // default value of depositRequestsStartIndex is UNSET_DEPOSIT_REQUESTS_START_INDEX stateElectraView.depositRequestsStartIndex = UNSET_DEPOSIT_REQUESTS_START_INDEX; stateElectraView.depositBalanceToConsume = BigInt(0); diff --git a/packages/state-transition/src/util/execution.ts b/packages/state-transition/src/util/execution.ts index 06e654f9f1d2..e11b588896c9 100644 --- a/packages/state-transition/src/util/execution.ts +++ b/packages/state-transition/src/util/execution.ts @@ -2,7 +2,6 @@ import { bellatrix, capella, deneb, - electra, isBlindedBeaconBlockBody, ssz, BeaconBlock, @@ -172,12 +171,13 @@ export function executionPayloadToPayloadHeader(fork: ForkSeq, payload: Executio } if (fork >= ForkSeq.electra) { - (bellatrixPayloadFields as electra.ExecutionPayloadHeader).depositRequestsRoot = - ssz.electra.DepositRequests.hashTreeRoot((payload as electra.ExecutionPayload).depositRequests); - (bellatrixPayloadFields as electra.ExecutionPayloadHeader).withdrawalRequestsRoot = - ssz.electra.WithdrawalRequests.hashTreeRoot((payload as electra.ExecutionPayload).withdrawalRequests); - (bellatrixPayloadFields as electra.ExecutionPayloadHeader).consolidationRequestsRoot = - ssz.electra.ConsolidationRequests.hashTreeRoot((payload as electra.ExecutionPayload).consolidationRequests); + // No change in Electra + // (bellatrixPayloadFields as electra.ExecutionPayloadHeader).depositRequestsRoot = + // ssz.electra.DepositRequests.hashTreeRoot((payload as electra.ExecutionPayload).depositRequests); + // (bellatrixPayloadFields as electra.ExecutionPayloadHeader).withdrawalRequestsRoot = + // ssz.electra.WithdrawalRequests.hashTreeRoot((payload as electra.ExecutionPayload).withdrawalRequests); + // (bellatrixPayloadFields as electra.ExecutionPayloadHeader).consolidationRequestsRoot = + // ssz.electra.ConsolidationRequests.hashTreeRoot((payload as electra.ExecutionPayload).consolidationRequests); } return bellatrixPayloadFields; diff --git a/packages/types/src/electra/sszTypes.ts b/packages/types/src/electra/sszTypes.ts index 522f7245cc1b..909ac4b2c611 100644 --- a/packages/types/src/electra/sszTypes.ts +++ b/packages/types/src/electra/sszTypes.ts @@ -8,7 +8,6 @@ import { } from "@chainsafe/ssz"; import { HISTORICAL_ROOTS_LIMIT, - BLOCK_BODY_EXECUTION_PAYLOAD_DEPTH as EXECUTION_PAYLOAD_DEPTH, EPOCHS_PER_SYNC_COMMITTEE_PERIOD, SLOTS_PER_EPOCH, MAX_DEPOSIT_REQUESTS_PER_PAYLOAD, @@ -149,25 +148,18 @@ export const ConsolidationRequests = new ListCompositeType( MAX_CONSOLIDATION_REQUESTS_PER_PAYLOAD ); -export const ExecutionPayload = new ContainerType( +export const ExecutionRequests = new ContainerType( { - ...denebSsz.ExecutionPayload.fields, - depositRequests: DepositRequests, // New in ELECTRA - withdrawalRequests: WithdrawalRequests, // New in ELECTRA - consolidationRequests: ConsolidationRequests, // New in ELECTRA + deposits: DepositRequests, + withdrawals: WithdrawalRequests, + consolidations: ConsolidationRequests, }, - {typeName: "ExecutionPayload", jsonCase: "eth2"} + {typeName: "ExecutionRequests", jsonCase: "eth2"} ); -export const ExecutionPayloadHeader = new ContainerType( - { - ...denebSsz.ExecutionPayloadHeader.fields, - depositRequestsRoot: Root, // New in ELECTRA - withdrawalRequestsRoot: Root, // New in ELECTRA - consolidationRequestsRoot: Root, // New in ELECTRA - }, - {typeName: "ExecutionPayloadHeader", jsonCase: "eth2"} -); +// Explicitly defining electra containers for consistency's sake +export const ExecutionPayloadHeader = denebSsz.ExecutionPayloadHeader; +export const ExecutionPayload = denebSsz.ExecutionPayload; // We have to preserve Fields ordering while changing the type of ExecutionPayload export const BeaconBlockBody = new ContainerType( @@ -181,9 +173,10 @@ export const BeaconBlockBody = new ContainerType( deposits: phase0Ssz.BeaconBlockBody.fields.deposits, voluntaryExits: phase0Ssz.BeaconBlockBody.fields.voluntaryExits, syncAggregate: altairSsz.BeaconBlockBody.fields.syncAggregate, - executionPayload: ExecutionPayload, // Modified in ELECTRA + executionPayload: ExecutionPayload, blsToExecutionChanges: capellaSsz.BeaconBlockBody.fields.blsToExecutionChanges, blobKzgCommitments: denebSsz.BeaconBlockBody.fields.blobKzgCommitments, + executionRequests: ExecutionRequests, // New in ELECTRA:EIP7251 }, {typeName: "BeaconBlockBody", jsonCase: "eth2", cachePermanentRootStruct: true} ); @@ -215,7 +208,7 @@ export const BlindedBeaconBlockBody = new ContainerType( deposits: phase0Ssz.BeaconBlockBody.fields.deposits, voluntaryExits: phase0Ssz.BeaconBlockBody.fields.voluntaryExits, syncAggregate: altairSsz.SyncAggregate, - executionPayloadHeader: ExecutionPayloadHeader, // Modified in ELECTRA + executionPayloadHeader: ExecutionPayloadHeader, blsToExecutionChanges: capellaSsz.BeaconBlockBody.fields.blsToExecutionChanges, blobKzgCommitments: denebSsz.BeaconBlockBody.fields.blobKzgCommitments, }, @@ -256,13 +249,13 @@ export const SignedBuilderBid = new ContainerType( {typeName: "SignedBuilderBid", jsonCase: "eth2"} ); -export const ExecutionPayloadAndBlobsBundle = new ContainerType( - { - executionPayload: ExecutionPayload, // Modified in ELECTRA - blobsBundle: denebSsz.BlobsBundle, - }, - {typeName: "ExecutionPayloadAndBlobsBundle", jsonCase: "eth2"} -); +// export const ExecutionPayloadAndBlobsBundle = new ContainerType( +// { +// executionPayload: denebSsz.ExecutionPayload, +// blobsBundle: denebSsz.BlobsBundle, +// }, +// {typeName: "ExecutionPayloadAndBlobsBundle", jsonCase: "eth2"} +// ); export const PendingBalanceDeposit = new ContainerType( { @@ -328,7 +321,7 @@ export const BeaconState = new ContainerType( currentSyncCommittee: altairSsz.SyncCommittee, nextSyncCommittee: altairSsz.SyncCommittee, // Execution - latestExecutionPayloadHeader: ExecutionPayloadHeader, // Modified in ELECTRA + latestExecutionPayloadHeader: ExecutionPayloadHeader, // Withdrawals nextWithdrawalIndex: capellaSsz.BeaconState.fields.nextWithdrawalIndex, nextWithdrawalValidatorIndex: capellaSsz.BeaconState.fields.nextWithdrawalValidatorIndex, @@ -347,30 +340,21 @@ export const BeaconState = new ContainerType( {typeName: "BeaconState", jsonCase: "eth2"} ); -export const LightClientHeader = new ContainerType( - { - beacon: phase0Ssz.BeaconBlockHeader, - execution: ExecutionPayloadHeader, // Modified in ELECTRA - executionBranch: new VectorCompositeType(Bytes32, EXECUTION_PAYLOAD_DEPTH), - }, - {typeName: "LightClientHeader", jsonCase: "eth2"} -); - export const LightClientBootstrap = new ContainerType( { - header: LightClientHeader, // Modified in ELECTRA + header: denebSsz.LightClientHeader, currentSyncCommittee: altairSsz.SyncCommittee, - currentSyncCommitteeBranch: new VectorCompositeType(Bytes32, NEXT_SYNC_COMMITTEE_DEPTH_ELECTRA), // Modified in ELECTRA + currentSyncCommitteeBranch: new VectorCompositeType(Bytes32, NEXT_SYNC_COMMITTEE_DEPTH_ELECTRA), }, {typeName: "LightClientBootstrap", jsonCase: "eth2"} ); export const LightClientUpdate = new ContainerType( { - attestedHeader: LightClientHeader, // Modified in ELECTRA + attestedHeader: denebSsz.LightClientHeader, nextSyncCommittee: altairSsz.SyncCommittee, nextSyncCommitteeBranch: new VectorCompositeType(Bytes32, NEXT_SYNC_COMMITTEE_DEPTH_ELECTRA), // Modified in ELECTRA - finalizedHeader: LightClientHeader, // Modified in ELECTRA + finalizedHeader: denebSsz.LightClientHeader, finalityBranch: new VectorCompositeType(Bytes32, FINALIZED_ROOT_DEPTH_ELECTRA), // Modified in ELECTRA syncAggregate: altairSsz.SyncAggregate, signatureSlot: Slot, @@ -380,8 +364,8 @@ export const LightClientUpdate = new ContainerType( export const LightClientFinalityUpdate = new ContainerType( { - attestedHeader: LightClientHeader, - finalizedHeader: LightClientHeader, + attestedHeader: denebSsz.LightClientHeader, + finalizedHeader: denebSsz.LightClientHeader, finalityBranch: new VectorCompositeType(Bytes32, FINALIZED_ROOT_DEPTH_ELECTRA), // Modified in ELECTRA syncAggregate: altairSsz.SyncAggregate, signatureSlot: Slot, @@ -391,7 +375,7 @@ export const LightClientFinalityUpdate = new ContainerType( export const LightClientOptimisticUpdate = new ContainerType( { - attestedHeader: LightClientHeader, // Modified in ELECTRA + attestedHeader: denebSsz.LightClientHeader, syncAggregate: altairSsz.SyncAggregate, signatureSlot: Slot, }, @@ -400,8 +384,8 @@ export const LightClientOptimisticUpdate = new ContainerType( export const LightClientStore = new ContainerType( { - snapshot: LightClientBootstrap, // Modified in ELECTRA - validUpdates: new ListCompositeType(LightClientUpdate, EPOCHS_PER_SYNC_COMMITTEE_PERIOD * SLOTS_PER_EPOCH), // Modified in ELECTRA + snapshot: LightClientBootstrap, + validUpdates: new ListCompositeType(LightClientUpdate, EPOCHS_PER_SYNC_COMMITTEE_PERIOD * SLOTS_PER_EPOCH), }, {typeName: "LightClientStore", jsonCase: "eth2"} ); diff --git a/packages/types/src/electra/types.ts b/packages/types/src/electra/types.ts index 9a81aec43b53..cfe4f5c24e18 100644 --- a/packages/types/src/electra/types.ts +++ b/packages/types/src/electra/types.ts @@ -20,8 +20,9 @@ export type ConsolidationRequests = ValueOf; export type ExecutionPayload = ValueOf; export type ExecutionPayloadHeader = ValueOf; +export type ExecutionRequests = ValueOf; -export type ExecutionPayloadAndBlobsBundle = ValueOf; +// export type ExecutionPayloadAndBlobsBundle = ValueOf; export type BeaconBlockBody = ValueOf; export type BeaconBlock = ValueOf; @@ -33,13 +34,13 @@ export type BlindedBeaconBlockBody = ValueOf; export type BlindedBeaconBlock = ValueOf; export type SignedBlindedBeaconBlock = ValueOf; -export type FullOrBlindedExecutionPayload = ExecutionPayload | ExecutionPayloadHeader; +// export type FullOrBlindedExecutionPayload = ExecutionPayload | ExecutionPayloadHeader; export type BuilderBid = ValueOf; export type SignedBuilderBid = ValueOf; export type SSEPayloadAttributes = ValueOf; -export type LightClientHeader = ValueOf; +// export type LightClientHeader = ValueOf; export type LightClientBootstrap = ValueOf; export type LightClientUpdate = ValueOf; export type LightClientFinalityUpdate = ValueOf; diff --git a/packages/types/src/types.ts b/packages/types/src/types.ts index 1071eed79a10..08fc06ac6cb9 100644 --- a/packages/types/src/types.ts +++ b/packages/types/src/types.ts @@ -1,4 +1,12 @@ -import {ForkAll, ForkBlobs, ForkExecution, ForkLightClient, ForkName, ForkPreBlobs} from "@lodestar/params"; +import { + ForkAll, + ForkBlobs, + ForkExecution, + ForkLightClient, + ForkName, + ForkPostElectra, + ForkPreBlobs, +} from "@lodestar/params"; import {ts as phase0} from "./phase0/index.js"; import {ts as altair} from "./altair/index.js"; import {ts as bellatrix} from "./bellatrix/index.js"; @@ -172,7 +180,7 @@ type TypesByFork = { BeaconState: electra.BeaconState; SignedBeaconBlock: electra.SignedBeaconBlock; Metadata: altair.Metadata; - LightClientHeader: electra.LightClientHeader; + LightClientHeader: deneb.LightClientHeader; LightClientBootstrap: electra.LightClientBootstrap; LightClientUpdate: electra.LightClientUpdate; LightClientFinalityUpdate: electra.LightClientFinalityUpdate; @@ -181,8 +189,8 @@ type TypesByFork = { BlindedBeaconBlock: electra.BlindedBeaconBlock; BlindedBeaconBlockBody: electra.BlindedBeaconBlockBody; SignedBlindedBeaconBlock: electra.SignedBlindedBeaconBlock; - ExecutionPayload: electra.ExecutionPayload; - ExecutionPayloadHeader: electra.ExecutionPayloadHeader; + ExecutionPayload: deneb.ExecutionPayload; + ExecutionPayloadHeader: deneb.ExecutionPayloadHeader; BuilderBid: electra.BuilderBid; SignedBuilderBid: electra.SignedBuilderBid; SSEPayloadAttributes: electra.SSEPayloadAttributes; @@ -199,6 +207,7 @@ type TypesByFork = { AttesterSlashing: electra.AttesterSlashing; AggregateAndProof: electra.AggregateAndProof; SignedAggregateAndProof: electra.SignedAggregateAndProof; + ExecutionRequests: electra.ExecutionRequests; }; }; @@ -233,6 +242,7 @@ export type SignedBeaconBlockOrContents = TypesByFork[F]["ExecutionPayload"]; export type ExecutionPayloadHeader = TypesByFork[F]["ExecutionPayloadHeader"]; +export type ExecutionRequests = TypesByFork[F]["ExecutionRequests"]; export type BlobsBundle = TypesByFork[F]["BlobsBundle"]; export type Contents = TypesByFork[F]["Contents"]; diff --git a/packages/types/src/utils/typeguards.ts b/packages/types/src/utils/typeguards.ts index a5f5b7808ae5..a892c3a0c9c0 100644 --- a/packages/types/src/utils/typeguards.ts +++ b/packages/types/src/utils/typeguards.ts @@ -1,4 +1,4 @@ -import {ForkBlobs, ForkExecution, ForkPostElectra} from "@lodestar/params"; +import {FINALIZED_ROOT_DEPTH_ELECTRA, ForkBlobs, ForkExecution, ForkPostElectra} from "@lodestar/params"; import { BlockContents, SignedBeaconBlock, @@ -76,7 +76,7 @@ export function isElectraAttestation(attestation: Attestation): attestation is A export function isElectraLightClientUpdate(update: LightClientUpdate): update is LightClientUpdate { const updatePostElectra = update as LightClientUpdate; return ( - updatePostElectra.attestedHeader.execution !== undefined && - updatePostElectra.attestedHeader.execution.depositRequestsRoot !== undefined + updatePostElectra.finalityBranch !== undefined && + updatePostElectra.finalityBranch.length === FINALIZED_ROOT_DEPTH_ELECTRA ); }