Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
27a2075
feat: add cached PTC window to the state
nflaig Apr 13, 2026
5e61c06
feat: trigger processExecutionPayload() once
twoeths Apr 16, 2026
b37bc6c
fix: allDataPromise resolve
twoeths Apr 16, 2026
e80c801
Merge branch 'unstable' into nflaig/alpha4-spec-4979
ensi321 Apr 16, 2026
613aa40
Update specref
ensi321 Apr 16, 2026
6d5e9e5
feat: new event ChainEvent.incompletePayloadEnvelope
twoeths Apr 17, 2026
42c3077
Merge branch 'unstable' into nflaig/alpha4-spec-4979
ensi321 Apr 17, 2026
f34a278
feat: add EIP-7928 BlockAccessList to gloas ExecutionPayload
ensi321 Apr 17, 2026
9058ad0
feat: add EIP-7928 blockAccessList to engine API serialization
ensi321 Apr 17, 2026
8120218
feat: bump engine API versions
ensi321 Apr 17, 2026
bbe17c7
Apply suggestion from @nflaig
ensi321 Apr 17, 2026
a1cb951
update comment
ensi321 Apr 17, 2026
9bc6eb6
feat: implement should_apply_proposer_boost for gloas
ensi321 Apr 18, 2026
4531a52
Skip test
ensi321 Apr 18, 2026
5517f57
Shift to cache as primary approach
ensi321 Apr 19, 2026
000b21c
Address @nflaig's comment
ensi321 Apr 19, 2026
06d23f3
lint
ensi321 Apr 20, 2026
b4e9577
Revert changes to initializeBeaconStateFromEth1
ensi321 Apr 20, 2026
c4282b9
Revert changes to sanity test
ensi321 Apr 20, 2026
1332882
init
ensi321 Apr 15, 2026
aaa16f6
refactor: revert dual-state from block import, block production, and …
ensi321 Apr 15, 2026
bf29eba
Clean up
ensi321 Apr 15, 2026
bbb5929
refactor: update Gloas SSZ types for deferred payload processing (spe…
ensi321 Apr 15, 2026
644d7f3
feat: add processParentExecutionPayload and remove withdrawal early r…
ensi321 Apr 15, 2026
68457ea
refactor: add processParentExecutionPayload as first step in processB…
ensi321 Apr 15, 2026
9a4a2c9
refactor: transform processExecutionPayloadEnvelope to pure verification
ensi321 Apr 15, 2026
7b851dd
refactor: remove executionPayloadStateRoot from fork choice onExecuti…
ensi321 Apr 15, 2026
5fbb0bc
refactor: simplify envelope import pipeline for deferred processing
ensi321 Apr 15, 2026
067edb1
feat: block production, gossip validation, and cleanup for deferred p…
ensi321 Apr 15, 2026
a3385bd
fix: type errors in processParentExecutionPayload and produceBlockBody
ensi321 Apr 15, 2026
e2c96a5
feat: range sync envelope support for Gloas (supersedes #9155)
ensi321 Apr 15, 2026
da8f5bd
feat: unknown payload sync for incoming blocks (supersedes #9102)
ensi321 Apr 15, 2026
c360e70
feat: Gloas DataColumnSidecar validation in range sync
ensi321 Apr 15, 2026
4474255
fix: guard payload-seen check on known block and use seenPayloadEnvelope
ensi321 Apr 16, 2026
4923d10
Update comments
ensi321 Apr 14, 2026
78ca807
Update comments
ensi321 Apr 14, 2026
190fd13
Fix spec test
ensi321 Apr 16, 2026
f5821e9
Address comments & follow up on spec change
ensi321 Apr 16, 2026
b5f24e4
Swap latestBlockHash and latestExecutionPayloadBid
ensi321 Apr 17, 2026
fecfcb3
fix upgrade state
ensi321 Apr 17, 2026
397aaf9
Bump version, skip fast_confirmation
ensi321 Apr 20, 2026
bf2747d
feat: implement EIP-7843 slot_number in ExecutionPayload (specs#4840)
ensi321 Apr 20, 2026
0e493ef
merge
ensi321 Apr 20, 2026
9afce2e
Merge branch 'nc/should-apply-proposer-boost' into nc/alpha.5-vibe
ensi321 Apr 20, 2026
984d50d
fix spec test
ensi321 Apr 20, 2026
5ae6848
Merge branch 'te/trigger_process_execution_payload' into nc/alpha.5-v…
twoeths Apr 20, 2026
f06fc60
feat: range sync for alpha.5
twoeths Apr 21, 2026
ca2d133
fix: do not handle try catch for importExecutionPayload()
twoeths Apr 21, 2026
92ea861
feat: cache the last 2 PayloadEnvelopeInputs
twoeths Apr 21, 2026
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
4 changes: 2 additions & 2 deletions packages/api/src/beacon/routes/beacon/block.ts
Original file line number Diff line number Diff line change
Expand Up @@ -606,7 +606,7 @@ export function getDefinitions(config: ChainForkConfig): RouteDefinitions<Endpoi
method: "POST",
req: {
writeReqJson: ({signedExecutionPayloadEnvelope}) => {
const fork = config.getForkName(signedExecutionPayloadEnvelope.message.slot);
const fork = config.getForkName(signedExecutionPayloadEnvelope.message.payload.slotNumber);
return {
body: getPostGloasForkTypes(fork).SignedExecutionPayloadEnvelope.toJson(signedExecutionPayloadEnvelope),
headers: {
Expand All @@ -621,7 +621,7 @@ export function getDefinitions(config: ChainForkConfig): RouteDefinitions<Endpoi
};
},
writeReqSsz: ({signedExecutionPayloadEnvelope}) => {
const fork = config.getForkName(signedExecutionPayloadEnvelope.message.slot);
const fork = config.getForkName(signedExecutionPayloadEnvelope.message.payload.slotNumber);
return {
body: getPostGloasForkTypes(fork).SignedExecutionPayloadEnvelope.serialize(signedExecutionPayloadEnvelope),
headers: {
Expand Down
4 changes: 0 additions & 4 deletions packages/api/src/beacon/routes/events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -186,15 +186,13 @@ export type EventData = {
builderIndex: BuilderIndex;
blockHash: RootHex;
blockRoot: RootHex;
stateRoot: RootHex;
executionOptimistic: boolean;
};
[EventType.executionPayloadGossip]: {
slot: Slot;
builderIndex: BuilderIndex;
blockHash: RootHex;
blockRoot: RootHex;
stateRoot: RootHex;
};
[EventType.executionPayloadAvailable]: {
slot: Slot;
Expand Down Expand Up @@ -376,7 +374,6 @@ export function getTypeByEvent(config: ChainForkConfig): {[K in EventType]: Type
builderIndex: ssz.BuilderIndex,
blockHash: stringType,
blockRoot: stringType,
stateRoot: stringType,
executionOptimistic: ssz.Boolean,
},
{jsonCase: "eth2"}
Expand All @@ -387,7 +384,6 @@ export function getTypeByEvent(config: ChainForkConfig): {[K in EventType]: Type
builderIndex: ssz.BuilderIndex,
blockHash: stringType,
blockRoot: stringType,
stateRoot: stringType,
},
{jsonCase: "eth2"}
),
Expand Down
2 changes: 0 additions & 2 deletions packages/api/test/unit/beacon/testData/events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -279,15 +279,13 @@ export const eventTestData: EventData = {
builderIndex: 42,
blockHash: "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
blockRoot: "0x9a2fefd2fdb57f74993c7780ea5b9030d2897b615b89f808011ca5aebed54eaf",
stateRoot: "0x600e852a08c1200654ddf11025f1ceacb3c2e74bdd5c630cde0838b2591b69f9",
executionOptimistic: false,
},
[EventType.executionPayloadGossip]: {
slot: 10,
builderIndex: 42,
blockHash: "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
blockRoot: "0x9a2fefd2fdb57f74993c7780ea5b9030d2897b615b89f808011ca5aebed54eaf",
stateRoot: "0x600e852a08c1200654ddf11025f1ceacb3c2e74bdd5c630cde0838b2591b69f9",
},
[EventType.executionPayloadAvailable]: {
slot: 10,
Expand Down
8 changes: 3 additions & 5 deletions packages/beacon-node/src/api/impl/beacon/blocks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ export function getBeaconBlockApi({
}

try {
await verifyBlocksInEpoch.call(chain as BeaconChain, parentBlock, [blockForImport], {
await verifyBlocksInEpoch.call(chain as BeaconChain, parentBlock, [blockForImport], null, {
...opts,
verifyOnly: true,
skipVerifyBlockSignatures: true,
Expand Down Expand Up @@ -651,11 +651,11 @@ export function getBeaconBlockApi({
async publishExecutionPayloadEnvelope({signedExecutionPayloadEnvelope}) {
const seenTimestampSec = Date.now() / 1000;
const envelope = signedExecutionPayloadEnvelope.message;
const slot = envelope.slot;
const slot = envelope.payload.slotNumber;
const fork = config.getForkName(slot);
const blockRootHex = toRootHex(envelope.beaconBlockRoot);
const blockHashHex = toRootHex(envelope.payload.blockHash);
const stateRootHex = toRootHex(envelope.stateRoot);
// stateRoot removed from envelope in consensus-specs#5094

if (!isForkPostGloas(fork)) {
throw new ApiError(400, `publishExecutionPayloadEnvelope not supported for pre-gloas fork=${fork}`);
Expand Down Expand Up @@ -740,7 +740,6 @@ export function getBeaconBlockApi({
slot,
blockRoot: blockRootHex,
blockHash: blockHashHex,
stateRoot: stateRootHex,
builderIndex: envelope.builderIndex,
isSelfBuild,
dataColumns: dataColumnSidecars.length,
Expand Down Expand Up @@ -768,7 +767,6 @@ export function getBeaconBlockApi({
builderIndex: envelope.builderIndex,
blockHash: blockHashHex,
blockRoot: blockRootHex,
stateRoot: stateRootHex,
});

const sentPeersArr = await publishPromise;
Expand Down
2 changes: 1 addition & 1 deletion packages/beacon-node/src/api/impl/lodestar/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ export function getLodestarApi({
return {
// biome-ignore lint/complexity/useLiteralKeys: The `blockProcessor` is a protected attribute
data: (chain as BeaconChain)["blockProcessor"].jobQueue.getItems().map((item) => {
const [blockInputs, opts] = item.args;
const [blockInputs, _payloadEnvelopes, opts] = item.args;
return {
blockSlots: blockInputs.map((blockInput) => blockInput.slot),
jobOpts: opts,
Expand Down
4 changes: 0 additions & 4 deletions packages/beacon-node/src/api/impl/validator/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1648,10 +1648,6 @@ export function getValidatorApi(
executionRequests: executionRequests,
builderIndex: BUILDER_INDEX_SELF_BUILD,
beaconBlockRoot,
slot,
// TODO GLOAS: stateRoot is no longer computed during block production.
// This field will be removed when we implement defer payload processing
stateRoot: ZERO_HASH,
};

logger.info("Produced execution payload envelope", {
Expand Down
3 changes: 1 addition & 2 deletions packages/beacon-node/src/chain/GetBlobsTracker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export class GetBlobsTracker {
this.config = init.config;
}

triggerGetBlobs(input: IBlockInput | PayloadEnvelopeInput, onComplete?: () => void): void {
triggerGetBlobs(input: IBlockInput | PayloadEnvelopeInput): void {
if (this.activeReconstructions.has(input.blockRootHex)) {
return;
}
Expand Down Expand Up @@ -101,7 +101,6 @@ export class GetBlobsTracker {
.then((result) => {
this.logger.debug("getBlobsV2 result for block", {...logCtx, result});
this.metrics?.dataColumns.dataColumnEngineResult.inc({result});
onComplete?.();
})
.catch((error) => {
this.logger.debug("Error during getBlobsV2 for block", logCtx, error as Error);
Expand Down
26 changes: 9 additions & 17 deletions packages/beacon-node/src/chain/blocks/importBlock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,15 +128,17 @@ export async function importBlock(
blockDelaySec,
currentSlot,
fork >= ForkSeq.gloas ? ExecutionStatus.PayloadSeparated : executionStatus,
// TODO GLOAS: this is not useful post-gloas, may need to remove it?
dataAvailabilityStatus
);

// This adds the state necessary to process the next block
// Some block event handlers require state being in state cache so need to do this before emitting EventType.block
this.regen.processState(blockRootHex, postState);

// For Gloas blocks, create PayloadEnvelopeInput so it's available for later payload import
if (fork >= ForkSeq.gloas) {
// For range sync, PayloadEnvelope is created before reaching this
// we also don't need to trigger getBlobs() in that case
if (fork >= ForkSeq.gloas && !opts.fromRangeSync) {
const payloadInput = this.seenPayloadEnvelopeInputCache.add({
blockRootHex,
block: block as SignedBeaconBlock<ForkPostGloas>,
Expand All @@ -152,21 +154,11 @@ export async function importBlock(
...(opts.seenTimestampSec !== undefined ? {recvToImport: Date.now() / 1000 - opts.seenTimestampSec} : {}),
});

// Immediately attempt fetch of data columns from execution engine as the bid contains kzg commitments
// which is all the information we need so there is no reason to delay until execution payload arrives
// TODO GLOAS: If we want EL retries after this initial attempt, add an explicit retry policy here
// (for example later in the slot). Do not couple retries to incoming gossip columns.
this.getBlobsTracker.triggerGetBlobs(payloadInput, () => {
// TODO GLOAS: come up with a better mechanism to trigger processExecutionPayload after data becomes available,
// similar to how pre-gloas uses waitForBlockAndAllData with a cutoff timeout and incompleteBlockInput event
this.processExecutionPayload(payloadInput, {validSignature: true}).catch((e) => {
this.logger.debug(
"Error processing execution payload after getBlobs",
{slot: blockSlot, root: blockRootHex},
e as Error
);
});
});
// Gossip path: immediately attempt fetch of data columns from execution engine. The bid
// contains kzg commitments, which is all we need — no reason to delay until the execution
// payload arrives. Columns fetched here feed payloadInput.addColumn, which resolves
// waitForAllData for any in-flight importExecutionPayload.
this.getBlobsTracker.triggerGetBlobs(payloadInput);
}

this.metrics?.importBlock.bySource.inc({source: source.source});
Expand Down
Loading
Loading