diff --git a/eth-reference-tests/src/referenceTest/java/tech/pegasys/teku/reference/phase0/ssz_static/SszTestExecutor.java b/eth-reference-tests/src/referenceTest/java/tech/pegasys/teku/reference/phase0/ssz_static/SszTestExecutor.java index 56b587b2b70..2a48f6cb7b0 100644 --- a/eth-reference-tests/src/referenceTest/java/tech/pegasys/teku/reference/phase0/ssz_static/SszTestExecutor.java +++ b/eth-reference-tests/src/referenceTest/java/tech/pegasys/teku/reference/phase0/ssz_static/SszTestExecutor.java @@ -210,6 +210,10 @@ public class SszTestExecutor implements TestExecutor { new SszTestExecutor<>( schemas -> SchemaDefinitionsElectra.required(schemas).getPendingBalanceDepositSchema())) + .put( + "ssz_static/PendingDeposit", + new SszTestExecutor<>( + schemas -> SchemaDefinitionsElectra.required(schemas).getPendingDepositSchema())) .put( "ssz_static/PendingConsolidation", new SszTestExecutor<>( diff --git a/ethereum/executionclient/src/main/java/tech/pegasys/teku/ethereum/executionclient/schema/GetPayloadV2Response.java b/ethereum/executionclient/src/main/java/tech/pegasys/teku/ethereum/executionclient/schema/GetPayloadV2Response.java index 600783c2fd8..1bdbdad99f7 100644 --- a/ethereum/executionclient/src/main/java/tech/pegasys/teku/ethereum/executionclient/schema/GetPayloadV2Response.java +++ b/ethereum/executionclient/src/main/java/tech/pegasys/teku/ethereum/executionclient/schema/GetPayloadV2Response.java @@ -21,6 +21,8 @@ import org.apache.tuweni.units.bigints.UInt256; import tech.pegasys.teku.ethereum.executionclient.serialization.UInt256AsHexDeserializer; import tech.pegasys.teku.ethereum.executionclient.serialization.UInt256AsHexSerializer; +import tech.pegasys.teku.spec.datastructures.execution.ExecutionPayloadSchema; +import tech.pegasys.teku.spec.datastructures.execution.GetPayloadResponse; public class GetPayloadV2Response { public final ExecutionPayloadV2 executionPayload; @@ -37,4 +39,10 @@ public GetPayloadV2Response( this.executionPayload = executionPayload; this.blockValue = blockValue; } + + public GetPayloadResponse asInternalGetPayloadResponse( + final ExecutionPayloadSchema executionPayloadSchema) { + return new GetPayloadResponse( + executionPayload.asInternalExecutionPayload(executionPayloadSchema), blockValue); + } } diff --git a/ethereum/executionclient/src/main/java/tech/pegasys/teku/ethereum/executionclient/schema/GetPayloadV3Response.java b/ethereum/executionclient/src/main/java/tech/pegasys/teku/ethereum/executionclient/schema/GetPayloadV3Response.java index 4869aa33478..3e7dbd3b4ee 100644 --- a/ethereum/executionclient/src/main/java/tech/pegasys/teku/ethereum/executionclient/schema/GetPayloadV3Response.java +++ b/ethereum/executionclient/src/main/java/tech/pegasys/teku/ethereum/executionclient/schema/GetPayloadV3Response.java @@ -21,6 +21,9 @@ import org.apache.tuweni.units.bigints.UInt256; import tech.pegasys.teku.ethereum.executionclient.serialization.UInt256AsHexDeserializer; import tech.pegasys.teku.ethereum.executionclient.serialization.UInt256AsHexSerializer; +import tech.pegasys.teku.spec.datastructures.blobs.versions.deneb.BlobSchema; +import tech.pegasys.teku.spec.datastructures.execution.ExecutionPayloadSchema; +import tech.pegasys.teku.spec.datastructures.execution.GetPayloadResponse; public class GetPayloadV3Response { public final ExecutionPayloadV3 executionPayload; @@ -46,4 +49,13 @@ public GetPayloadV3Response( this.blobsBundle = blobsBundle; this.shouldOverrideBuilder = shouldOverrideBuilder; } + + public GetPayloadResponse asInternalGetPayloadResponse( + final ExecutionPayloadSchema executionPayloadSchema, final BlobSchema blobSchema) { + return new GetPayloadResponse( + executionPayload.asInternalExecutionPayload(executionPayloadSchema), + blockValue, + blobsBundle.asInternalBlobsBundle(blobSchema), + shouldOverrideBuilder); + } } diff --git a/ethereum/executionclient/src/main/java/tech/pegasys/teku/ethereum/executionclient/schema/GetPayloadV4Response.java b/ethereum/executionclient/src/main/java/tech/pegasys/teku/ethereum/executionclient/schema/GetPayloadV4Response.java index e9bb45ed743..e414321626b 100644 --- a/ethereum/executionclient/src/main/java/tech/pegasys/teku/ethereum/executionclient/schema/GetPayloadV4Response.java +++ b/ethereum/executionclient/src/main/java/tech/pegasys/teku/ethereum/executionclient/schema/GetPayloadV4Response.java @@ -21,6 +21,9 @@ import org.apache.tuweni.units.bigints.UInt256; import tech.pegasys.teku.ethereum.executionclient.serialization.UInt256AsHexDeserializer; import tech.pegasys.teku.ethereum.executionclient.serialization.UInt256AsHexSerializer; +import tech.pegasys.teku.spec.datastructures.blobs.versions.deneb.BlobSchema; +import tech.pegasys.teku.spec.datastructures.execution.ExecutionPayloadSchema; +import tech.pegasys.teku.spec.datastructures.execution.GetPayloadResponse; public class GetPayloadV4Response { public final ExecutionPayloadV3 executionPayload; @@ -46,4 +49,13 @@ public GetPayloadV4Response( this.blobsBundle = blobsBundle; this.shouldOverrideBuilder = shouldOverrideBuilder; } + + public GetPayloadResponse asInternalGetPayloadResponse( + final ExecutionPayloadSchema executionPayloadSchema, final BlobSchema blobSchema) { + return new GetPayloadResponse( + executionPayload.asInternalExecutionPayload(executionPayloadSchema), + blockValue, + blobsBundle.asInternalBlobsBundle(blobSchema), + shouldOverrideBuilder); + } } 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..a8ef2d41953 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,23 @@ 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 executionPayloadSchema = + schemaDefinitionCapella.getExecutionPayloadSchema(); + assertThat(future) + .isCompletedWithValue(responseData.asInternalGetPayloadResponse(executionPayloadSchema)); } @Test @@ -83,16 +87,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 +105,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 +145,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..df49c8a7d42 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,31 @@ 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 executionPayloadSchema = + schemaDefinitionDeneb.getExecutionPayloadSchema(); + final BlobSchema blobSchema = schemaDefinitionDeneb.getBlobSchema(); + assertThat(future) + .isCompletedWithValue( + responseData.asInternalGetPayloadResponse(executionPayloadSchema, blobSchema)); } @Test @@ -92,17 +96,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 +127,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 +147,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..a0b10002bd7 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,31 @@ 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 executionPayloadSchema = + schemaDefinitionElectra.getExecutionPayloadSchema(); + final BlobSchema blobSchema = schemaDefinitionElectra.getBlobSchema(); + assertThat(future) + .isCompletedWithValue( + responseData.asInternalGetPayloadResponse(executionPayloadSchema, blobSchema)); } @Test @@ -95,11 +99,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 +118,7 @@ void engineNewPayload_shouldCallNewPayloadV4() { eq(versionedHashes), eq(parentBeaconBlockRoot), eq(executionRequestsHash)); - assertThat(future).isCompleted(); + assertThat(future).isCompletedWithValue(responseData.asInternalExecutionPayload()); } @Test @@ -135,19 +139,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 +162,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() { diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/config/SpecConfigElectra.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/config/SpecConfigElectra.java index e443cc26f83..83c648f6dbf 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/config/SpecConfigElectra.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/config/SpecConfigElectra.java @@ -42,7 +42,7 @@ static SpecConfigElectra required(final SpecConfig specConfig) { UInt64 getMaxEffectiveBalanceElectra(); - int getPendingBalanceDepositsLimit(); + int getPendingDepositsLimit(); int getPendingPartialWithdrawalsLimit(); @@ -64,6 +64,8 @@ static SpecConfigElectra required(final SpecConfig specConfig) { int getMaxPendingPartialsPerWithdrawalsSweep(); + int getMaxPendingDepositsPerEpoch(); + @Override Optional toVersionElectra(); } diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/config/SpecConfigElectraImpl.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/config/SpecConfigElectraImpl.java index a389e74e797..62140a31259 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/config/SpecConfigElectraImpl.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/config/SpecConfigElectraImpl.java @@ -27,7 +27,7 @@ public class SpecConfigElectraImpl extends DelegatingSpecConfigDeneb implements private final UInt64 minActivationBalance; private final UInt64 maxEffectiveBalanceElectra; - private final int pendingBalanceDepositsLimit; + private final int pendingDepositsLimit; private final int pendingPartialWithdrawalsLimit; private final int pendingConsolidationsLimit; private final int minSlashingPenaltyQuotientElectra; @@ -38,6 +38,7 @@ public class SpecConfigElectraImpl extends DelegatingSpecConfigDeneb implements private final int maxDepositRequestsPerPayload; private final int maxWithdrawalRequestsPerPayload; private final int maxPendingPartialsPerWithdrawalsSweep; + private final int maxPendingDepositsPerEpoch; public SpecConfigElectraImpl( final SpecConfigDeneb specConfig, @@ -46,7 +47,7 @@ public SpecConfigElectraImpl( final UInt64 minPerEpochChurnLimitElectra, final UInt64 minActivationBalance, final UInt64 maxEffectiveBalanceElectra, - final int pendingBalanceDepositsLimit, + final int pendingDepositsLimit, final int pendingPartialWithdrawalsLimit, final int pendingConsolidationsLimit, final int minSlashingPenaltyQuotientElectra, @@ -56,14 +57,15 @@ public SpecConfigElectraImpl( final int maxConsolidationRequestsPerPayload, final int maxDepositRequestsPerPayload, final int maxWithdrawalRequestsPerPayload, - final int maxPendingPartialsPerWithdrawalsSweep) { + final int maxPendingPartialsPerWithdrawalsSweep, + final int maxPendingDepositsPerEpoch) { super(specConfig); this.electraForkVersion = electraForkVersion; this.electraForkEpoch = electraForkEpoch; this.minPerEpochChurnLimitElectra = minPerEpochChurnLimitElectra; this.minActivationBalance = minActivationBalance; this.maxEffectiveBalanceElectra = maxEffectiveBalanceElectra; - this.pendingBalanceDepositsLimit = pendingBalanceDepositsLimit; + this.pendingDepositsLimit = pendingDepositsLimit; this.pendingPartialWithdrawalsLimit = pendingPartialWithdrawalsLimit; this.pendingConsolidationsLimit = pendingConsolidationsLimit; this.minSlashingPenaltyQuotientElectra = minSlashingPenaltyQuotientElectra; @@ -74,6 +76,7 @@ public SpecConfigElectraImpl( this.maxDepositRequestsPerPayload = maxDepositRequestsPerPayload; this.maxWithdrawalRequestsPerPayload = maxWithdrawalRequestsPerPayload; this.maxPendingPartialsPerWithdrawalsSweep = maxPendingPartialsPerWithdrawalsSweep; + this.maxPendingDepositsPerEpoch = maxPendingDepositsPerEpoch; } @Override @@ -102,8 +105,8 @@ public UInt64 getMaxEffectiveBalanceElectra() { } @Override - public int getPendingBalanceDepositsLimit() { - return pendingBalanceDepositsLimit; + public int getPendingDepositsLimit() { + return pendingDepositsLimit; } @Override @@ -156,6 +159,11 @@ public int getMaxPendingPartialsPerWithdrawalsSweep() { return maxPendingPartialsPerWithdrawalsSweep; } + @Override + public int getMaxPendingDepositsPerEpoch() { + return maxPendingDepositsPerEpoch; + } + @Override public Optional toVersionElectra() { return Optional.of(this); @@ -176,7 +184,7 @@ public boolean equals(final Object o) { && Objects.equals(minPerEpochChurnLimitElectra, that.minPerEpochChurnLimitElectra) && Objects.equals(minActivationBalance, that.minActivationBalance) && Objects.equals(maxEffectiveBalanceElectra, that.maxEffectiveBalanceElectra) - && pendingBalanceDepositsLimit == that.pendingBalanceDepositsLimit + && pendingDepositsLimit == that.pendingDepositsLimit && pendingPartialWithdrawalsLimit == that.pendingPartialWithdrawalsLimit && pendingConsolidationsLimit == that.pendingConsolidationsLimit && minSlashingPenaltyQuotientElectra == that.minSlashingPenaltyQuotientElectra @@ -186,7 +194,8 @@ public boolean equals(final Object o) { && maxConsolidationRequestsPerPayload == that.maxConsolidationRequestsPerPayload && maxDepositRequestsPerPayload == that.maxDepositRequestsPerPayload && maxWithdrawalRequestsPerPayload == that.maxWithdrawalRequestsPerPayload - && maxPendingPartialsPerWithdrawalsSweep == that.maxPendingPartialsPerWithdrawalsSweep; + && maxPendingPartialsPerWithdrawalsSweep == that.maxPendingPartialsPerWithdrawalsSweep + && maxPendingDepositsPerEpoch == that.maxPendingDepositsPerEpoch; } @Override @@ -198,7 +207,7 @@ public int hashCode() { minPerEpochChurnLimitElectra, minActivationBalance, maxEffectiveBalanceElectra, - pendingBalanceDepositsLimit, + pendingDepositsLimit, pendingPartialWithdrawalsLimit, pendingConsolidationsLimit, minSlashingPenaltyQuotientElectra, @@ -208,6 +217,7 @@ public int hashCode() { maxConsolidationRequestsPerPayload, maxDepositRequestsPerPayload, maxWithdrawalRequestsPerPayload, - maxPendingPartialsPerWithdrawalsSweep); + maxPendingPartialsPerWithdrawalsSweep, + maxPendingDepositsPerEpoch); } } diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/config/builder/ElectraBuilder.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/config/builder/ElectraBuilder.java index e4b68df534b..830d3b8eebc 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/config/builder/ElectraBuilder.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/config/builder/ElectraBuilder.java @@ -34,7 +34,7 @@ public class ElectraBuilder implements ForkConfigBuilder getValidationMap() { constants.put("minPerEpochChurnLimitElectra", minPerEpochChurnLimitElectra); constants.put("minActivationBalance", minActivationBalance); constants.put("maxEffectiveBalanceElectra", maxEffectiveBalanceElectra); - constants.put("pendingBalanceDepositsLimit", pendingBalanceDepositsLimit); + constants.put("pendingDepositsLimit", pendingDepositsLimit); constants.put("pendingPartialWithdrawalsLimit", pendingPartialWithdrawalsLimit); constants.put("pendingConsolidationsLimit", pendingConsolidationsLimit); constants.put("minSlashingPenaltyQuotientElectra", minSlashingPenaltyQuotientElectra); @@ -207,6 +215,7 @@ public Map getValidationMap() { constants.put("maxDepositRequestsPerPayload", maxDepositRequestsPerPayload); constants.put("maxWithdrawalRequestsPerPayload", maxWithdrawalRequestsPerPayload); constants.put("maxPendingPartialsPerWithdrawalsSweep", maxPendingPartialsPerWithdrawalsSweep); + constants.put("maxPendingDepositsPerEpoch", maxPendingDepositsPerEpoch); return constants; } diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/state/beaconstate/versions/electra/BeaconStateSchemaElectra.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/state/beaconstate/versions/electra/BeaconStateSchemaElectra.java index 258e13c0e0c..5b1bd4aa780 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/state/beaconstate/versions/electra/BeaconStateSchemaElectra.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/state/beaconstate/versions/electra/BeaconStateSchemaElectra.java @@ -128,8 +128,7 @@ private static List getUniqueFields(final SpecConfig specConfig) { BeaconStateFields.PENDING_BALANCE_DEPOSITS, () -> SszListSchema.create( - pendingBalanceDepositSchema, - specConfigElectra.getPendingBalanceDepositsLimit())); + pendingBalanceDepositSchema, specConfigElectra.getPendingDepositsLimit())); final SszField pendingPartialWithdrawalsField = new SszField( PENDING_PARTIAL_WITHDRAWALS_INDEX, diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/state/versions/electra/PendingDeposit.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/state/versions/electra/PendingDeposit.java new file mode 100644 index 00000000000..69d11d07f42 --- /dev/null +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/state/versions/electra/PendingDeposit.java @@ -0,0 +1,117 @@ +/* + * Copyright Consensys Software Inc., 2024 + * + * 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.state.versions.electra; + +import org.apache.tuweni.bytes.Bytes32; +import tech.pegasys.teku.bls.BLSPublicKey; +import tech.pegasys.teku.bls.BLSSignature; +import tech.pegasys.teku.infrastructure.ssz.containers.Container5; +import tech.pegasys.teku.infrastructure.ssz.containers.ContainerSchema5; +import tech.pegasys.teku.infrastructure.ssz.primitive.SszBytes32; +import tech.pegasys.teku.infrastructure.ssz.primitive.SszUInt64; +import tech.pegasys.teku.infrastructure.ssz.schema.SszPrimitiveSchemas; +import tech.pegasys.teku.infrastructure.ssz.tree.TreeNode; +import tech.pegasys.teku.infrastructure.unsigned.UInt64; +import tech.pegasys.teku.spec.datastructures.type.SszPublicKey; +import tech.pegasys.teku.spec.datastructures.type.SszPublicKeySchema; +import tech.pegasys.teku.spec.datastructures.type.SszSignature; +import tech.pegasys.teku.spec.datastructures.type.SszSignatureSchema; + +public class PendingDeposit + extends Container5< + PendingDeposit, SszPublicKey, SszBytes32, SszUInt64, SszSignature, SszUInt64> { + + public static class PendingDepositSchema + extends ContainerSchema5< + PendingDeposit, SszPublicKey, SszBytes32, SszUInt64, SszSignature, SszUInt64> { + + public PendingDepositSchema() { + super( + "PendingDeposit", + namedSchema("pubkey", SszPublicKeySchema.INSTANCE), + namedSchema("withdrawal_credentials", SszPrimitiveSchemas.BYTES32_SCHEMA), + namedSchema("amount", SszPrimitiveSchemas.UINT64_SCHEMA), + namedSchema("signature", SszSignatureSchema.INSTANCE), + namedSchema("slot", SszPrimitiveSchemas.UINT64_SCHEMA)); + } + + @Override + public PendingDeposit createFromBackingNode(final TreeNode node) { + return new PendingDeposit(this, node); + } + + public PendingDeposit create( + final SszPublicKey publicKey, + final SszBytes32 withdrawalCredentials, + final SszUInt64 amount, + final SszSignature signature, + final SszUInt64 slot) { + return new PendingDeposit(this, publicKey, withdrawalCredentials, amount, signature, slot); + } + + public SszPublicKey getPublicKeySchema() { + return (SszPublicKey) getFieldSchema0(); + } + + public SszBytes32 getWithdrawalCredentialsSchema() { + return (SszBytes32) getFieldSchema1(); + } + + public SszUInt64 getAmountSchema() { + return (SszUInt64) getFieldSchema2(); + } + + public SszSignatureSchema getSignatureSchema() { + return (SszSignatureSchema) getFieldSchema3(); + } + + public SszUInt64 getSlotSchema() { + return (SszUInt64) getFieldSchema4(); + } + } + + private PendingDeposit(final PendingDepositSchema type, final TreeNode backingNode) { + super(type, backingNode); + } + + private PendingDeposit( + final PendingDepositSchema type, + final SszPublicKey publicKey, + final SszBytes32 withdrawalCredentials, + final SszUInt64 amount, + final SszSignature signature, + final SszUInt64 slot) { + super(type, publicKey, withdrawalCredentials, amount, signature, slot); + } + + public BLSPublicKey getPublicKey() { + return ((SszPublicKey) get(0)).getBLSPublicKey(); + } + + public Bytes32 getWithdrawalCredentials() { + return ((SszBytes32) get(1)).get(); + } + + public UInt64 getAmount() { + return ((SszUInt64) get(2)).get(); + } + + public BLSSignature getSignature() { + return ((SszSignature) get(3)).getSignature(); + } + + public UInt64 getSlot() { + return ((SszUInt64) get(4)).get(); + } +} diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/SchemaDefinitionsElectra.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/SchemaDefinitionsElectra.java index fd29e92cd34..fe064ae6f83 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/SchemaDefinitionsElectra.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/SchemaDefinitionsElectra.java @@ -62,6 +62,7 @@ import tech.pegasys.teku.spec.datastructures.state.beaconstate.versions.electra.MutableBeaconStateElectra; import tech.pegasys.teku.spec.datastructures.state.versions.electra.PendingBalanceDeposit; import tech.pegasys.teku.spec.datastructures.state.versions.electra.PendingConsolidation; +import tech.pegasys.teku.spec.datastructures.state.versions.electra.PendingDeposit; import tech.pegasys.teku.spec.datastructures.state.versions.electra.PendingPartialWithdrawal; import tech.pegasys.teku.spec.schemas.registry.SchemaRegistry; @@ -97,6 +98,7 @@ public class SchemaDefinitionsElectra extends SchemaDefinitionsDeneb { private final ConsolidationRequestSchema consolidationRequestSchema; private final PendingBalanceDeposit.PendingBalanceDepositSchema pendingBalanceDepositSchema; + private final PendingDeposit.PendingDepositSchema pendingDepositSchema; private final PendingPartialWithdrawal.PendingPartialWithdrawalSchema pendingPartialWithdrawalSchema; @@ -170,6 +172,7 @@ public SchemaDefinitionsElectra(final SchemaRegistry schemaRegistry) { this.withdrawalRequestSchema = WithdrawalRequest.SSZ_SCHEMA; this.consolidationRequestSchema = ConsolidationRequest.SSZ_SCHEMA; this.pendingBalanceDepositSchema = new PendingBalanceDeposit.PendingBalanceDepositSchema(); + this.pendingDepositSchema = new PendingDeposit.PendingDepositSchema(); this.pendingPartialWithdrawalSchema = new PendingPartialWithdrawal.PendingPartialWithdrawalSchema(); this.pendingConsolidationSchema = new PendingConsolidation.PendingConsolidationSchema(); @@ -321,6 +324,10 @@ public PendingBalanceDeposit.PendingBalanceDepositSchema getPendingBalanceDeposi return pendingBalanceDepositSchema; } + public PendingDeposit.PendingDepositSchema getPendingDepositSchema() { + return pendingDepositSchema; + } + public SszListSchema getPendingBalanceDepositsSchema() { return beaconStateSchema.getPendingBalanceDepositsSchema(); } diff --git a/ethereum/spec/src/main/resources/tech/pegasys/teku/spec/config/presets/mainnet/electra.yaml b/ethereum/spec/src/main/resources/tech/pegasys/teku/spec/config/presets/mainnet/electra.yaml index ca41f21fc04..0b594ff3404 100644 --- a/ethereum/spec/src/main/resources/tech/pegasys/teku/spec/config/presets/mainnet/electra.yaml +++ b/ethereum/spec/src/main/resources/tech/pegasys/teku/spec/config/presets/mainnet/electra.yaml @@ -10,7 +10,7 @@ MAX_EFFECTIVE_BALANCE_ELECTRA: 2048000000000 # State list lengths # --------------------------------------------------------------- # `uint64(2**27)` (= 134,217,728) -PENDING_BALANCE_DEPOSITS_LIMIT: 134217728 +PENDING_DEPOSITS_LIMIT: 134217728 # `uint64(2**27)` (= 134,217,728) PENDING_PARTIAL_WITHDRAWALS_LIMIT: 134217728 # `uint64(2**18)` (= 262,144) @@ -42,4 +42,9 @@ MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD: 16 # Withdrawals processing # --------------------------------------------------------------- # 2**3 ( = 8) pending withdrawals -MAX_PENDING_PARTIALS_PER_WITHDRAWALS_SWEEP: 8 \ No newline at end of file +MAX_PENDING_PARTIALS_PER_WITHDRAWALS_SWEEP: 8 + +# Pending deposits processing +# --------------------------------------------------------------- +# 2**4 ( = 4) pending deposits +MAX_PENDING_DEPOSITS_PER_EPOCH: 16 \ No newline at end of file diff --git a/ethereum/spec/src/main/resources/tech/pegasys/teku/spec/config/presets/minimal/electra.yaml b/ethereum/spec/src/main/resources/tech/pegasys/teku/spec/config/presets/minimal/electra.yaml index 16bc5fdbc1d..126c84727c9 100644 --- a/ethereum/spec/src/main/resources/tech/pegasys/teku/spec/config/presets/minimal/electra.yaml +++ b/ethereum/spec/src/main/resources/tech/pegasys/teku/spec/config/presets/minimal/electra.yaml @@ -10,7 +10,7 @@ MAX_EFFECTIVE_BALANCE_ELECTRA: 2048000000000 # State list lengths # --------------------------------------------------------------- # `uint64(2**27)` (= 134,217,728) -PENDING_BALANCE_DEPOSITS_LIMIT: 134217728 +PENDING_DEPOSITS_LIMIT: 134217728 # [customized] `uint64(2**6)` (= 64) PENDING_PARTIAL_WITHDRAWALS_LIMIT: 64 # [customized] `uint64(2**6)` (= 64) @@ -42,4 +42,9 @@ MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD: 2 # Withdrawals processing # --------------------------------------------------------------- # 2**0 ( = 1) pending withdrawals -MAX_PENDING_PARTIALS_PER_WITHDRAWALS_SWEEP: 1 \ No newline at end of file +MAX_PENDING_PARTIALS_PER_WITHDRAWALS_SWEEP: 1 + +# Pending deposits processing +# --------------------------------------------------------------- +# 2**4 ( = 4) pending deposits +MAX_PENDING_DEPOSITS_PER_EPOCH: 16 \ No newline at end of file diff --git a/ethereum/spec/src/main/resources/tech/pegasys/teku/spec/config/presets/swift/electra.yaml b/ethereum/spec/src/main/resources/tech/pegasys/teku/spec/config/presets/swift/electra.yaml index 16bc5fdbc1d..126c84727c9 100644 --- a/ethereum/spec/src/main/resources/tech/pegasys/teku/spec/config/presets/swift/electra.yaml +++ b/ethereum/spec/src/main/resources/tech/pegasys/teku/spec/config/presets/swift/electra.yaml @@ -10,7 +10,7 @@ MAX_EFFECTIVE_BALANCE_ELECTRA: 2048000000000 # State list lengths # --------------------------------------------------------------- # `uint64(2**27)` (= 134,217,728) -PENDING_BALANCE_DEPOSITS_LIMIT: 134217728 +PENDING_DEPOSITS_LIMIT: 134217728 # [customized] `uint64(2**6)` (= 64) PENDING_PARTIAL_WITHDRAWALS_LIMIT: 64 # [customized] `uint64(2**6)` (= 64) @@ -42,4 +42,9 @@ MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD: 2 # Withdrawals processing # --------------------------------------------------------------- # 2**0 ( = 1) pending withdrawals -MAX_PENDING_PARTIALS_PER_WITHDRAWALS_SWEEP: 1 \ No newline at end of file +MAX_PENDING_PARTIALS_PER_WITHDRAWALS_SWEEP: 1 + +# Pending deposits processing +# --------------------------------------------------------------- +# 2**4 ( = 4) pending deposits +MAX_PENDING_DEPOSITS_PER_EPOCH: 16 \ No newline at end of file diff --git a/ethereum/spec/src/test/java/tech/pegasys/teku/spec/config/SpecConfigElectraTest.java b/ethereum/spec/src/test/java/tech/pegasys/teku/spec/config/SpecConfigElectraTest.java index ff7e95f9d33..e17f6cd61c6 100644 --- a/ethereum/spec/src/test/java/tech/pegasys/teku/spec/config/SpecConfigElectraTest.java +++ b/ethereum/spec/src/test/java/tech/pegasys/teku/spec/config/SpecConfigElectraTest.java @@ -95,6 +95,7 @@ private SpecConfigElectra createRandomElectraConfig( dataStructureUtil.randomPositiveInt(1), dataStructureUtil.randomPositiveInt(8192), dataStructureUtil.randomPositiveInt(16), - dataStructureUtil.randomPositiveInt(8)) {}; + dataStructureUtil.randomPositiveInt(8), + dataStructureUtil.randomPositiveInt(16)) {}; } }