diff --git a/ethereum/executionclient/src/integration-test/java/tech/pegasys/teku/ethereum/executionclient/web3j/Web3JExecutionEngineClientTest.java b/ethereum/executionclient/src/integration-test/java/tech/pegasys/teku/ethereum/executionclient/web3j/Web3JExecutionEngineClientTest.java index 61b01eda021..e9a70f36b0c 100644 --- a/ethereum/executionclient/src/integration-test/java/tech/pegasys/teku/ethereum/executionclient/web3j/Web3JExecutionEngineClientTest.java +++ b/ethereum/executionclient/src/integration-test/java/tech/pegasys/teku/ethereum/executionclient/web3j/Web3JExecutionEngineClientTest.java @@ -323,11 +323,11 @@ public void newPayloadV4_shouldBuildRequestAndResponseSuccessfully() { final List blobVersionedHashes = dataStructureUtil.randomVersionedHashes(3); final Bytes32 parentBeaconBlockRoot = dataStructureUtil.randomBytes32(); - final Bytes32 executionRequestHash = dataStructureUtil.randomBytes32(); + final List executionRequests = dataStructureUtil.randomEncodedExecutionRequests(); final SafeFuture> futureResponse = eeClient.newPayloadV4( - executionPayloadV3, blobVersionedHashes, parentBeaconBlockRoot, executionRequestHash); + executionPayloadV3, blobVersionedHashes, parentBeaconBlockRoot, executionRequests); assertThat(futureResponse) .succeedsWithin(1, TimeUnit.SECONDS) diff --git a/ethereum/executionclient/src/main/java/tech/pegasys/teku/ethereum/executionclient/ExecutionEngineClient.java b/ethereum/executionclient/src/main/java/tech/pegasys/teku/ethereum/executionclient/ExecutionEngineClient.java index ebbdd3d4286..19d8d8a3d97 100644 --- a/ethereum/executionclient/src/main/java/tech/pegasys/teku/ethereum/executionclient/ExecutionEngineClient.java +++ b/ethereum/executionclient/src/main/java/tech/pegasys/teku/ethereum/executionclient/ExecutionEngineClient.java @@ -15,6 +15,7 @@ import java.util.List; import java.util.Optional; +import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.bytes.Bytes32; import tech.pegasys.teku.ethereum.executionclient.schema.BlobAndProofV1; import tech.pegasys.teku.ethereum.executionclient.schema.ClientVersionV1; @@ -64,7 +65,7 @@ SafeFuture> newPayloadV4( ExecutionPayloadV3 executionPayload, List blobVersionedHashes, Bytes32 parentBeaconBlockRoot, - Bytes32 executionRequestHash); + List executionRequests); SafeFuture> forkChoiceUpdatedV1( ForkChoiceStateV1 forkChoiceState, Optional payloadAttributes); diff --git a/ethereum/executionclient/src/main/java/tech/pegasys/teku/ethereum/executionclient/ThrottlingExecutionEngineClient.java b/ethereum/executionclient/src/main/java/tech/pegasys/teku/ethereum/executionclient/ThrottlingExecutionEngineClient.java index 8ee347e077b..646a513c8dc 100644 --- a/ethereum/executionclient/src/main/java/tech/pegasys/teku/ethereum/executionclient/ThrottlingExecutionEngineClient.java +++ b/ethereum/executionclient/src/main/java/tech/pegasys/teku/ethereum/executionclient/ThrottlingExecutionEngineClient.java @@ -15,6 +15,7 @@ import java.util.List; import java.util.Optional; +import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.bytes.Bytes32; import org.hyperledger.besu.plugin.services.MetricsSystem; import tech.pegasys.teku.ethereum.executionclient.schema.BlobAndProofV1; @@ -112,14 +113,11 @@ public SafeFuture> newPayloadV4( final ExecutionPayloadV3 executionPayload, final List blobVersionedHashes, final Bytes32 parentBeaconBlockRoot, - final Bytes32 executionRequestHash) { + final List executionRequests) { return taskQueue.queueTask( () -> delegate.newPayloadV4( - executionPayload, - blobVersionedHashes, - parentBeaconBlockRoot, - executionRequestHash)); + executionPayload, blobVersionedHashes, parentBeaconBlockRoot, executionRequests)); } @Override diff --git a/ethereum/executionclient/src/main/java/tech/pegasys/teku/ethereum/executionclient/methods/EngineNewPayloadV4.java b/ethereum/executionclient/src/main/java/tech/pegasys/teku/ethereum/executionclient/methods/EngineNewPayloadV4.java index 8a72db49295..57ff1341bd7 100644 --- a/ethereum/executionclient/src/main/java/tech/pegasys/teku/ethereum/executionclient/methods/EngineNewPayloadV4.java +++ b/ethereum/executionclient/src/main/java/tech/pegasys/teku/ethereum/executionclient/methods/EngineNewPayloadV4.java @@ -16,6 +16,7 @@ import java.util.List; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.bytes.Bytes32; import tech.pegasys.teku.ethereum.executionclient.ExecutionEngineClient; import tech.pegasys.teku.ethereum.executionclient.response.ResponseUnwrapper; @@ -51,21 +52,21 @@ public SafeFuture execute(final JsonRpcRequestParams params) { final List blobVersionedHashes = params.getRequiredListParameter(1, VersionedHash.class); final Bytes32 parentBeaconBlockRoot = params.getRequiredParameter(2, Bytes32.class); - final Bytes32 executionRequestHash = params.getRequiredParameter(3, Bytes32.class); + final List executionRequests = params.getRequiredListParameter(3, Bytes.class); LOG.trace( - "Calling {}(executionPayload={}, blobVersionedHashes={}, parentBeaconBlockRoot={}, executionRequestHash={})", + "Calling {}(executionPayload={}, blobVersionedHashes={}, parentBeaconBlockRoot={}, executionRequests={})", getVersionedName(), executionPayload, blobVersionedHashes, parentBeaconBlockRoot, - executionRequestHash); + executionRequests); final ExecutionPayloadV3 executionPayloadV3 = ExecutionPayloadV3.fromInternalExecutionPayload(executionPayload); return executionEngineClient .newPayloadV4( - executionPayloadV3, blobVersionedHashes, parentBeaconBlockRoot, executionRequestHash) + executionPayloadV3, blobVersionedHashes, parentBeaconBlockRoot, executionRequests) .thenApply(ResponseUnwrapper::unwrapExecutionClientResponseOrThrow) .thenApply(PayloadStatusV1::asInternalExecutionPayload) .thenPeek( diff --git a/ethereum/executionclient/src/main/java/tech/pegasys/teku/ethereum/executionclient/metrics/MetricRecordingExecutionEngineClient.java b/ethereum/executionclient/src/main/java/tech/pegasys/teku/ethereum/executionclient/metrics/MetricRecordingExecutionEngineClient.java index 4e6d59668a0..62d3a4def02 100644 --- a/ethereum/executionclient/src/main/java/tech/pegasys/teku/ethereum/executionclient/metrics/MetricRecordingExecutionEngineClient.java +++ b/ethereum/executionclient/src/main/java/tech/pegasys/teku/ethereum/executionclient/metrics/MetricRecordingExecutionEngineClient.java @@ -16,6 +16,7 @@ import java.util.List; import java.util.Map; import java.util.Optional; +import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.bytes.Bytes32; import org.hyperledger.besu.plugin.services.MetricsSystem; import tech.pegasys.teku.ethereum.executionclient.ExecutionEngineClient; @@ -143,11 +144,11 @@ public SafeFuture> newPayloadV4( final ExecutionPayloadV3 executionPayload, final List blobVersionedHashes, final Bytes32 parentBeaconBlockRoot, - final Bytes32 executionRequestHash) { + final List executionRequests) { return countRequest( () -> delegate.newPayloadV4( - executionPayload, blobVersionedHashes, parentBeaconBlockRoot, executionRequestHash), + executionPayload, blobVersionedHashes, parentBeaconBlockRoot, executionRequests), NEW_PAYLOAD_V4_METHOD); } diff --git a/ethereum/executionclient/src/main/java/tech/pegasys/teku/ethereum/executionclient/web3j/Web3JExecutionEngineClient.java b/ethereum/executionclient/src/main/java/tech/pegasys/teku/ethereum/executionclient/web3j/Web3JExecutionEngineClient.java index 137d99b3211..c47e6f87b61 100644 --- a/ethereum/executionclient/src/main/java/tech/pegasys/teku/ethereum/executionclient/web3j/Web3JExecutionEngineClient.java +++ b/ethereum/executionclient/src/main/java/tech/pegasys/teku/ethereum/executionclient/web3j/Web3JExecutionEngineClient.java @@ -21,6 +21,7 @@ import java.util.Collections; import java.util.List; import java.util.Optional; +import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.bytes.Bytes32; import org.apache.tuweni.units.bigints.UInt256; import org.web3j.protocol.core.DefaultBlockParameterName; @@ -180,7 +181,7 @@ public SafeFuture> newPayloadV4( final ExecutionPayloadV3 executionPayload, final List blobVersionedHashes, final Bytes32 parentBeaconBlockRoot, - final Bytes32 executionRequestHash) { + final List executionRequests) { final List expectedBlobVersionedHashes = blobVersionedHashes.stream().map(VersionedHash::toHexString).toList(); final Request web3jRequest = @@ -190,7 +191,7 @@ public SafeFuture> newPayloadV4( executionPayload, expectedBlobVersionedHashes, parentBeaconBlockRoot.toHexString(), - executionRequestHash.toHexString()), + executionRequests), web3JClient.getWeb3jService(), PayloadStatusV1Web3jResponse.class); return web3JClient.doRequest(web3jRequest, EL_ENGINE_BLOCK_EXECUTION_TIMEOUT); diff --git a/ethereum/executionclient/src/test/java/tech/pegasys/teku/ethereum/executionclient/methods/EngineGetPayloadV4Test.java b/ethereum/executionclient/src/test/java/tech/pegasys/teku/ethereum/executionclient/methods/EngineGetPayloadV4Test.java index 860e2c2bb51..1d79c160606 100644 --- a/ethereum/executionclient/src/test/java/tech/pegasys/teku/ethereum/executionclient/methods/EngineGetPayloadV4Test.java +++ b/ethereum/executionclient/src/test/java/tech/pegasys/teku/ethereum/executionclient/methods/EngineGetPayloadV4Test.java @@ -130,7 +130,7 @@ public void shouldCallGetPayloadV4AndParseResponseSuccessfully() { final ExecutionPayload executionPayloadElectra = dataStructureUtil.randomExecutionPayload(); final ExecutionRequests executionRequests = dataStructureUtil.randomExecutionRequests(); final List encodedExecutionRequests = - executionRequestsDataCodec.encodeWithoutTypePrefix(executionRequests); + executionRequestsDataCodec.encode(executionRequests); assertThat(executionPayloadElectra).isInstanceOf(ExecutionPayloadDeneb.class); when(executionEngineClient.getPayloadV4(eq(executionPayloadContext.getPayloadId()))) diff --git a/ethereum/executionclient/src/test/java/tech/pegasys/teku/ethereum/executionclient/methods/EngineNewPayloadV4Test.java b/ethereum/executionclient/src/test/java/tech/pegasys/teku/ethereum/executionclient/methods/EngineNewPayloadV4Test.java index 524875313a9..9035576e852 100644 --- a/ethereum/executionclient/src/test/java/tech/pegasys/teku/ethereum/executionclient/methods/EngineNewPayloadV4Test.java +++ b/ethereum/executionclient/src/test/java/tech/pegasys/teku/ethereum/executionclient/methods/EngineNewPayloadV4Test.java @@ -25,6 +25,7 @@ import java.util.List; import java.util.concurrent.TimeUnit; +import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.bytes.Bytes32; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -119,7 +120,7 @@ public void shouldReturnFailedExecutionWhenEngineClientRequestFails() { final ExecutionPayload executionPayload = dataStructureUtil.randomExecutionPayload(); final List blobVersionedHashes = dataStructureUtil.randomVersionedHashes(3); final Bytes32 parentBeaconBlockRoot = dataStructureUtil.randomBytes32(); - final Bytes32 executionRequestHash = dataStructureUtil.randomBytes32(); + final List executionRequests = dataStructureUtil.randomEncodedExecutionRequests(); final String errorResponseFromClient = "error!"; when(executionEngineClient.newPayloadV4(any(), any(), any(), any())) @@ -130,7 +131,7 @@ public void shouldReturnFailedExecutionWhenEngineClientRequestFails() { .add(executionPayload) .add(blobVersionedHashes) .add(parentBeaconBlockRoot) - .add(executionRequestHash) + .add(executionRequests) .build(); assertThat(jsonRpcMethod.execute(params)) @@ -143,7 +144,7 @@ public void shouldCallNewPayloadV4WithExecutionPayloadV3AndCorrectParameters() { final ExecutionPayload executionPayload = dataStructureUtil.randomExecutionPayload(); final List blobVersionedHashes = dataStructureUtil.randomVersionedHashes(4); final Bytes32 parentBeaconBlockRoot = dataStructureUtil.randomBytes32(); - final Bytes32 executionRequestHash = dataStructureUtil.randomBytes32(); + final List executionRequests = dataStructureUtil.randomEncodedExecutionRequests(); final ExecutionPayloadV3 executionPayloadV3 = ExecutionPayloadV3.fromInternalExecutionPayload(executionPayload); @@ -155,7 +156,7 @@ public void shouldCallNewPayloadV4WithExecutionPayloadV3AndCorrectParameters() { eq(executionPayloadV3), eq(blobVersionedHashes), eq(parentBeaconBlockRoot), - eq(executionRequestHash))) + eq(executionRequests))) .thenReturn(dummySuccessfulResponse()); final JsonRpcRequestParams params = @@ -163,7 +164,7 @@ public void shouldCallNewPayloadV4WithExecutionPayloadV3AndCorrectParameters() { .add(executionPayload) .add(blobVersionedHashes) .add(parentBeaconBlockRoot) - .add(executionRequestHash) + .add(executionRequests) .build(); assertThat(jsonRpcMethod.execute(params)).isCompleted(); @@ -173,7 +174,7 @@ public void shouldCallNewPayloadV4WithExecutionPayloadV3AndCorrectParameters() { eq(executionPayloadV3), eq(blobVersionedHashes), eq(parentBeaconBlockRoot), - eq(executionRequestHash)); + eq(executionRequests)); verifyNoMoreInteractions(executionEngineClient); } diff --git a/ethereum/executionlayer/src/main/java/tech/pegasys/teku/ethereum/executionlayer/ExecutionClientHandlerImpl.java b/ethereum/executionlayer/src/main/java/tech/pegasys/teku/ethereum/executionlayer/ExecutionClientHandlerImpl.java index 06cd24fd07e..581f494cb0a 100644 --- a/ethereum/executionlayer/src/main/java/tech/pegasys/teku/ethereum/executionlayer/ExecutionClientHandlerImpl.java +++ b/ethereum/executionlayer/src/main/java/tech/pegasys/teku/ethereum/executionlayer/ExecutionClientHandlerImpl.java @@ -110,7 +110,7 @@ public SafeFuture engineNewPayload( .add(executionPayload) .addOptional(newPayloadRequest.getVersionedHashes()) .addOptional(newPayloadRequest.getParentBeaconBlockRoot()) - .addOptional(newPayloadRequest.getExecutionRequestsHash()); + .addOptional(newPayloadRequest.getExecutionRequests()); return engineMethodsResolver .getMethod( 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 0bd039d2d65..1665419dfba 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,6 +20,7 @@ import java.util.List; import java.util.Optional; +import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.bytes.Bytes32; import org.apache.tuweni.units.bigints.UInt256; import org.junit.jupiter.api.BeforeEach; @@ -98,10 +99,10 @@ void engineNewPayload_shouldCallNewPayloadV4() { final ExecutionPayload payload = dataStructureUtil.randomExecutionPayload(); final List versionedHashes = dataStructureUtil.randomVersionedHashes(3); final Bytes32 parentBeaconBlockRoot = dataStructureUtil.randomBytes32(); - final Bytes32 executionRequestsHash = dataStructureUtil.randomBytes32(); + final List encodedExecutionRequests = dataStructureUtil.randomEncodedExecutionRequests(); final NewPayloadRequest newPayloadRequest = new NewPayloadRequest( - payload, versionedHashes, parentBeaconBlockRoot, executionRequestsHash); + payload, versionedHashes, parentBeaconBlockRoot, encodedExecutionRequests); final ExecutionPayloadV3 payloadV3 = ExecutionPayloadV3.fromInternalExecutionPayload(payload); final PayloadStatusV1 responseData = new PayloadStatusV1( @@ -112,7 +113,7 @@ void engineNewPayload_shouldCallNewPayloadV4() { eq(payloadV3), eq(versionedHashes), eq(parentBeaconBlockRoot), - eq(executionRequestsHash))) + eq(encodedExecutionRequests))) .thenReturn(dummyResponse); final SafeFuture future = handler.engineNewPayload(newPayloadRequest, UInt64.ZERO); @@ -121,7 +122,7 @@ void engineNewPayload_shouldCallNewPayloadV4() { eq(payloadV3), eq(versionedHashes), eq(parentBeaconBlockRoot), - eq(executionRequestsHash)); + eq(encodedExecutionRequests)); assertThat(future).isCompletedWithValue(responseData.asInternalExecutionPayload()); } diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/execution/NewPayloadRequest.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/execution/NewPayloadRequest.java index e8a112eac9f..174e7e686a4 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/execution/NewPayloadRequest.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/execution/NewPayloadRequest.java @@ -17,6 +17,7 @@ import java.util.List; import java.util.Objects; import java.util.Optional; +import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.bytes.Bytes32; import tech.pegasys.teku.spec.logic.versions.deneb.types.VersionedHash; @@ -25,13 +26,13 @@ public class NewPayloadRequest { private final ExecutionPayload executionPayload; private final Optional> versionedHashes; private final Optional parentBeaconBlockRoot; - private final Optional executionRequestsHash; + private final Optional> executionRequests; public NewPayloadRequest(final ExecutionPayload executionPayload) { this.executionPayload = executionPayload; this.versionedHashes = Optional.empty(); this.parentBeaconBlockRoot = Optional.empty(); - this.executionRequestsHash = Optional.empty(); + this.executionRequests = Optional.empty(); } public NewPayloadRequest( @@ -41,18 +42,18 @@ public NewPayloadRequest( this.executionPayload = executionPayload; this.versionedHashes = Optional.of(versionedHashes); this.parentBeaconBlockRoot = Optional.of(parentBeaconBlockRoot); - this.executionRequestsHash = Optional.empty(); + this.executionRequests = Optional.empty(); } public NewPayloadRequest( final ExecutionPayload executionPayload, final List versionedHashes, final Bytes32 parentBeaconBlockRoot, - final Bytes32 executionRequestsHash) { + final List executionRequests) { this.executionPayload = executionPayload; this.versionedHashes = Optional.of(versionedHashes); this.parentBeaconBlockRoot = Optional.of(parentBeaconBlockRoot); - this.executionRequestsHash = Optional.of(executionRequestsHash); + this.executionRequests = Optional.of(executionRequests); } public ExecutionPayload getExecutionPayload() { @@ -67,8 +68,8 @@ public Optional getParentBeaconBlockRoot() { return parentBeaconBlockRoot; } - public Optional getExecutionRequestsHash() { - return executionRequestsHash; + public Optional> getExecutionRequests() { + return executionRequests; } @Override @@ -83,13 +84,13 @@ public boolean equals(final Object o) { return Objects.equals(executionPayload, that.executionPayload) && Objects.equals(versionedHashes, that.versionedHashes) && Objects.equals(parentBeaconBlockRoot, that.parentBeaconBlockRoot) - && Objects.equals(executionRequestsHash, that.executionRequestsHash); + && Objects.equals(executionRequests, that.executionRequests); } @Override public int hashCode() { return Objects.hash( - executionPayload, versionedHashes, parentBeaconBlockRoot, executionRequestsHash); + executionPayload, versionedHashes, parentBeaconBlockRoot, executionRequests); } @Override @@ -98,7 +99,7 @@ public String toString() { .add("executionPayload", executionPayload) .add("versionedHashes", versionedHashes) .add("parentBeaconBlockRoot", parentBeaconBlockRoot) - .add("executionRequestsHash", executionRequestsHash) + .add("executionRequests", executionRequests) .toString(); } } diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/execution/versions/electra/ExecutionRequestsDataCodec.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/execution/versions/electra/ExecutionRequestsDataCodec.java index 1e51ad64264..e3127504af6 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/execution/versions/electra/ExecutionRequestsDataCodec.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/execution/versions/electra/ExecutionRequestsDataCodec.java @@ -13,11 +13,8 @@ package tech.pegasys.teku.spec.datastructures.execution.versions.electra; -import com.google.common.annotations.VisibleForTesting; import java.util.List; import org.apache.tuweni.bytes.Bytes; -import org.apache.tuweni.bytes.Bytes32; -import tech.pegasys.teku.infrastructure.crypto.Hash; import tech.pegasys.teku.infrastructure.ssz.SszList; import tech.pegasys.teku.spec.datastructures.execution.ExecutionRequestsBuilder; @@ -27,10 +24,6 @@ public class ExecutionRequestsDataCodec { private static final int EXPECTED_REQUEST_DATA_ELEMENTS = 3; - private static final Bytes DEPOSIT_REQUEST_PREFIX = Bytes.of(DepositRequest.REQUEST_TYPE); - private static final Bytes WITHDRAWAL_REQUEST_PREFIX = Bytes.of(WithdrawalRequest.REQUEST_TYPE); - private static final Bytes CONSOLIDATION_REQUEST_PREFIX = - Bytes.of(ConsolidationRequest.REQUEST_TYPE); private final ExecutionRequestsSchema executionRequestsSchema; @@ -38,6 +31,12 @@ public ExecutionRequestsDataCodec(final ExecutionRequestsSchema executionRequest this.executionRequestsSchema = executionRequestsSchema; } + /** + * Decodes the execution requests received from the EL. + * + * @param executionRequestData list of encoded execution requests from the EL + * @return an ExecutionRequests object with the requests + */ public ExecutionRequests decode(final List executionRequestData) { if (executionRequestData.size() != EXPECTED_REQUEST_DATA_ELEMENTS) { throw new IllegalArgumentException( @@ -78,17 +77,13 @@ public ExecutionRequests decode(final List executionRequestData) { return executionRequestsBuilder.build(); } - public Bytes32 hash(final ExecutionRequests executionRequests) { - final Bytes sortedEncodedRequests = - encodeWithTypePrefix(executionRequests).stream() - .map(Hash::sha256) - .map(Bytes.class::cast) - .reduce(Bytes.EMPTY, Bytes::concatenate); - return Hash.sha256(sortedEncodedRequests); - } - - @VisibleForTesting - public List encodeWithoutTypePrefix(final ExecutionRequests executionRequests) { + /** + * Encodes the provided ExecutionRequests object to send the requests to the EL for validation. + * + * @param executionRequests the execution requests in the BeaconBlock + * @return list of encoded execution requests + */ + public List encode(final ExecutionRequests executionRequests) { final SszList depositRequestsSszList = executionRequestsSchema .getDepositRequestsSchema() @@ -107,13 +102,4 @@ public List encodeWithoutTypePrefix(final ExecutionRequests executionRequ withdrawalRequestsSszList.sszSerialize(), consolidationRequestsSszList.sszSerialize()); } - - @VisibleForTesting - List encodeWithTypePrefix(final ExecutionRequests executionRequests) { - final List encodeWithoutTypePrefix = encodeWithoutTypePrefix(executionRequests); - return List.of( - Bytes.concatenate(DEPOSIT_REQUEST_PREFIX, encodeWithoutTypePrefix.get(0)), - Bytes.concatenate(WITHDRAWAL_REQUEST_PREFIX, encodeWithoutTypePrefix.get(1)), - Bytes.concatenate(CONSOLIDATION_REQUEST_PREFIX, encodeWithoutTypePrefix.get(2))); - } } diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/electra/SpecLogicElectra.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/electra/SpecLogicElectra.java index 3dce3a95d9a..96cc8954090 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/electra/SpecLogicElectra.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/electra/SpecLogicElectra.java @@ -16,6 +16,7 @@ import java.util.Optional; import tech.pegasys.teku.infrastructure.time.TimeProvider; import tech.pegasys.teku.spec.config.SpecConfigElectra; +import tech.pegasys.teku.spec.datastructures.execution.versions.electra.ExecutionRequestsDataCodec; import tech.pegasys.teku.spec.logic.common.AbstractSpecLogic; import tech.pegasys.teku.spec.logic.common.helpers.Predicates; import tech.pegasys.teku.spec.logic.common.operations.OperationSignatureVerifier; @@ -153,6 +154,8 @@ public static SpecLogicElectra create( beaconStateAccessors, validatorsUtil, config, miscHelpers, schemaDefinitions); final LightClientUtil lightClientUtil = new LightClientUtil(beaconStateAccessors, syncCommitteeUtil, schemaDefinitions); + final ExecutionRequestsDataCodec executionRequestsDataCodec = + new ExecutionRequestsDataCodec(schemaDefinitions.getExecutionRequestsSchema()); final BlockProcessorElectra blockProcessor = new BlockProcessorElectra( config, @@ -166,7 +169,8 @@ public static SpecLogicElectra create( attestationUtil, validatorsUtil, operationValidator, - schemaDefinitions); + schemaDefinitions, + executionRequestsDataCodec); final ForkChoiceUtil forkChoiceUtil = new ForkChoiceUtilDeneb( config, beaconStateAccessors, epochProcessor, attestationUtil, miscHelpers); diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/electra/block/BlockProcessorElectra.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/electra/block/BlockProcessorElectra.java index ed5a8a7b684..dffd43c51d7 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/electra/block/BlockProcessorElectra.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/electra/block/BlockProcessorElectra.java @@ -105,7 +105,8 @@ public BlockProcessorElectra( final AttestationUtil attestationUtil, final ValidatorsUtil validatorsUtil, final OperationValidator operationValidator, - final SchemaDefinitionsElectra schemaDefinitions) { + final SchemaDefinitionsElectra schemaDefinitions, + final ExecutionRequestsDataCodec executionRequestsDataCodec) { super( specConfig, predicates, @@ -124,8 +125,7 @@ public BlockProcessorElectra( this.beaconStateMutatorsElectra = beaconStateMutators; this.beaconStateAccessorsElectra = beaconStateAccessors; this.schemaDefinitionsElectra = schemaDefinitions; - this.executionRequestsDataCodec = - new ExecutionRequestsDataCodec(schemaDefinitions.getExecutionRequestsSchema()); + this.executionRequestsDataCodec = executionRequestsDataCodec; } @Override @@ -146,7 +146,7 @@ public NewPayloadRequest computeNewPayloadRequest( executionPayload, versionedHashes, parentBeaconBlockRoot, - executionRequestsDataCodec.hash(executionRequests)); + executionRequestsDataCodec.encode(executionRequests)); } @Override diff --git a/ethereum/spec/src/test/java/tech/pegasys/teku/spec/datastructures/execution/versions/electra/ExecutionRequestsDataCodecTest.java b/ethereum/spec/src/test/java/tech/pegasys/teku/spec/datastructures/execution/versions/electra/ExecutionRequestsDataCodecTest.java index 520565983b2..73d5f595432 100644 --- a/ethereum/spec/src/test/java/tech/pegasys/teku/spec/datastructures/execution/versions/electra/ExecutionRequestsDataCodecTest.java +++ b/ethereum/spec/src/test/java/tech/pegasys/teku/spec/datastructures/execution/versions/electra/ExecutionRequestsDataCodecTest.java @@ -39,6 +39,19 @@ class ExecutionRequestsDataCodecTest { private final ExecutionRequestsDataCodec codec = new ExecutionRequestsDataCodec(executionRequestsSchema); + @Test + public void codecRoundTrip() { + final List expectedExecutionRequestsData = + List.of( + depositRequestListEncoded, + withdrawalRequestsListEncoded, + consolidationRequestsListEncoded); + + final List encodedExecutionRequestData = + codec.encode(codec.decode(expectedExecutionRequestsData)); + assertThat(encodedExecutionRequestData).isEqualTo(expectedExecutionRequestsData); + } + @Test public void decodeExecutionRequestData() { final List executionRequestsData = @@ -122,7 +135,7 @@ public void decodeExecutionRequestDataWithZeroElements() { } @Test - public void encodeWithTypePrefixExecutionRequests() { + public void encodeExecutionRequests() { final ExecutionRequests executionRequests = new ExecutionRequestsBuilderElectra(executionRequestsSchema) .deposits(List.of(depositRequest1, depositRequest2)) @@ -130,19 +143,17 @@ public void encodeWithTypePrefixExecutionRequests() { .consolidations(List.of(consolidationRequest1)) .build(); - final List encodedRequests = codec.encodeWithTypePrefix(executionRequests); + final List encodedRequests = codec.encode(executionRequests); assertThat(encodedRequests) .containsExactly( - Bytes.concatenate(Bytes.of(DepositRequest.REQUEST_TYPE), depositRequestListEncoded), - Bytes.concatenate( - Bytes.of(WithdrawalRequest.REQUEST_TYPE), withdrawalRequestsListEncoded), - Bytes.concatenate( - Bytes.of(ConsolidationRequest.REQUEST_TYPE), consolidationRequestsListEncoded)); + depositRequestListEncoded, + withdrawalRequestsListEncoded, + consolidationRequestsListEncoded); } @Test - public void encodeWithTypePrefixExecutionRequestsWithOneEmptyRequestList() { + public void encodeWithWithOneEmptyRequestList() { final ExecutionRequests executionRequests = new ExecutionRequestsBuilderElectra(executionRequestsSchema) .deposits(List.of(depositRequest1, depositRequest2)) @@ -150,18 +161,14 @@ public void encodeWithTypePrefixExecutionRequestsWithOneEmptyRequestList() { .consolidations(List.of(consolidationRequest1)) .build(); - final List encodedRequests = codec.encodeWithTypePrefix(executionRequests); + final List encodedRequests = codec.encode(executionRequests); assertThat(encodedRequests) - .containsExactly( - Bytes.concatenate(Bytes.of(DepositRequest.REQUEST_TYPE), depositRequestListEncoded), - Bytes.of(WithdrawalRequest.REQUEST_TYPE), - Bytes.concatenate( - Bytes.of(ConsolidationRequest.REQUEST_TYPE), consolidationRequestsListEncoded)); + .containsExactly(depositRequestListEncoded, Bytes.EMPTY, consolidationRequestsListEncoded); } @Test - public void encodeWithTypePrefixExecutionRequestsWithAllEmptyRequestLists() { + public void encodeWithAllEmptyRequestLists() { final ExecutionRequests executionRequests = new ExecutionRequestsBuilderElectra(executionRequestsSchema) .deposits(List.of()) @@ -169,45 +176,9 @@ public void encodeWithTypePrefixExecutionRequestsWithAllEmptyRequestLists() { .consolidations(List.of()) .build(); - final List encodedRequests = codec.encodeWithTypePrefix(executionRequests); - - assertThat(encodedRequests) - .containsExactly( - Bytes.of(DepositRequest.REQUEST_TYPE), - Bytes.of(WithdrawalRequest.REQUEST_TYPE), - Bytes.of(ConsolidationRequest.REQUEST_TYPE)); - } - - @Test - public void hashExecutionRequests() { - // Previously known hash of the encoded execution requests - final Bytes expectedHash = - Bytes.fromHexString("0xc0ff01be6ca468a08f1f5fb1dc83b3d92cc782b47ee567bcf17f925e73ff9c00"); - final ExecutionRequests executionRequests = - new ExecutionRequestsBuilderElectra(executionRequestsSchema) - .deposits(List.of(depositRequest1, depositRequest2)) - .withdrawals(List.of(withdrawalRequest1, withdrawalRequest2)) - .consolidations(List.of(consolidationRequest1)) - .build(); - - // Hash will only match if elements and order are correct - assertThat(codec.hash(executionRequests)).isEqualTo(expectedHash); - } - - @Test - public void hashExecutionRequestsWithAllEmptyRequestLists() { - // Previously known hash of the encoded execution requests - final Bytes expectedHash = - Bytes.fromHexString("0x6036c41849da9c076ed79654d434017387a88fb833c2856b32e18218b3341c5f"); - final ExecutionRequests executionRequests = - new ExecutionRequestsBuilderElectra(executionRequestsSchema) - .deposits(List.of()) - .withdrawals(List.of()) - .consolidations(List.of()) - .build(); + final List encodedRequests = codec.encode(executionRequests); - // Hash will only match if elements and order are correct - assertThat(codec.hash(executionRequests)).isEqualTo(expectedHash); + assertThat(encodedRequests).containsExactly(Bytes.EMPTY, Bytes.EMPTY, Bytes.EMPTY); } // Examples taken from diff --git a/ethereum/spec/src/test/java/tech/pegasys/teku/spec/logic/versions/electra/block/BlockProcessorElectraTest.java b/ethereum/spec/src/test/java/tech/pegasys/teku/spec/logic/versions/electra/block/BlockProcessorElectraTest.java index 3add055fa7f..8a33c73de79 100644 --- a/ethereum/spec/src/test/java/tech/pegasys/teku/spec/logic/versions/electra/block/BlockProcessorElectraTest.java +++ b/ethereum/spec/src/test/java/tech/pegasys/teku/spec/logic/versions/electra/block/BlockProcessorElectraTest.java @@ -22,6 +22,7 @@ import java.util.function.Supplier; import java.util.stream.Collectors; import java.util.stream.IntStream; +import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.bytes.Bytes32; import org.junit.jupiter.api.Test; import tech.pegasys.teku.bls.BLSPublicKey; @@ -545,8 +546,8 @@ public void shouldCreateNewPayloadRequestWithExecutionRequestsHash() throws Exce .map(SszKZGCommitment::getKZGCommitment) .map(miscHelpers::kzgCommitmentToVersionedHash) .collect(Collectors.toList()); - final Bytes32 expectedExecutionRequestsHash = - getExecutionRequestsDataCodec().hash(blockBody.getExecutionRequests()); + final List expectedExecutionRequests = + getExecutionRequestsDataCodec().encode(blockBody.getExecutionRequests()); final NewPayloadRequest newPayloadRequest = spec.getBlockProcessor(UInt64.ONE).computeNewPayloadRequest(preState, blockBody); @@ -564,8 +565,7 @@ public void shouldCreateNewPayloadRequestWithExecutionRequestsHash() throws Exce assertThat(newPayloadRequest.getParentBeaconBlockRoot()).isPresent(); assertThat(newPayloadRequest.getParentBeaconBlockRoot().get()) .isEqualTo(preState.getLatestBlockHeader().getParentRoot()); - assertThat(newPayloadRequest.getExecutionRequestsHash()) - .hasValue(expectedExecutionRequestsHash); + assertThat(newPayloadRequest.getExecutionRequests()).hasValue(expectedExecutionRequests); } private Supplier validatorExitContextSupplier(final BeaconState state) { diff --git a/ethereum/spec/src/testFixtures/java/tech/pegasys/teku/spec/util/DataStructureUtil.java b/ethereum/spec/src/testFixtures/java/tech/pegasys/teku/spec/util/DataStructureUtil.java index 98c31a885e7..405eef9c9cd 100644 --- a/ethereum/spec/src/testFixtures/java/tech/pegasys/teku/spec/util/DataStructureUtil.java +++ b/ethereum/spec/src/testFixtures/java/tech/pegasys/teku/spec/util/DataStructureUtil.java @@ -2512,7 +2512,7 @@ public List randomEncodedExecutionRequests() { spec.forMilestone(SpecMilestone.ELECTRA).getSchemaDefinitions()) .getExecutionRequestsSchema(); return new ExecutionRequestsDataCodec(executionRequestsSchema) - .encodeWithoutTypePrefix(randomExecutionRequests()); + .encode(randomExecutionRequests()); } public WithdrawalRequest randomWithdrawalRequest() {