Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/beacon-node/src/chain/blocks/importBlock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@ export async function importBlock(
if (headBlockHash !== ZERO_HASH_HEX) {
this.executionEngine
.notifyForkchoiceUpdate(
this.config.getForkSeq(this.forkChoice.getHead().slot),
this.config.getForkName(this.forkChoice.getHead().slot),
headBlockHash,
safeBlockHash,
finalizedBlockHash
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,7 @@ export async function verifyBlockExecutionPayload(

// TODO: Handle better notifyNewPayload() returning error is syncing
const execResult = await chain.executionEngine.notifyNewPayload(
chain.config.getForkSeq(block.message.slot),
chain.config.getForkName(block.message.slot),
executionPayloadEnabled
);

Expand Down
8 changes: 4 additions & 4 deletions packages/beacon-node/src/chain/prepareNextSlot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {Slot} from "@lodestar/types";
import {ILogger, sleep} from "@lodestar/utils";
import {GENESIS_SLOT, ZERO_HASH_HEX} from "../constants/constants.js";
import {IMetrics} from "../metrics/index.js";
import {TransitionConfigurationV1} from "../execution/engine/interface.js";
import {ForkExecution, TransitionConfigurationV1} from "../execution/engine/interface.js";
import {ChainEvent} from "./emitter.js";
import {prepareExecutionPayload} from "./produceBlock/produceBlockBody.js";
import {IBeaconChain} from "./interface.js";
Expand Down Expand Up @@ -55,11 +55,11 @@ export class PrepareNextSlotScheduler {
const prepareEpoch = computeEpochAtSlot(prepareSlot);
const nextEpoch = computeEpochAtSlot(clockSlot) + 1;
const isEpochTransition = prepareEpoch === nextEpoch;
const forkSeq = this.config.getForkSeq(prepareSlot);
const fork = this.config.getForkName(prepareSlot);

// Early return if we are pre-genesis
// or we are pre-bellatrix and this is not an epoch transition
if (prepareSlot <= GENESIS_SLOT || (forkSeq < ForkSeq.bellatrix && !isEpochTransition)) {
if (prepareSlot <= GENESIS_SLOT || (ForkSeq[fork] < ForkSeq.bellatrix && !isEpochTransition)) {
return;
}

Expand Down Expand Up @@ -137,8 +137,8 @@ export class PrepareNextSlotScheduler {
// left for scheduler and this gives nice sematics to catch and log errors in the
// try/catch wrapper here.
await prepareExecutionPayload(
forkSeq,
this.chain,
fork as ForkExecution, // State is of execution type
safeBlockHash,
finalizedBlockHash,
prepareState,
Expand Down
55 changes: 32 additions & 23 deletions packages/beacon-node/src/chain/produceBlock/produceBlockBody.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,13 @@ import {ForkName, ForkSeq} from "@lodestar/params";
import {toHex, sleep} from "@lodestar/utils";

import type {BeaconChain} from "../chain.js";
import {PayloadId, IExecutionEngine, IExecutionBuilder} from "../../execution/index.js";
import {
PayloadId,
IExecutionEngine,
IExecutionBuilder,
PayloadAttributes,
ForkExecution,
} from "../../execution/index.js";
import {ZERO_HASH, ZERO_HASH_HEX} from "../../constants/index.js";
import {IEth1ForBlockProduction} from "../../eth1/index.js";
import {numToQuantity} from "../../eth1/provider/utils.js";
Expand Down Expand Up @@ -114,8 +120,9 @@ export async function produceBlockBody<T extends BlockType>(
);
}

const forkInfo = currentState.config.getForkInfo(blockSlot);
if (forkInfo.name !== ForkName.phase0 && forkInfo.name !== ForkName.altair) {
const fork = currentState.config.getForkName(blockSlot);

if (fork !== ForkName.phase0 && fork !== ForkName.altair) {
const safeBlockHash = this.forkChoice.getJustifiedBlock().executionPayloadBlockHash ?? ZERO_HASH_HEX;
const finalizedBlockHash = this.forkChoice.getFinalizedBlock().executionPayloadBlockHash ?? ZERO_HASH_HEX;
const feeRecipient = this.beaconProposerCache.getOrDefault(proposerIndex);
Expand All @@ -128,8 +135,8 @@ export async function produceBlockBody<T extends BlockType>(
// header.
if (this.executionBuilder.issueLocalFcUForBlockProduction) {
await prepareExecutionPayload(
forkInfo.seq,
this,
fork,
safeBlockHash,
finalizedBlockHash ?? ZERO_HASH_HEX,
currentState as CachedBeaconStateBellatrix,
Expand All @@ -141,8 +148,8 @@ export async function produceBlockBody<T extends BlockType>(
// fetched from the payload id and a blinded block will be produced instead of
// fullblock for the validator to sign
(blockBody as allForks.BlindedBeaconBlockBody).executionPayloadHeader = await prepareExecutionPayloadHeader(
forkInfo.seq,
this,
fork,
currentState as CachedBeaconStateBellatrix,
proposerPubKey
);
Expand All @@ -152,16 +159,16 @@ export async function produceBlockBody<T extends BlockType>(
// will takeover if the builder flow was activated and errors
try {
const prepareRes = await prepareExecutionPayload(
forkInfo.seq,
this,
fork,
safeBlockHash,
finalizedBlockHash ?? ZERO_HASH_HEX,
currentState as CachedBeaconStateBellatrix,
feeRecipient
);
if (prepareRes.isPremerge) {
(blockBody as allForks.ExecutionBlockBody).executionPayload = ssz.allForksExecution[
forkInfo.name
fork
].ExecutionPayload.defaultValue();
} else {
const {prepType, payloadId} = prepareRes;
Expand All @@ -173,7 +180,7 @@ export async function produceBlockBody<T extends BlockType>(
// See: https://discord.com/channels/595666850260713488/892088344438255616/1009882079632314469
await sleep(PAYLOAD_GENERATION_TIME_MS);
}
const payload = await this.executionEngine.getPayload(forkInfo.seq, payloadId);
const payload = await this.executionEngine.getPayload(fork, payloadId);
(blockBody as allForks.ExecutionBlockBody).executionPayload = payload;

const fetchedTime = Date.now() / 1000 - computeTimeAtSlot(this.config, blockSlot, this.genesisTime);
Expand All @@ -194,7 +201,7 @@ export async function produceBlockBody<T extends BlockType>(
e as Error
);
(blockBody as allForks.ExecutionBlockBody).executionPayload = ssz.allForksExecution[
forkInfo.name
fork
].ExecutionPayload.defaultValue();
} else {
// since merge transition is complete, we need a valid payload even if with an
Expand All @@ -205,7 +212,7 @@ export async function produceBlockBody<T extends BlockType>(
}
}

if (forkInfo.seq >= ForkSeq.capella) {
if (ForkSeq[fork] >= ForkSeq.capella) {
// TODO: blsToExecutionChanges should be passed in the produceBlock call
(blockBody as capella.BeaconBlockBody).blsToExecutionChanges = [];
}
Expand All @@ -221,12 +228,12 @@ export async function produceBlockBody<T extends BlockType>(
* @returns PayloadId = pow block found, null = pow NOT found
*/
export async function prepareExecutionPayload(
fork: ForkSeq,
chain: {
eth1: IEth1ForBlockProduction;
executionEngine: IExecutionEngine;
config: IChainForkConfig;
},
fork: ForkExecution,
safeBlockHash: RootHex,
finalizedBlockHash: RootHex,
state: CachedBeaconStateExecutions,
Expand Down Expand Up @@ -268,21 +275,23 @@ export async function prepareExecutionPayload(
prepType = PayloadPreparationType.Fresh;
}

const withdrawalAttrs =
fork >= ForkSeq.capella
? {withdrawals: getExpectedWithdrawals(state as CachedBeaconStateCapella).withdrawals}
: {};
const attributes: PayloadAttributes = {
fork,
timestamp,
prevRandao,
suggestedFeeRecipient,
};

if (ForkSeq[fork] >= ForkSeq.capella) {
attributes.withdrawals = getExpectedWithdrawals(state as CachedBeaconStateCapella).withdrawals;
}

payloadId = await chain.executionEngine.notifyForkchoiceUpdate(
fork,
toHex(parentHash),
safeBlockHash,
finalizedBlockHash,
{
timestamp,
prevRandao,
suggestedFeeRecipient,
...withdrawalAttrs,
}
attributes
);
}

Expand All @@ -299,19 +308,19 @@ export async function prepareExecutionPayload(
}

async function prepareExecutionPayloadHeader(
fork: ForkSeq,
chain: {
eth1: IEth1ForBlockProduction;
executionBuilder?: IExecutionBuilder;
config: IChainForkConfig;
},
fork: ForkExecution,
state: CachedBeaconStateBellatrix,
proposerPubKey: BLSPubkey
): Promise<allForks.ExecutionPayloadHeader> {
if (!chain.executionBuilder) {
throw Error("executionBuilder required");
}
if (fork >= ForkSeq.capella) {
if (ForkSeq[fork] >= ForkSeq.capella) {
throw Error("executionBuilder capella api not implemented");
}

Expand Down
4 changes: 2 additions & 2 deletions packages/beacon-node/src/eth1/provider/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,10 +106,10 @@ export function bytesToData(bytes: Uint8Array): DATA {
/**
* DATA as defined in ethereum execution layer JSON RPC https://eth.wiki/json-rpc/API
*/
export function dataToBytes(hex: DATA, fixedLength?: number): Uint8Array {
export function dataToBytes(hex: DATA, fixedLength: number | null): Uint8Array {
try {
const bytes = fromHexString(hex);
if (fixedLength !== undefined && bytes.length !== fixedLength) {
if (fixedLength != null && bytes.length !== fixedLength) {
throw Error(`Wrong data length ${bytes.length} expected ${fixedLength}`);
}
return bytes;
Expand Down
5 changes: 5 additions & 0 deletions packages/beacon-node/src/execution/engine/disabled.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@ export class ExecutionEngineDisabled implements IExecutionEngine {
async getPayload(): Promise<never> {
throw Error("Execution engine disabled");
}

async getBlobsBundle(): Promise<never> {
throw Error("Execution engine disabled");
}

async exchangeTransitionConfigurationV1(): Promise<never> {
throw Error("Execution engine disabled");
}
Expand Down
Loading