From 5f9cc0de631a16fe4479b03a7a094d8ebb235652 Mon Sep 17 00:00:00 2001 From: Mehdi AOUADI Date: Fri, 4 Oct 2024 16:13:00 +0200 Subject: [PATCH] add rpc method return type checks in unit tests --- .../BellatrixExecutionClientHandlerTest.java | 45 +++++---- .../CapellaExecutionClientHandlerTest.java | 67 ++++++++------ .../DenebExecutionClientHandlerTest.java | 92 +++++++++++-------- .../ElectraExecutionClientHandlerTest.java | 90 ++++++++++-------- 4 files changed, 167 insertions(+), 127 deletions(-) diff --git a/ethereum/executionlayer/src/test/java/tech/pegasys/teku/ethereum/executionlayer/BellatrixExecutionClientHandlerTest.java b/ethereum/executionlayer/src/test/java/tech/pegasys/teku/ethereum/executionlayer/BellatrixExecutionClientHandlerTest.java index 8685323e91f..b97c46c29d5 100644 --- a/ethereum/executionlayer/src/test/java/tech/pegasys/teku/ethereum/executionlayer/BellatrixExecutionClientHandlerTest.java +++ b/ethereum/executionlayer/src/test/java/tech/pegasys/teku/ethereum/executionlayer/BellatrixExecutionClientHandlerTest.java @@ -13,6 +13,7 @@ package tech.pegasys.teku.ethereum.executionlayer; +import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -30,10 +31,12 @@ import tech.pegasys.teku.spec.TestSpecFactory; import tech.pegasys.teku.spec.datastructures.execution.ExecutionPayload; import tech.pegasys.teku.spec.datastructures.execution.ExecutionPayloadContext; +import tech.pegasys.teku.spec.datastructures.execution.GetPayloadResponse; import tech.pegasys.teku.spec.datastructures.execution.NewPayloadRequest; import tech.pegasys.teku.spec.executionlayer.ExecutionPayloadStatus; import tech.pegasys.teku.spec.executionlayer.ForkChoiceState; import tech.pegasys.teku.spec.executionlayer.PayloadBuildingAttributes; +import tech.pegasys.teku.spec.executionlayer.PayloadStatus; import tech.pegasys.teku.spec.util.DataStructureUtil; class BellatrixExecutionClientHandlerTest extends ExecutionHandlerClientTest { @@ -43,7 +46,6 @@ void setup() { dataStructureUtil = new DataStructureUtil(spec); } - @SuppressWarnings("FutureReturnValueIgnored") @Test void engineGetPayload_shouldCallGetPayloadV1() { final ExecutionClientHandler handler = getHandler(); @@ -54,35 +56,36 @@ void engineGetPayload_shouldCallGetPayloadV1() { dataStructureUtil.randomForkChoiceState(false), dataStructureUtil.randomPayloadBuildingAttributes(false)); + final ExecutionPayload executionPayload = dataStructureUtil.randomExecutionPayload(); + final ExecutionPayloadV1 responseData = + ExecutionPayloadV1.fromInternalExecutionPayload(executionPayload); final SafeFuture> dummyResponse = - SafeFuture.completedFuture( - new Response<>( - ExecutionPayloadV1.fromInternalExecutionPayload( - dataStructureUtil.randomExecutionPayload()))); + SafeFuture.completedFuture(new Response<>(responseData)); when(executionEngineClient.getPayloadV1(context.getPayloadId())).thenReturn(dummyResponse); - handler.engineGetPayload(context, slot); + final SafeFuture future = handler.engineGetPayload(context, slot); verify(executionEngineClient).getPayloadV1(context.getPayloadId()); + assertThat(future).isCompletedWithValue(new GetPayloadResponse(executionPayload)); } - @SuppressWarnings("FutureReturnValueIgnored") @Test void engineNewPayload_shouldCallNewPayloadV1() { final ExecutionClientHandler handler = getHandler(); final ExecutionPayload payload = dataStructureUtil.randomExecutionPayload(); final NewPayloadRequest newPayloadRequest = new NewPayloadRequest(payload); final ExecutionPayloadV1 payloadV1 = ExecutionPayloadV1.fromInternalExecutionPayload(payload); + final PayloadStatusV1 responseData = + new PayloadStatusV1( + ExecutionPayloadStatus.ACCEPTED, dataStructureUtil.randomBytes32(), null); final SafeFuture> dummyResponse = - SafeFuture.completedFuture( - new Response<>( - new PayloadStatusV1( - ExecutionPayloadStatus.ACCEPTED, dataStructureUtil.randomBytes32(), null))); + SafeFuture.completedFuture(new Response<>(responseData)); when(executionEngineClient.newPayloadV1(payloadV1)).thenReturn(dummyResponse); - handler.engineNewPayload(newPayloadRequest, UInt64.ZERO); + final SafeFuture future = + handler.engineNewPayload(newPayloadRequest, UInt64.ZERO); verify(executionEngineClient).newPayloadV1(payloadV1); + assertThat(future).isCompletedWithValue(responseData.asInternalExecutionPayload()); } - @SuppressWarnings("FutureReturnValueIgnored") @Test void engineForkChoiceUpdated_shouldCallEngineForkChoiceUpdatedV1() { final ExecutionClientHandler handler = getHandler(); @@ -101,16 +104,18 @@ void engineForkChoiceUpdated_shouldCallEngineForkChoiceUpdatedV1() { dataStructureUtil.randomBytes32()); final Optional payloadAttributes = PayloadAttributesV1.fromInternalPayloadBuildingAttributes(Optional.of(attributes)); + final ForkChoiceUpdatedResult responseData = + new ForkChoiceUpdatedResult( + new PayloadStatusV1( + ExecutionPayloadStatus.ACCEPTED, dataStructureUtil.randomBytes32(), ""), + dataStructureUtil.randomBytes8()); final SafeFuture> dummyResponse = - SafeFuture.completedFuture( - new Response<>( - new ForkChoiceUpdatedResult( - new PayloadStatusV1( - ExecutionPayloadStatus.ACCEPTED, dataStructureUtil.randomBytes32(), ""), - dataStructureUtil.randomBytes8()))); + SafeFuture.completedFuture(new Response<>(responseData)); when(executionEngineClient.forkChoiceUpdatedV1(forkChoiceStateV1, payloadAttributes)) .thenReturn(dummyResponse); - handler.engineForkChoiceUpdated(forkChoiceState, Optional.of(attributes)); + final SafeFuture future = + handler.engineForkChoiceUpdated(forkChoiceState, Optional.of(attributes)); verify(executionEngineClient).forkChoiceUpdatedV1(forkChoiceStateV1, payloadAttributes); + assertThat(future).isCompletedWithValue(responseData.asInternalExecutionPayload()); } } diff --git a/ethereum/executionlayer/src/test/java/tech/pegasys/teku/ethereum/executionlayer/CapellaExecutionClientHandlerTest.java b/ethereum/executionlayer/src/test/java/tech/pegasys/teku/ethereum/executionlayer/CapellaExecutionClientHandlerTest.java index 7ff06867007..82605955280 100644 --- a/ethereum/executionlayer/src/test/java/tech/pegasys/teku/ethereum/executionlayer/CapellaExecutionClientHandlerTest.java +++ b/ethereum/executionlayer/src/test/java/tech/pegasys/teku/ethereum/executionlayer/CapellaExecutionClientHandlerTest.java @@ -19,7 +19,6 @@ import java.util.List; import java.util.Optional; -import java.util.concurrent.ExecutionException; import org.apache.tuweni.units.bigints.UInt256; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -35,13 +34,14 @@ import tech.pegasys.teku.spec.TestSpecFactory; import tech.pegasys.teku.spec.datastructures.execution.ExecutionPayload; import tech.pegasys.teku.spec.datastructures.execution.ExecutionPayloadContext; +import tech.pegasys.teku.spec.datastructures.execution.ExecutionPayloadSchema; import tech.pegasys.teku.spec.datastructures.execution.GetPayloadResponse; import tech.pegasys.teku.spec.datastructures.execution.NewPayloadRequest; -import tech.pegasys.teku.spec.datastructures.execution.versions.capella.ExecutionPayloadCapella; import tech.pegasys.teku.spec.executionlayer.ExecutionPayloadStatus; import tech.pegasys.teku.spec.executionlayer.ForkChoiceState; import tech.pegasys.teku.spec.executionlayer.PayloadBuildingAttributes; import tech.pegasys.teku.spec.executionlayer.PayloadStatus; +import tech.pegasys.teku.spec.schemas.SchemaDefinitionsCapella; import tech.pegasys.teku.spec.util.DataStructureUtil; public class CapellaExecutionClientHandlerTest extends ExecutionHandlerClientTest { @@ -53,7 +53,7 @@ void setup() { } @Test - void engineGetPayload_shouldCallGetPayloadV2() throws ExecutionException, InterruptedException { + void engineGetPayload_shouldCallGetPayloadV2() { final ExecutionClientHandler handler = getHandler(); final UInt64 slot = dataStructureUtil.randomUInt64(1_000_000); final ExecutionPayloadContext context = @@ -62,19 +62,26 @@ void engineGetPayload_shouldCallGetPayloadV2() throws ExecutionException, Interr dataStructureUtil.randomForkChoiceState(false), dataStructureUtil.randomPayloadBuildingAttributes(false)); + final GetPayloadV2Response responseData = + new GetPayloadV2Response( + ExecutionPayloadV2.fromInternalExecutionPayload( + dataStructureUtil.randomExecutionPayload()), + UInt256.MAX_VALUE); final SafeFuture> dummyResponse = - SafeFuture.completedFuture( - new Response<>( - new GetPayloadV2Response( - ExecutionPayloadV2.fromInternalExecutionPayload( - dataStructureUtil.randomExecutionPayload()), - UInt256.MAX_VALUE))); + SafeFuture.completedFuture(new Response<>(responseData)); when(executionEngineClient.getPayloadV2(context.getPayloadId())).thenReturn(dummyResponse); final SafeFuture future = handler.engineGetPayload(context, slot); verify(executionEngineClient).getPayloadV2(context.getPayloadId()); - assertThat(future).isCompleted(); - assertThat(future.get().getExecutionPayload()).isInstanceOf(ExecutionPayloadCapella.class); + final SchemaDefinitionsCapella schemaDefinitionCapella = + spec.atSlot(slot).getSchemaDefinitions().toVersionCapella().orElseThrow(); + final ExecutionPayloadSchema payloadSchema = + schemaDefinitionCapella.getExecutionPayloadSchema(); + assertThat(future) + .isCompletedWithValue( + new GetPayloadResponse( + responseData.executionPayload.asInternalExecutionPayload(payloadSchema), + responseData.blockValue)); } @Test @@ -83,16 +90,16 @@ void engineNewPayload_shouldCallNewPayloadV2() { final ExecutionPayload payload = dataStructureUtil.randomExecutionPayload(); final NewPayloadRequest newPayloadRequest = new NewPayloadRequest(payload); final ExecutionPayloadV2 payloadV2 = ExecutionPayloadV2.fromInternalExecutionPayload(payload); + final PayloadStatusV1 responseData = + new PayloadStatusV1( + ExecutionPayloadStatus.ACCEPTED, dataStructureUtil.randomBytes32(), null); final SafeFuture> dummyResponse = - SafeFuture.completedFuture( - new Response<>( - new PayloadStatusV1( - ExecutionPayloadStatus.ACCEPTED, dataStructureUtil.randomBytes32(), null))); + SafeFuture.completedFuture(new Response<>(responseData)); when(executionEngineClient.newPayloadV2(payloadV2)).thenReturn(dummyResponse); final SafeFuture future = handler.engineNewPayload(newPayloadRequest, UInt64.ZERO); verify(executionEngineClient).newPayloadV2(payloadV2); - assertThat(future).isCompleted(); + assertThat(future).isCompletedWithValue(responseData.asInternalExecutionPayload()); } @Test @@ -101,19 +108,19 @@ void engineForkChoiceUpdated_shouldCallEngineForkChoiceUpdatedV2() { final ForkChoiceState forkChoiceState = dataStructureUtil.randomForkChoiceState(false); final ForkChoiceStateV1 forkChoiceStateV1 = ForkChoiceStateV1.fromInternalForkChoiceState(forkChoiceState); + final ForkChoiceUpdatedResult responseData = + new ForkChoiceUpdatedResult( + new PayloadStatusV1( + ExecutionPayloadStatus.ACCEPTED, dataStructureUtil.randomBytes32(), ""), + dataStructureUtil.randomBytes8()); final SafeFuture> dummyResponse = - SafeFuture.completedFuture( - new Response<>( - new ForkChoiceUpdatedResult( - new PayloadStatusV1( - ExecutionPayloadStatus.ACCEPTED, dataStructureUtil.randomBytes32(), ""), - dataStructureUtil.randomBytes8()))); + SafeFuture.completedFuture(new Response<>(responseData)); when(executionEngineClient.forkChoiceUpdatedV2(forkChoiceStateV1, Optional.empty())) .thenReturn(dummyResponse); final SafeFuture future = handler.engineForkChoiceUpdated(forkChoiceState, Optional.empty()); verify(executionEngineClient).forkChoiceUpdatedV2(forkChoiceStateV1, Optional.empty()); - assertThat(future).isCompleted(); + assertThat(future).isCompletedWithValue(responseData.asInternalExecutionPayload()); } @Test @@ -141,18 +148,18 @@ void engineForkChoiceUpdatedBuildingBlockOnForkTransition_shouldCallEngineForkCh capellaStartSlot.minusMinZero(1), dataStructureUtil.randomBytes32(), false); final ForkChoiceStateV1 forkChoiceStateV1 = ForkChoiceStateV1.fromInternalForkChoiceState(forkChoiceState); + final ForkChoiceUpdatedResult responseData = + new ForkChoiceUpdatedResult( + new PayloadStatusV1( + ExecutionPayloadStatus.ACCEPTED, dataStructureUtil.randomBytes32(), ""), + dataStructureUtil.randomBytes8()); final SafeFuture> dummyResponse = - SafeFuture.completedFuture( - new Response<>( - new ForkChoiceUpdatedResult( - new PayloadStatusV1( - ExecutionPayloadStatus.ACCEPTED, dataStructureUtil.randomBytes32(), ""), - dataStructureUtil.randomBytes8()))); + SafeFuture.completedFuture(new Response<>(responseData)); when(executionEngineClient.forkChoiceUpdatedV2(forkChoiceStateV1, payloadAttributes)) .thenReturn(dummyResponse); final SafeFuture future = handler.engineForkChoiceUpdated(forkChoiceState, Optional.of(attributes)); verify(executionEngineClient).forkChoiceUpdatedV2(forkChoiceStateV1, payloadAttributes); - assertThat(future).isCompleted(); + assertThat(future).isCompletedWithValue(responseData.asInternalExecutionPayload()); } } diff --git a/ethereum/executionlayer/src/test/java/tech/pegasys/teku/ethereum/executionlayer/DenebExecutionClientHandlerTest.java b/ethereum/executionlayer/src/test/java/tech/pegasys/teku/ethereum/executionlayer/DenebExecutionClientHandlerTest.java index af480670b49..cdd2cb5e247 100644 --- a/ethereum/executionlayer/src/test/java/tech/pegasys/teku/ethereum/executionlayer/DenebExecutionClientHandlerTest.java +++ b/ethereum/executionlayer/src/test/java/tech/pegasys/teku/ethereum/executionlayer/DenebExecutionClientHandlerTest.java @@ -19,7 +19,6 @@ import java.util.List; import java.util.Optional; -import java.util.concurrent.ExecutionException; import org.apache.tuweni.bytes.Bytes32; import org.apache.tuweni.units.bigints.UInt256; import org.junit.jupiter.api.BeforeEach; @@ -36,18 +35,20 @@ import tech.pegasys.teku.infrastructure.async.SafeFuture; import tech.pegasys.teku.infrastructure.unsigned.UInt64; import tech.pegasys.teku.spec.TestSpecFactory; +import tech.pegasys.teku.spec.datastructures.blobs.versions.deneb.BlobSchema; import tech.pegasys.teku.spec.datastructures.blobs.versions.deneb.BlobSidecar; import tech.pegasys.teku.spec.datastructures.execution.BlobAndProof; import tech.pegasys.teku.spec.datastructures.execution.ExecutionPayload; import tech.pegasys.teku.spec.datastructures.execution.ExecutionPayloadContext; +import tech.pegasys.teku.spec.datastructures.execution.ExecutionPayloadSchema; import tech.pegasys.teku.spec.datastructures.execution.GetPayloadResponse; import tech.pegasys.teku.spec.datastructures.execution.NewPayloadRequest; -import tech.pegasys.teku.spec.datastructures.execution.versions.deneb.ExecutionPayloadDeneb; import tech.pegasys.teku.spec.executionlayer.ExecutionPayloadStatus; import tech.pegasys.teku.spec.executionlayer.ForkChoiceState; import tech.pegasys.teku.spec.executionlayer.PayloadBuildingAttributes; import tech.pegasys.teku.spec.executionlayer.PayloadStatus; import tech.pegasys.teku.spec.logic.versions.deneb.types.VersionedHash; +import tech.pegasys.teku.spec.schemas.SchemaDefinitionsDeneb; import tech.pegasys.teku.spec.util.DataStructureUtil; public class DenebExecutionClientHandlerTest extends ExecutionHandlerClientTest { @@ -59,28 +60,35 @@ void setup() { } @Test - void engineGetPayload_shouldCallGetPayloadV3() throws ExecutionException, InterruptedException { + void engineGetPayload_shouldCallGetPayloadV3() { final ExecutionClientHandler handler = getHandler(); final ExecutionPayloadContext context = randomContext(); + final GetPayloadV3Response responseData = + new GetPayloadV3Response( + ExecutionPayloadV3.fromInternalExecutionPayload( + dataStructureUtil.randomExecutionPayload()), + UInt256.MAX_VALUE, + BlobsBundleV1.fromInternalBlobsBundle(dataStructureUtil.randomBlobsBundle()), + true); final SafeFuture> dummyResponse = - SafeFuture.completedFuture( - new Response<>( - new GetPayloadV3Response( - ExecutionPayloadV3.fromInternalExecutionPayload( - dataStructureUtil.randomExecutionPayload()), - UInt256.MAX_VALUE, - BlobsBundleV1.fromInternalBlobsBundle(dataStructureUtil.randomBlobsBundle()), - true))); + SafeFuture.completedFuture(new Response<>(responseData)); when(executionEngineClient.getPayloadV3(context.getPayloadId())).thenReturn(dummyResponse); final UInt64 slot = dataStructureUtil.randomUInt64(1_000_000); final SafeFuture future = handler.engineGetPayload(context, slot); verify(executionEngineClient).getPayloadV3(context.getPayloadId()); - assertThat(future).isCompleted(); - assertThat(future.get().getExecutionPayload()).isInstanceOf(ExecutionPayloadDeneb.class); - assertThat(future.get().getExecutionPayloadValue()).isEqualTo(UInt256.MAX_VALUE); - assertThat(future.get().getBlobsBundle()).isPresent(); - assertThat(future.get().getShouldOverrideBuilder()).isTrue(); + final SchemaDefinitionsDeneb schemaDefinitionDeneb = + spec.atSlot(slot).getSchemaDefinitions().toVersionDeneb().orElseThrow(); + final ExecutionPayloadSchema payloadSchema = + schemaDefinitionDeneb.getExecutionPayloadSchema(); + final BlobSchema blobSchema = schemaDefinitionDeneb.getBlobSchema(); + assertThat(future) + .isCompletedWithValue( + new GetPayloadResponse( + responseData.executionPayload.asInternalExecutionPayload(payloadSchema), + responseData.blockValue, + responseData.blobsBundle.asInternalBlobsBundle(blobSchema), + responseData.shouldOverrideBuilder)); } @Test @@ -92,17 +100,17 @@ void engineNewPayload_shouldCallNewPayloadV3() { final NewPayloadRequest newPayloadRequest = new NewPayloadRequest(payload, versionedHashes, parentBeaconBlockRoot); final ExecutionPayloadV3 payloadV3 = ExecutionPayloadV3.fromInternalExecutionPayload(payload); + final PayloadStatusV1 responseData = + new PayloadStatusV1( + ExecutionPayloadStatus.ACCEPTED, dataStructureUtil.randomBytes32(), null); final SafeFuture> dummyResponse = - SafeFuture.completedFuture( - new Response<>( - new PayloadStatusV1( - ExecutionPayloadStatus.ACCEPTED, dataStructureUtil.randomBytes32(), null))); + SafeFuture.completedFuture(new Response<>(responseData)); when(executionEngineClient.newPayloadV3(payloadV3, versionedHashes, parentBeaconBlockRoot)) .thenReturn(dummyResponse); final SafeFuture future = handler.engineNewPayload(newPayloadRequest, UInt64.ZERO); verify(executionEngineClient).newPayloadV3(payloadV3, versionedHashes, parentBeaconBlockRoot); - assertThat(future).isCompleted(); + assertThat(future).isCompletedWithValue(responseData.asInternalExecutionPayload()); } @Test @@ -123,19 +131,19 @@ void engineForkChoiceUpdated_shouldCallEngineForkChoiceUpdatedV3() { dataStructureUtil.randomBytes32()); final Optional payloadAttributes = PayloadAttributesV3.fromInternalPayloadBuildingAttributesV3(Optional.of(attributes)); + final ForkChoiceUpdatedResult responseData = + new ForkChoiceUpdatedResult( + new PayloadStatusV1( + ExecutionPayloadStatus.ACCEPTED, dataStructureUtil.randomBytes32(), ""), + dataStructureUtil.randomBytes8()); final SafeFuture> dummyResponse = - SafeFuture.completedFuture( - new Response<>( - new ForkChoiceUpdatedResult( - new PayloadStatusV1( - ExecutionPayloadStatus.ACCEPTED, dataStructureUtil.randomBytes32(), ""), - dataStructureUtil.randomBytes8()))); + SafeFuture.completedFuture(new Response<>(responseData)); when(executionEngineClient.forkChoiceUpdatedV3(forkChoiceStateV1, payloadAttributes)) .thenReturn(dummyResponse); final SafeFuture future = handler.engineForkChoiceUpdated(forkChoiceState, Optional.of(attributes)); verify(executionEngineClient).forkChoiceUpdatedV3(forkChoiceStateV1, payloadAttributes); - assertThat(future).isCompleted(); + assertThat(future).isCompletedWithValue(responseData.asInternalExecutionPayload()); } @Test @@ -143,23 +151,29 @@ void engineGetBlobs_shouldCallGetBlobsV1() { final ExecutionClientHandler handler = getHandler(); final int maxBlobsPerBlock = spec.getMaxBlobsPerBlock().orElseThrow(); final List versionedHashes = - dataStructureUtil.randomVersionedHashes(maxBlobsPerBlock); + dataStructureUtil.randomVersionedHashes(maxBlobsPerBlock - 1); final List blobSidecars = dataStructureUtil.randomBlobSidecars(maxBlobsPerBlock); final UInt64 slot = dataStructureUtil.randomUInt64(1_000_000); + final List responseData = + blobSidecars.stream() + .map( + blobSidecar -> + new BlobAndProofV1( + blobSidecar.getBlob().getBytes(), + blobSidecar.getKZGProof().getBytesCompressed())) + .toList(); final SafeFuture>> dummyResponse = - SafeFuture.completedFuture( - new Response<>( - blobSidecars.stream() - .map( - blobSidecar -> - new BlobAndProofV1( - blobSidecar.getBlob().getBytes(), - blobSidecar.getKZGProof().getBytesCompressed())) - .toList())); + SafeFuture.completedFuture(new Response<>(responseData)); when(executionEngineClient.getBlobsV1(versionedHashes)).thenReturn(dummyResponse); final SafeFuture> future = handler.engineGetBlobs(versionedHashes, slot); verify(executionEngineClient).getBlobsV1(versionedHashes); - assertThat(future).isCompleted(); + final BlobSchema blobSchema = + spec.atSlot(slot).getSchemaDefinitions().toVersionDeneb().orElseThrow().getBlobSchema(); + assertThat(future) + .isCompletedWithValue( + responseData.stream() + .map(blobAndProofV1 -> blobAndProofV1.asInternalBlobsAndProofs(blobSchema)) + .toList()); } private ExecutionPayloadContext randomContext() { diff --git a/ethereum/executionlayer/src/test/java/tech/pegasys/teku/ethereum/executionlayer/ElectraExecutionClientHandlerTest.java b/ethereum/executionlayer/src/test/java/tech/pegasys/teku/ethereum/executionlayer/ElectraExecutionClientHandlerTest.java index c4d85f558b0..345946f0b96 100644 --- a/ethereum/executionlayer/src/test/java/tech/pegasys/teku/ethereum/executionlayer/ElectraExecutionClientHandlerTest.java +++ b/ethereum/executionlayer/src/test/java/tech/pegasys/teku/ethereum/executionlayer/ElectraExecutionClientHandlerTest.java @@ -20,7 +20,6 @@ import java.util.List; import java.util.Optional; -import java.util.concurrent.ExecutionException; import org.apache.tuweni.bytes.Bytes32; import org.apache.tuweni.units.bigints.UInt256; import org.junit.jupiter.api.BeforeEach; @@ -37,18 +36,20 @@ import tech.pegasys.teku.infrastructure.async.SafeFuture; import tech.pegasys.teku.infrastructure.unsigned.UInt64; import tech.pegasys.teku.spec.TestSpecFactory; +import tech.pegasys.teku.spec.datastructures.blobs.versions.deneb.BlobSchema; import tech.pegasys.teku.spec.datastructures.blobs.versions.deneb.BlobSidecar; import tech.pegasys.teku.spec.datastructures.execution.BlobAndProof; import tech.pegasys.teku.spec.datastructures.execution.ExecutionPayload; import tech.pegasys.teku.spec.datastructures.execution.ExecutionPayloadContext; +import tech.pegasys.teku.spec.datastructures.execution.ExecutionPayloadSchema; import tech.pegasys.teku.spec.datastructures.execution.GetPayloadResponse; import tech.pegasys.teku.spec.datastructures.execution.NewPayloadRequest; -import tech.pegasys.teku.spec.datastructures.execution.versions.deneb.ExecutionPayloadDeneb; import tech.pegasys.teku.spec.executionlayer.ExecutionPayloadStatus; import tech.pegasys.teku.spec.executionlayer.ForkChoiceState; import tech.pegasys.teku.spec.executionlayer.PayloadBuildingAttributes; import tech.pegasys.teku.spec.executionlayer.PayloadStatus; import tech.pegasys.teku.spec.logic.versions.deneb.types.VersionedHash; +import tech.pegasys.teku.spec.schemas.SchemaDefinitionsElectra; import tech.pegasys.teku.spec.util.DataStructureUtil; public class ElectraExecutionClientHandlerTest extends ExecutionHandlerClientTest { @@ -60,28 +61,35 @@ void setup() { } @Test - void engineGetPayload_shouldCallGetPayloadV4() throws ExecutionException, InterruptedException { + void engineGetPayload_shouldCallGetPayloadV4() { final ExecutionClientHandler handler = getHandler(); final ExecutionPayloadContext context = randomContext(); + final GetPayloadV4Response responseData = + new GetPayloadV4Response( + ExecutionPayloadV3.fromInternalExecutionPayload( + dataStructureUtil.randomExecutionPayload()), + UInt256.MAX_VALUE, + BlobsBundleV1.fromInternalBlobsBundle(dataStructureUtil.randomBlobsBundle()), + true); final SafeFuture> dummyResponse = - SafeFuture.completedFuture( - new Response<>( - new GetPayloadV4Response( - ExecutionPayloadV3.fromInternalExecutionPayload( - dataStructureUtil.randomExecutionPayload()), - UInt256.MAX_VALUE, - BlobsBundleV1.fromInternalBlobsBundle(dataStructureUtil.randomBlobsBundle()), - true))); + SafeFuture.completedFuture(new Response<>(responseData)); when(executionEngineClient.getPayloadV4(context.getPayloadId())).thenReturn(dummyResponse); final UInt64 slot = dataStructureUtil.randomUInt64(1_000_000); final SafeFuture future = handler.engineGetPayload(context, slot); verify(executionEngineClient).getPayloadV4(context.getPayloadId()); - assertThat(future).isCompleted(); - assertThat(future.get().getExecutionPayload()).isInstanceOf(ExecutionPayloadDeneb.class); - assertThat(future.get().getExecutionPayloadValue()).isEqualTo(UInt256.MAX_VALUE); - assertThat(future.get().getBlobsBundle()).isPresent(); - assertThat(future.get().getShouldOverrideBuilder()).isTrue(); + final SchemaDefinitionsElectra schemaDefinitionElectra = + spec.atSlot(slot).getSchemaDefinitions().toVersionElectra().orElseThrow(); + final ExecutionPayloadSchema payloadSchema = + schemaDefinitionElectra.getExecutionPayloadSchema(); + final BlobSchema blobSchema = schemaDefinitionElectra.getBlobSchema(); + assertThat(future) + .isCompletedWithValue( + new GetPayloadResponse( + responseData.executionPayload.asInternalExecutionPayload(payloadSchema), + responseData.blockValue, + responseData.blobsBundle.asInternalBlobsBundle(blobSchema), + responseData.shouldOverrideBuilder)); } @Test @@ -95,11 +103,11 @@ void engineNewPayload_shouldCallNewPayloadV4() { new NewPayloadRequest( payload, versionedHashes, parentBeaconBlockRoot, executionRequestsHash); final ExecutionPayloadV3 payloadV3 = ExecutionPayloadV3.fromInternalExecutionPayload(payload); + final PayloadStatusV1 responseData = + new PayloadStatusV1( + ExecutionPayloadStatus.ACCEPTED, dataStructureUtil.randomBytes32(), null); final SafeFuture> dummyResponse = - SafeFuture.completedFuture( - new Response<>( - new PayloadStatusV1( - ExecutionPayloadStatus.ACCEPTED, dataStructureUtil.randomBytes32(), null))); + SafeFuture.completedFuture(new Response<>(responseData)); when(executionEngineClient.newPayloadV4( eq(payloadV3), eq(versionedHashes), @@ -114,7 +122,7 @@ void engineNewPayload_shouldCallNewPayloadV4() { eq(versionedHashes), eq(parentBeaconBlockRoot), eq(executionRequestsHash)); - assertThat(future).isCompleted(); + assertThat(future).isCompletedWithValue(responseData.asInternalExecutionPayload()); } @Test @@ -135,19 +143,19 @@ void engineForkChoiceUpdated_shouldCallEngineForkChoiceUpdatedV3() { dataStructureUtil.randomBytes32()); final Optional payloadAttributes = PayloadAttributesV3.fromInternalPayloadBuildingAttributesV3(Optional.of(attributes)); + final ForkChoiceUpdatedResult responseData = + new ForkChoiceUpdatedResult( + new PayloadStatusV1( + ExecutionPayloadStatus.ACCEPTED, dataStructureUtil.randomBytes32(), ""), + dataStructureUtil.randomBytes8()); final SafeFuture> dummyResponse = - SafeFuture.completedFuture( - new Response<>( - new ForkChoiceUpdatedResult( - new PayloadStatusV1( - ExecutionPayloadStatus.ACCEPTED, dataStructureUtil.randomBytes32(), ""), - dataStructureUtil.randomBytes8()))); + SafeFuture.completedFuture(new Response<>(responseData)); when(executionEngineClient.forkChoiceUpdatedV3(forkChoiceStateV1, payloadAttributes)) .thenReturn(dummyResponse); final SafeFuture future = handler.engineForkChoiceUpdated(forkChoiceState, Optional.of(attributes)); verify(executionEngineClient).forkChoiceUpdatedV3(forkChoiceStateV1, payloadAttributes); - assertThat(future).isCompleted(); + assertThat(future).isCompletedWithValue(responseData.asInternalExecutionPayload()); } @Test @@ -158,20 +166,26 @@ void engineGetBlobs_shouldCallGetBlobsV1() { dataStructureUtil.randomVersionedHashes(maxBlobsPerBlock); final List blobSidecars = dataStructureUtil.randomBlobSidecars(maxBlobsPerBlock); final UInt64 slot = dataStructureUtil.randomUInt64(1_000_000); + final List responseData = + blobSidecars.stream() + .map( + blobSidecar -> + new BlobAndProofV1( + blobSidecar.getBlob().getBytes(), + blobSidecar.getKZGProof().getBytesCompressed())) + .toList(); final SafeFuture>> dummyResponse = - SafeFuture.completedFuture( - new Response<>( - blobSidecars.stream() - .map( - blobSidecar -> - new BlobAndProofV1( - blobSidecar.getBlob().getBytes(), - blobSidecar.getKZGProof().getBytesCompressed())) - .toList())); + SafeFuture.completedFuture(new Response<>(responseData)); when(executionEngineClient.getBlobsV1(versionedHashes)).thenReturn(dummyResponse); final SafeFuture> future = handler.engineGetBlobs(versionedHashes, slot); verify(executionEngineClient).getBlobsV1(versionedHashes); - assertThat(future).isCompleted(); + final BlobSchema blobSchema = + spec.atSlot(slot).getSchemaDefinitions().toVersionDeneb().orElseThrow().getBlobSchema(); + assertThat(future) + .isCompletedWithValue( + responseData.stream() + .map(blobAndProofV1 -> blobAndProofV1.asInternalBlobsAndProofs(blobSchema)) + .toList()); } private ExecutionPayloadContext randomContext() {