Skip to content

Commit

Permalink
Fix throw when ExecutionPayloadContext is empty and move it to the top (
Browse files Browse the repository at this point in the history
  • Loading branch information
zilm13 authored Feb 24, 2024
1 parent 7585440 commit a4b5f3e
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 48 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,13 @@ private SafeFuture<Void> setExecutionData(
final BeaconState blockSlotState,
final BlockProductionPerformance blockProductionPerformance) {

if (spec.isMergeTransitionComplete(blockSlotState) && executionPayloadContext.isEmpty()) {
throw new IllegalStateException(
String.format(
"ExecutionPayloadContext is not provided for production of post-merge block at slot %s",
blockSlotState.getSlot()));
}

// if requestedBlinded has been specified, we strictly follow it otherwise, we should run
// Builder
// flow (blinded) only if we have a validator registration
Expand Down Expand Up @@ -246,10 +253,7 @@ private SafeFuture<Void> setExecutionData(
// Post-Deneb: Execution Payload / Execution Payload Header + KZG Commitments
final ExecutionPayloadResult executionPayloadResult =
executionLayerBlockProductionManager.initiateBlockAndBlobsProduction(
// kzg commitments are supported: we should have already merged by now, so we
// can safely assume we have an executionPayloadContext
executionPayloadContext.orElseThrow(
() -> new IllegalStateException("Cannot provide kzg commitments before The Merge")),
executionPayloadContext.orElseThrow(),
blockSlotState,
shouldTryBuilderFlow,
requestedBuilderBoostFactor,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static tech.pegasys.teku.infrastructure.async.SafeFutureAssert.assertThatSafeFuture;
import static tech.pegasys.teku.infrastructure.async.SafeFutureAssert.safeJoin;
import static tech.pegasys.teku.statetransition.validation.InternalValidationResult.ACCEPT;

Expand Down Expand Up @@ -91,6 +92,7 @@

class BlockOperationSelectorFactoryTest {
private final Spec spec = TestSpecFactory.createMinimalDeneb();
private final Spec specBellatrix = TestSpecFactory.createMinimalBellatrix();
private final DataStructureUtil dataStructureUtil = new DataStructureUtil(spec);

private final Function<UInt64, BeaconBlockBodySchema<?>> beaconBlockSchemaSupplier =
Expand Down Expand Up @@ -161,12 +163,12 @@ class BlockOperationSelectorFactoryTest {
mock(ExecutionLayerBlockProductionManager.class);

private final ExecutionPayload defaultExecutionPayload =
SchemaDefinitionsBellatrix.required(spec.getGenesisSpec().getSchemaDefinitions())
SchemaDefinitionsBellatrix.required(specBellatrix.getGenesisSpec().getSchemaDefinitions())
.getExecutionPayloadSchema()
.getDefault();

private final ExecutionPayloadHeader executionPayloadHeaderOfDefaultPayload =
SchemaDefinitionsBellatrix.required(spec.getGenesisSpec().getSchemaDefinitions())
SchemaDefinitionsBellatrix.required(specBellatrix.getGenesisSpec().getSchemaDefinitions())
.getExecutionPayloadHeaderSchema()
.getHeaderOfDefaultPayload();

Expand All @@ -187,6 +189,21 @@ class BlockOperationSelectorFactoryTest {
defaultGraffiti,
forkChoiceNotifier,
executionLayer);
private final BlockOperationSelectorFactory factoryBellatrix =
new BlockOperationSelectorFactory(
specBellatrix,
attestationPool,
attesterSlashingPool,
proposerSlashingPool,
voluntaryExitPool,
blsToExecutionChangePool,
contributionPool,
depositProvider,
eth1DataCache,
defaultGraffiti,
forkChoiceNotifier,
executionLayer);
private ExecutionPayloadContext executionPayloadContext;

@BeforeEach
void setUp() {
Expand All @@ -202,14 +219,24 @@ void setUp() {
.thenReturn(SafeFuture.completedFuture(ACCEPT));
when(blsToExecutionChangeValidator.validateForGossip(any()))
.thenReturn(SafeFuture.completedFuture(ACCEPT));
this.executionPayloadContext = dataStructureUtil.randomPayloadExecutionContext(false);
when(forkChoiceNotifier.getPayloadId(any(), any()))
.thenReturn(SafeFuture.completedFuture(Optional.empty()));
.thenReturn(SafeFuture.completedFuture(Optional.of(executionPayloadContext)));
}

@Test
void shouldNotSelectOperationsWhenNoneAreAvailable() {
final UInt64 slot = UInt64.ONE;
final BeaconState blockSlotState = dataStructureUtil.randomBeaconState(slot);
final ExecutionPayload randomExecutionPayload = dataStructureUtil.randomExecutionPayload();
final UInt256 blockExecutionValue = dataStructureUtil.randomUInt256();

prepareBlockProductionWithPayload(
randomExecutionPayload,
executionPayloadContext,
blockSlotState,
Optional.of(blockExecutionValue));

safeJoin(
factory
.createSelector(
Expand Down Expand Up @@ -248,6 +275,15 @@ void shouldIncludeValidOperations() {
assertThat(contributionPool.addLocal(contribution)).isCompletedWithValue(ACCEPT);
addToPool(blsToExecutionChangePool, blsToExecutionChange);

final ExecutionPayload randomExecutionPayload = dataStructureUtil.randomExecutionPayload();
final UInt256 blockExecutionValue = dataStructureUtil.randomUInt256();

prepareBlockProductionWithPayload(
randomExecutionPayload,
executionPayloadContext,
blockSlotState,
Optional.of(blockExecutionValue));

safeJoin(
factory
.createSelector(
Expand Down Expand Up @@ -328,6 +364,14 @@ void shouldNotIncludeInvalidOperations() {
blockSlotState, blsToExecutionChange2))
.thenReturn(Optional.of(BlsToExecutionChangeInvalidReason.invalidValidatorIndex()));

final ExecutionPayload randomExecutionPayload = dataStructureUtil.randomExecutionPayload();
final UInt256 blockExecutionValue = dataStructureUtil.randomUInt256();
prepareBlockProductionWithPayload(
randomExecutionPayload,
executionPayloadContext,
blockSlotState,
Optional.of(blockExecutionValue));

safeJoin(
factory
.createSelector(
Expand Down Expand Up @@ -357,8 +401,11 @@ void shouldNotIncludeInvalidOperations() {
void shouldIncludeDefaultExecutionPayload() {
final UInt64 slot = UInt64.ONE;
final BeaconState blockSlotState = dataStructureUtil.randomBeaconStatePreMerge(slot);
when(forkChoiceNotifier.getPayloadId(any(), any()))
.thenReturn(SafeFuture.completedFuture(Optional.empty()));

safeJoin(
factory
factoryBellatrix
.createSelector(
parentRoot,
blockSlotState,
Expand All @@ -375,8 +422,11 @@ void shouldIncludeDefaultExecutionPayload() {
void shouldIncludeExecutionPayloadHeaderOfDefaultPayload() {
final UInt64 slot = UInt64.ONE;
final BeaconState blockSlotState = dataStructureUtil.randomBeaconStatePreMerge(slot);
when(forkChoiceNotifier.getPayloadId(any(), any()))
.thenReturn(SafeFuture.completedFuture(Optional.empty()));

safeJoin(
factory
factoryBellatrix
.createSelector(
parentRoot,
blockSlotState,
Expand All @@ -394,14 +444,9 @@ void shouldIncludeExecutionPayloadHeaderOfDefaultPayload() {
void shouldIncludeNonDefaultExecutionPayload() {
final UInt64 slot = UInt64.ONE;
final BeaconState blockSlotState = dataStructureUtil.randomBeaconState(slot);

final ExecutionPayloadContext executionPayloadContext =
dataStructureUtil.randomPayloadExecutionContext(false);
final ExecutionPayload randomExecutionPayload = dataStructureUtil.randomExecutionPayload();
final UInt256 blockExecutionValue = dataStructureUtil.randomUInt256();

when(forkChoiceNotifier.getPayloadId(any(), any()))
.thenReturn(SafeFuture.completedFuture(Optional.of(executionPayloadContext)));
prepareBlockProductionWithPayload(
randomExecutionPayload,
executionPayloadContext,
Expand Down Expand Up @@ -430,16 +475,10 @@ void shouldIncludeNonDefaultExecutionPayload() {
void shouldIncludeExecutionPayloadHeaderIfBlindedBlockRequested() {
final UInt64 slot = UInt64.ONE;
final BeaconState blockSlotState = dataStructureUtil.randomBeaconState(slot);

final ExecutionPayloadContext executionPayloadContext =
dataStructureUtil.randomPayloadExecutionContext(false);
final ExecutionPayloadHeader randomExecutionPayloadHeader =
dataStructureUtil.randomExecutionPayloadHeader();

final UInt256 blockExecutionValue = dataStructureUtil.randomUInt256();

when(forkChoiceNotifier.getPayloadId(any(), any()))
.thenReturn(SafeFuture.completedFuture(Optional.of(executionPayloadContext)));
prepareBlockProductionWithPayloadHeader(
randomExecutionPayloadHeader,
executionPayloadContext,
Expand Down Expand Up @@ -468,15 +507,9 @@ void shouldIncludeExecutionPayloadHeaderIfBlindedBlockRequested() {
void shouldIncludeExecutionPayloadIfUnblindedBlockRequested() {
final UInt64 slot = UInt64.ONE;
final BeaconState blockSlotState = dataStructureUtil.randomBeaconState(slot);

final ExecutionPayloadContext executionPayloadContext =
dataStructureUtil.randomPayloadExecutionContext(false);
final ExecutionPayload randomExecutionPayload = dataStructureUtil.randomExecutionPayload();

final UInt256 blockExecutionValue = dataStructureUtil.randomUInt256();

when(forkChoiceNotifier.getPayloadId(any(), any()))
.thenReturn(SafeFuture.completedFuture(Optional.of(executionPayloadContext)));
prepareBlockProductionWithPayload(
randomExecutionPayload,
executionPayloadContext,
Expand Down Expand Up @@ -505,15 +538,9 @@ void shouldIncludeExecutionPayloadIfUnblindedBlockRequested() {
void shouldIncludeExecutionPayloadIfRequestedBlindedIsEmpty() {
final UInt64 slot = UInt64.ONE;
final BeaconState blockSlotState = dataStructureUtil.randomBeaconState(slot);

final ExecutionPayloadContext executionPayloadContext =
dataStructureUtil.randomPayloadExecutionContext(false, false);
final ExecutionPayload randomExecutionPayload = dataStructureUtil.randomExecutionPayload();

final UInt256 blockExecutionValue = dataStructureUtil.randomUInt256();

when(forkChoiceNotifier.getPayloadId(any(), any()))
.thenReturn(SafeFuture.completedFuture(Optional.of(executionPayloadContext)));
prepareBlockProductionWithPayload(
randomExecutionPayload,
executionPayloadContext,
Expand Down Expand Up @@ -543,14 +570,12 @@ void shouldIncludeExecutionPayloadIfRequestedBlindedIsEmptyAndBuilderFlowFallsBa
final UInt64 slot = UInt64.ONE;
final BeaconState blockSlotState = dataStructureUtil.randomBeaconState(slot);

final ExecutionPayloadContext executionPayloadContext =
dataStructureUtil.randomPayloadExecutionContext(false, true);
final ExecutionPayload randomExecutionPayload = dataStructureUtil.randomExecutionPayload();

final UInt256 blockExecutionValue = dataStructureUtil.randomUInt256();

this.executionPayloadContext = dataStructureUtil.randomPayloadExecutionContext(false, true);
when(forkChoiceNotifier.getPayloadId(any(), any()))
.thenReturn(SafeFuture.completedFuture(Optional.of(executionPayloadContext)));

final ExecutionPayload randomExecutionPayload = dataStructureUtil.randomExecutionPayload();
final UInt256 blockExecutionValue = dataStructureUtil.randomUInt256();
prepareBlindedBlockProductionWithFallBack(
randomExecutionPayload,
executionPayloadContext,
Expand Down Expand Up @@ -639,15 +664,10 @@ void shouldUnblindSignedBlindedBeaconBlock() {
void shouldIncludeKzgCommitmentsInBlock() {
final BeaconState blockSlotState = dataStructureUtil.randomBeaconState();

final ExecutionPayloadContext executionPayloadContext =
dataStructureUtil.randomPayloadExecutionContext(false);
final ExecutionPayload randomExecutionPayload = dataStructureUtil.randomExecutionPayload();

final UInt256 blockExecutionValue = dataStructureUtil.randomUInt256();

when(forkChoiceNotifier.getPayloadId(any(), any()))
.thenReturn(SafeFuture.completedFuture(Optional.of(executionPayloadContext)));

final BlobsBundle blobsBundle = dataStructureUtil.randomBlobsBundle();

prepareBlockAndBlobsProduction(
Expand Down Expand Up @@ -683,16 +703,11 @@ void shouldIncludeKzgCommitmentsInBlock() {
void shouldIncludeKzgCommitmentsInBlindedBlock() {
final BeaconState blockSlotState = dataStructureUtil.randomBeaconState();

final ExecutionPayloadContext executionPayloadContext =
dataStructureUtil.randomPayloadExecutionContext(false);
final ExecutionPayloadHeader randomExecutionPayloadHeader =
dataStructureUtil.randomExecutionPayloadHeader();

final UInt256 blockExecutionValue = dataStructureUtil.randomUInt256();

when(forkChoiceNotifier.getPayloadId(any(), any()))
.thenReturn(SafeFuture.completedFuture(Optional.of(executionPayloadContext)));

final SszList<SszKZGCommitment> blobKzgCommitments =
dataStructureUtil.randomBlobKzgCommitments();

Expand Down Expand Up @@ -866,6 +881,29 @@ void shouldCreateBlobSidecarsForBlindedBlock() {
});
}

@Test
void shouldThrowWhenExecutionPayloadContextNotProvided() {
final UInt64 slot = UInt64.ONE;
final BeaconState blockSlotState = dataStructureUtil.randomBeaconState(slot);
when(forkChoiceNotifier.getPayloadId(any(), any()))
.thenReturn(SafeFuture.completedFuture(Optional.empty()));

assertThatSafeFuture(
factory
.createSelector(
parentRoot,
blockSlotState,
dataStructureUtil.randomSignature(),
Optional.empty(),
Optional.of(false),
Optional.empty(),
BlockProductionPerformance.NOOP)
.apply(bodyBuilder))
.isCompletedExceptionallyWith(IllegalStateException.class)
.hasMessage(
"ExecutionPayloadContext is not provided for production of post-merge block at slot 1");
}

private void prepareBlockProductionWithPayload(
final ExecutionPayload executionPayload,
final ExecutionPayloadContext executionPayloadContext,
Expand Down

0 comments on commit a4b5f3e

Please sign in to comment.