Skip to content
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
import tech.pegasys.teku.spec.datastructures.blocks.blockbody.BeaconBlockBodyBuilder;
import tech.pegasys.teku.spec.datastructures.builder.BuilderBid;
import tech.pegasys.teku.spec.datastructures.builder.BuilderPayload;
import tech.pegasys.teku.spec.datastructures.builder.versions.gloas.BuilderConfig;
import tech.pegasys.teku.spec.datastructures.execution.BlobAndCellProofs;
import tech.pegasys.teku.spec.datastructures.execution.BlobsBundle;
import tech.pegasys.teku.spec.datastructures.execution.BuilderBidOrFallbackData;
Expand Down Expand Up @@ -389,7 +390,7 @@ private SafeFuture<Void> setExecutionData(
executionPayloadContext.orElseThrow(),
blockSlotState,
shouldTryBuilderFlow,
blockProductionContext.requestedBuilderBoostFactor(),
blockProductionContext.builderConfig().map(BuilderConfig::getBuilderBoostFactor),
blockProductionContext.blockProductionPerformance());

return SafeFuture.allOf(
Expand Down Expand Up @@ -556,7 +557,7 @@ private SafeFuture<Void> setExecutionPayloadBid(
blockProductionContext.parentExecutionBlockHash(),
blockSlotState,
executionPayloadResult.getPayloadResponseFutureFromLocalFlowRequired(),
blockProductionContext.requestedBuilderBoostFactor(),
blockProductionContext.builderConfig().map(BuilderConfig::getBuilderBoostFactor),
blockProductionContext.blockProductionPerformance())
.thenAccept(bodyBuilder::signedExecutionPayloadBid);
return SafeFuture.allOf(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import tech.pegasys.teku.ethereum.performance.trackers.BlockProductionPerformance;
import tech.pegasys.teku.infrastructure.unsigned.UInt64;
import tech.pegasys.teku.spec.Spec;
import tech.pegasys.teku.spec.datastructures.builder.versions.gloas.BuilderConfig;
import tech.pegasys.teku.spec.datastructures.forkchoice.ForkChoiceNode;
import tech.pegasys.teku.spec.datastructures.forkchoice.ForkChoicePayloadStatus;
import tech.pegasys.teku.spec.datastructures.state.beaconstate.BeaconState;
Expand All @@ -33,7 +34,7 @@ public record BlockProductionContext(
Bytes32 parentExecutionBlockHash,
BLSSignature randaoReveal,
Optional<Bytes32> graffiti,
Optional<UInt64> requestedBuilderBoostFactor,
Optional<BuilderConfig> builderConfig,
BlockProductionPerformance blockProductionPerformance) {

public static BlockProductionContext create(
Expand All @@ -43,7 +44,7 @@ public static BlockProductionContext create(
final ChainHead parentChainHead,
final BLSSignature randaoReveal,
final Optional<Bytes32> graffiti,
final Optional<UInt64> requestedBuilderBoostFactor,
final Optional<BuilderConfig> builderConfig,
final BlockProductionPerformance blockProductionPerformance) {
checkArgument(
blockSlotState.getSlot().equals(proposalSlot),
Expand All @@ -63,7 +64,7 @@ public static BlockProductionContext create(
parentChainHead.getExecutionBlockHash(),
randaoReveal,
graffiti,
requestedBuilderBoostFactor,
builderConfig,
blockProductionPerformance);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@
import tech.pegasys.teku.spec.datastructures.blocks.SignedBlockAndState;
import tech.pegasys.teku.spec.datastructures.blocks.SignedBlockContainer;
import tech.pegasys.teku.spec.datastructures.builder.SignedValidatorRegistration;
import tech.pegasys.teku.spec.datastructures.builder.versions.gloas.BuilderConfig;
import tech.pegasys.teku.spec.datastructures.epbs.versions.gloas.ExecutionPayloadBid;
import tech.pegasys.teku.spec.datastructures.epbs.versions.gloas.ExecutionPayloadEnvelope;
import tech.pegasys.teku.spec.datastructures.epbs.versions.gloas.PayloadAttestationData;
Expand Down Expand Up @@ -446,13 +447,11 @@ public SafeFuture<Optional<BlockContainerAndMetaData>> createUnsignedBlock(
final UInt64 slot,
final BLSSignature randaoReveal,
final Optional<Bytes32> graffiti,
final Optional<UInt64> requestedBuilderBoostFactor) {
final boolean includePayload,
final Optional<BuilderConfig> builderConfig) {
return blockProductionBySlotCache
.computeIfAbsent(
slot,
__ ->
createUnsignedBlockInternal(
slot, randaoReveal, graffiti, requestedBuilderBoostFactor))
slot, __ -> createUnsignedBlockInternal(slot, randaoReveal, graffiti, builderConfig))
.whenException(
__ -> {
// allow further block production attempts for this slot
Expand Down Expand Up @@ -493,7 +492,7 @@ private SafeFuture<Optional<BlockContainerAndMetaData>> createUnsignedBlockInter
final UInt64 slot,
final BLSSignature randaoReveal,
final Optional<Bytes32> graffiti,
final Optional<UInt64> requestedBuilderBoostFactor) {
final Optional<BuilderConfig> builderConfig) {
LOG.info("Creating unsigned block for slot {}", slot);
performanceTracker.reportBlockProductionAttempt(spec.computeEpochAtSlot(slot));
if (isSyncActive()) {
Expand All @@ -506,7 +505,7 @@ private SafeFuture<Optional<BlockContainerAndMetaData>> createUnsignedBlockInter
blockProductionPreparationContext.blockProductionPerformance.validatorBlockRequested();

return blockProductionPreparationContext
.toBlockProductionContext(spec, slot, randaoReveal, graffiti, requestedBuilderBoostFactor)
.toBlockProductionContext(spec, slot, randaoReveal, graffiti, builderConfig)
.thenCompose(this::createBlock)
.thenPeek(
maybeBlock ->
Expand Down Expand Up @@ -1235,7 +1234,7 @@ SafeFuture<BlockProductionContext> toBlockProductionContext(
final UInt64 proposalSlot,
final BLSSignature randaoReveal,
final Optional<Bytes32> graffiti,
final Optional<UInt64> requestedBuilderBoostFactor) {
final Optional<BuilderConfig> builderConfig) {
return stateFuture.thenCombine(
chainHeadFuture,
(state, chainHead) ->
Expand All @@ -1246,7 +1245,7 @@ SafeFuture<BlockProductionContext> toBlockProductionContext(
chainHead,
randaoReveal,
graffiti,
requestedBuilderBoostFactor,
builderConfig,
blockProductionPerformance));
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,14 @@
import tech.pegasys.teku.spec.TestSpecInvocationContextProvider;
import tech.pegasys.teku.spec.datastructures.blocks.SignedBlockAndState;
import tech.pegasys.teku.spec.datastructures.blocks.StateAndBlockSummary;
import tech.pegasys.teku.spec.datastructures.builder.versions.gloas.BuilderConfig;
import tech.pegasys.teku.spec.datastructures.forkchoice.ForkChoiceNode;
import tech.pegasys.teku.spec.datastructures.forkchoice.ForkChoicePayloadStatus;
import tech.pegasys.teku.spec.datastructures.forkchoice.ProtoNodeData;
import tech.pegasys.teku.spec.datastructures.forkchoice.ProtoNodeValidationStatus;
import tech.pegasys.teku.spec.datastructures.state.beaconstate.BeaconState;
import tech.pegasys.teku.spec.generator.ChainBuilder;
import tech.pegasys.teku.spec.schemas.ApiSchemas;
import tech.pegasys.teku.spec.util.DataStructureUtil;
import tech.pegasys.teku.storage.client.ChainHead;

Expand All @@ -60,11 +62,11 @@ void create_shouldDeriveParentRootFromStateAndPreservePayloadStatus() throws Exc
final UInt64 proposalSlot = parentBlock.getSlot().plus(1);
final BeaconState blockSlotState = spec.processSlots(parentBlock.getState(), proposalSlot);
final ChainHead parentChainHead = chainHead(parentBlock, PAYLOAD_STATUS_FULL);
final Optional<UInt64> requestedBuilderBoostFactor = Optional.of(UInt64.valueOf(42));
final Optional<BuilderConfig> builderConfig =
Optional.of(ApiSchemas.BUILDER_CONFIG_SCHEMA.create(UInt64.valueOf(42)));

final BlockProductionContext context =
createBlockProductionContext(
proposalSlot, blockSlotState, parentChainHead, requestedBuilderBoostFactor);
createBlockProductionContext(proposalSlot, blockSlotState, parentChainHead, builderConfig);

assertThat(context.proposalSlot()).isEqualTo(proposalSlot);
assertThat(context.blockSlotState()).isSameAs(blockSlotState);
Expand All @@ -76,7 +78,7 @@ void create_shouldDeriveParentRootFromStateAndPreservePayloadStatus() throws Exc
assertThat(context.parentPayloadStatus()).isEqualTo(PAYLOAD_STATUS_FULL);
assertThat(context.parentExecutionBlockHash())
.isEqualTo(parentChainHead.getExecutionBlockHash());
assertThat(context.requestedBuilderBoostFactor()).isEqualTo(requestedBuilderBoostFactor);
assertThat(context.builderConfig()).isEqualTo(builderConfig);
assertThat(context.blockProductionPerformance()).isSameAs(BlockProductionPerformance.NOOP);
}

Expand Down Expand Up @@ -130,7 +132,7 @@ private BlockProductionContext createBlockProductionContext(
final UInt64 proposalSlot,
final BeaconState blockSlotState,
final ChainHead parentChainHead,
final Optional<UInt64> requestedBuilderBoostFactor) {
final Optional<BuilderConfig> builderConfig) {
final BLSSignature randaoReveal = dataStructureUtil.randomSignature();
final Optional<Bytes32> graffiti = Optional.of(dataStructureUtil.randomBytes32());
return BlockProductionContext.create(
Expand All @@ -140,7 +142,7 @@ private BlockProductionContext createBlockProductionContext(
parentChainHead,
randaoReveal,
graffiti,
requestedBuilderBoostFactor,
builderConfig,
BlockProductionPerformance.NOOP);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import tech.pegasys.teku.spec.datastructures.forkchoice.ForkChoiceNode;
import tech.pegasys.teku.spec.datastructures.state.beaconstate.BeaconState;
import tech.pegasys.teku.spec.datastructures.state.beaconstate.versions.gloas.BeaconStateGloas;
import tech.pegasys.teku.spec.schemas.ApiSchemas;

final class BlockProductionTestUtil {

Expand Down Expand Up @@ -59,7 +60,7 @@ static BlockProductionContext blockProductionContext(
parentExecutionBlockHash(blockSlotState),
randaoReveal,
graffiti,
requestedBuilderBoostFactor,
requestedBuilderBoostFactor.map(ApiSchemas.BUILDER_CONFIG_SCHEMA::create),
blockProductionPerformance);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
* Copyright Consensys Software Inc., 2026
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*/

package tech.pegasys.teku.spec.datastructures.builder.versions.gloas;

import java.util.List;
import tech.pegasys.teku.infrastructure.ssz.SszList;
import tech.pegasys.teku.infrastructure.ssz.containers.Container3;
import tech.pegasys.teku.infrastructure.ssz.primitive.SszUInt64;
import tech.pegasys.teku.infrastructure.ssz.tree.TreeNode;
import tech.pegasys.teku.infrastructure.unsigned.UInt64;

public class BuilderConfig
extends Container3<BuilderConfig, SszUInt64, SszUInt64, SszList<BuilderEntry>> {

protected BuilderConfig(
final BuilderConfigSchema schema,
final UInt64 minBid,
final UInt64 builderBoostFactor,
final List<BuilderEntry> builders) {
super(
schema,
SszUInt64.of(minBid),
SszUInt64.of(builderBoostFactor),
schema.getBuildersSchema().createFromElements(builders));
}

protected BuilderConfig(final BuilderConfigSchema schema, final TreeNode backingNode) {
super(schema, backingNode);
}

public UInt64 getMinBid() {
return getField0().get();
}

public UInt64 getBuilderBoostFactor() {
return getField1().get();
}

public SszList<BuilderEntry> getBuilders() {
return getField2();
}

@Override
public BuilderConfigSchema getSchema() {
return (BuilderConfigSchema) super.getSchema();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
* Copyright Consensys Software Inc., 2026
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*/

package tech.pegasys.teku.spec.datastructures.builder.versions.gloas;

import java.util.List;
import tech.pegasys.teku.infrastructure.ssz.SszList;
import tech.pegasys.teku.infrastructure.ssz.containers.ContainerSchema3;
import tech.pegasys.teku.infrastructure.ssz.primitive.SszUInt64;
import tech.pegasys.teku.infrastructure.ssz.schema.SszListSchema;
import tech.pegasys.teku.infrastructure.ssz.schema.SszPrimitiveSchemas;
import tech.pegasys.teku.infrastructure.ssz.tree.TreeNode;
import tech.pegasys.teku.infrastructure.unsigned.UInt64;

public class BuilderConfigSchema
extends ContainerSchema3<BuilderConfig, SszUInt64, SszUInt64, SszList<BuilderEntry>> {

private static final long MAX_BUILDER_ENTRIES = 64;

public BuilderConfigSchema(final BuilderEntrySchema builderEntrySchema) {
super(
"BuilderConfig",
namedSchema("min_bid", SszPrimitiveSchemas.UINT64_SCHEMA),
namedSchema("builder_boost_factor", SszPrimitiveSchemas.UINT64_SCHEMA),
namedSchema("builders", SszListSchema.create(builderEntrySchema, MAX_BUILDER_ENTRIES)));
}

public BuilderConfig create(
final UInt64 minBid, final UInt64 builderBoostFactor, final List<BuilderEntry> builders) {
return new BuilderConfig(this, minBid, builderBoostFactor, builders);
}

public BuilderConfig create(final UInt64 builderBoostFactor) {
return new BuilderConfig(this, UInt64.ZERO, builderBoostFactor, List.of());
}

@Override
public BuilderConfig createFromBackingNode(final TreeNode node) {
return new BuilderConfig(this, node);
}

@SuppressWarnings("unchecked")
public SszListSchema<BuilderEntry, ?> getBuildersSchema() {
return (SszListSchema<BuilderEntry, ?>) getChildSchema(getFieldIndex("builders"));
}
}
Loading
Loading