Skip to content

Commit

Permalink
implement ssz in builder client
Browse files Browse the repository at this point in the history
  • Loading branch information
tbenr committed Jan 14, 2025
1 parent 4493bae commit 095c767
Show file tree
Hide file tree
Showing 37 changed files with 727 additions and 445 deletions.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ void getStatus_success() {
.satisfies(
response -> {
assertThat(response.isSuccess()).isTrue();
assertThat(response.getPayload()).isNull();
assertThat(response.payload()).isNull();
});

verifyGetRequest("/eth/v1/builder/status");
Expand All @@ -158,7 +158,7 @@ void getStatus_failures() {
.satisfies(
response -> {
assertThat(response.isFailure()).isTrue();
assertThat(response.getErrorMessage()).isEqualTo(INTERNAL_SERVER_ERROR_MESSAGE);
assertThat(response.errorMessage()).isEqualTo(INTERNAL_SERVER_ERROR_MESSAGE);
});

verifyGetRequest("/eth/v1/builder/status");
Expand All @@ -177,7 +177,7 @@ void registerValidators_success() {
.satisfies(
response -> {
assertThat(response.isSuccess()).isTrue();
assertThat(response.getPayload()).isNull();
assertThat(response.payload()).isNull();
});

verifyPostRequest("/eth/v1/builder/validators", signedValidatorRegistrationsRequest);
Expand All @@ -194,7 +194,7 @@ void registerValidators_zeroRegistrationsDoesNotMakeRequest() {
.satisfies(
response -> {
assertThat(response.isSuccess()).isTrue();
assertThat(response.getPayload()).isNull();
assertThat(response.payload()).isNull();
});

assertThat(mockWebServer.getRequestCount()).isEqualTo(0);
Expand All @@ -215,7 +215,7 @@ void registerValidators_failures() {
.satisfies(
response -> {
assertThat(response.isFailure()).isTrue();
assertThat(response.getErrorMessage()).isEqualTo(unknownValidatorError);
assertThat(response.errorMessage()).isEqualTo(unknownValidatorError);
});

verifyPostRequest("/eth/v1/builder/validators", signedValidatorRegistrationsRequest);
Expand All @@ -228,7 +228,7 @@ void registerValidators_failures() {
.satisfies(
response -> {
assertThat(response.isFailure()).isTrue();
assertThat(response.getErrorMessage()).isEqualTo(INTERNAL_SERVER_ERROR_MESSAGE);
assertThat(response.errorMessage()).isEqualTo(INTERNAL_SERVER_ERROR_MESSAGE);
});

verifyPostRequest("/eth/v1/builder/validators", signedValidatorRegistrationsRequest);
Expand All @@ -247,7 +247,7 @@ void getHeader_success_doesNotSetUserAgentHeader() {
.satisfies(
response -> {
assertThat(response.isSuccess()).isTrue();
assertThat(response.getPayload())
assertThat(response.payload())
.isPresent()
.hasValueSatisfying(this::verifySignedBuilderBidResponse);
});
Expand All @@ -270,7 +270,7 @@ void getHeader_success() {
.satisfies(
response -> {
assertThat(response.isSuccess()).isTrue();
assertThat(response.getPayload())
assertThat(response.payload())
.isPresent()
.hasValueSatisfying(this::verifySignedBuilderBidResponse);
});
Expand All @@ -289,7 +289,7 @@ void getHeader_noHeaderAvailable() {
.satisfies(
response -> {
assertThat(response.isSuccess()).isTrue();
assertThat(response.getPayload()).isEmpty();
assertThat(response.payload()).isEmpty();
});

verifyGetRequest(
Expand All @@ -308,7 +308,7 @@ void getHeader_failures() {
.satisfies(
response -> {
assertThat(response.isFailure()).isTrue();
assertThat(response.getErrorMessage()).isEqualTo(missingParentHashError);
assertThat(response.errorMessage()).isEqualTo(missingParentHashError);
});

verifyGetRequest(
Expand All @@ -322,7 +322,7 @@ void getHeader_failures() {
.satisfies(
response -> {
assertThat(response.isFailure()).isTrue();
assertThat(response.getErrorMessage()).isEqualTo(INTERNAL_SERVER_ERROR_MESSAGE);
assertThat(response.errorMessage()).isEqualTo(INTERNAL_SERVER_ERROR_MESSAGE);
});

verifyGetRequest(
Expand Down Expand Up @@ -386,7 +386,7 @@ void getPayload_success() {
.satisfies(
response -> {
assertThat(response.isSuccess()).isTrue();
final BuilderPayload builderPayload = response.getPayload();
final BuilderPayload builderPayload = response.payload();
verifyBuilderPayloadResponse(builderPayload);
});
final Consumer<RecordedRequest> containsConsensusVersionHeader =
Expand Down Expand Up @@ -414,7 +414,7 @@ void getPayload_failures() {
.satisfies(
response -> {
assertThat(response.isFailure()).isTrue();
assertThat(response.getErrorMessage()).isEqualTo(missingSignatureError);
assertThat(response.errorMessage()).isEqualTo(missingSignatureError);
});

verifyPostRequest("/eth/v1/builder/blinded_blocks", signedBlindedBeaconBlockRequest);
Expand All @@ -427,7 +427,7 @@ void getPayload_failures() {
.satisfies(
response -> {
assertThat(response.isFailure()).isTrue();
assertThat(response.getErrorMessage()).isEqualTo(INTERNAL_SERVER_ERROR_MESSAGE);
assertThat(response.errorMessage()).isEqualTo(INTERNAL_SERVER_ERROR_MESSAGE);
});

verifyPostRequest("/eth/v1/builder/blinded_blocks", signedBlindedBeaconBlockRequest);
Expand All @@ -450,7 +450,7 @@ void getPayload_wrongVersion(final SpecContext specContext) {
.satisfies(
response -> {
assertThat(response.isSuccess()).isTrue();
final BuilderPayload builderPayload = response.getPayload();
final BuilderPayload builderPayload = response.payload();
verifyBuilderPayloadResponse(builderPayload);
});

Expand Down Expand Up @@ -515,7 +515,7 @@ private void verifySignedBuilderBidResponse(final SignedBuilderBid actual) {
schemaDefinitions.getSignedBuilderBidSchema().getJsonTypeDefinition());
try {
final SignedBuilderBid expected =
JsonUtil.parse(signedBuilderBidResponse, responseTypeDefinition).getData();
JsonUtil.parse(signedBuilderBidResponse, responseTypeDefinition).data();
assertThat(actual).isEqualTo(expected);
} catch (final JsonProcessingException ex) {
Assertions.fail(ex);
Expand All @@ -539,7 +539,7 @@ private void verifyBuilderPayloadResponse(final BuilderPayload actual) {
schemaDefinitions.getBuilderPayloadSchema().getJsonTypeDefinition());
try {
final BuilderPayload expected =
JsonUtil.parse(unblindedBuilderPayloadResponse, responseTypeDefinition).getData();
JsonUtil.parse(unblindedBuilderPayloadResponse, responseTypeDefinition).data();
assertThat(actual).isEqualTo(expected);
} catch (final JsonProcessingException ex) {
Assertions.fail(ex);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ void forkChoiceUpdated_shouldRoundtripWithMockedWebServer() throws Exception {
.matches(
forkChoiceUpdatedResultResponse ->
forkChoiceUpdatedResultResponse
.getPayload()
.payload()
.asInternalExecutionPayload()
.getPayloadStatus()
.equals(payloadStatusResponse));
Expand All @@ -203,7 +203,7 @@ public void exchangeCapabilities_shouldBuildRequestAndResponseSuccessfully() thr
eeClient.exchangeCapabilities(consensusCapabilities);
assertThat(response)
.succeedsWithin(1, TimeUnit.SECONDS)
.isEqualTo(new Response<>(executionCapabilities));
.isEqualTo(Response.fromPayloadReceivedAsJson(executionCapabilities));

final Map<String, Object> requestData = takeRequest();
verifyJsonRpcMethodCall(requestData, "engine_exchangeCapabilities");
Expand All @@ -224,7 +224,7 @@ public void getClientVersionV1_shouldBuildRequestAndResponseSuccessfully() throw
eeClient.getClientVersionV1(consensusClientVersion);
assertThat(response)
.succeedsWithin(1, TimeUnit.SECONDS)
.isEqualTo(new Response<>(List.of(executionClientVersion)));
.isEqualTo(Response.fromPayloadReceivedAsJson(List.of(executionClientVersion)));

final Map<String, Object> requestData = takeRequest();
verifyJsonRpcMethodCall(requestData, "engine_getClientVersionV1");
Expand Down Expand Up @@ -270,7 +270,7 @@ public void newPayloadV3_shouldBuildRequestAndResponseSuccessfully() {
.succeedsWithin(1, TimeUnit.SECONDS)
.matches(
response ->
response.getPayload().asInternalExecutionPayload().equals(payloadStatusResponse));
response.payload().asInternalExecutionPayload().equals(payloadStatusResponse));

final Map<String, Object> requestData = takeRequest();
verifyJsonRpcMethodCall(requestData, "engine_newPayloadV3");
Expand Down Expand Up @@ -333,7 +333,7 @@ public void newPayloadV4_shouldBuildRequestAndResponseSuccessfully() {
.succeedsWithin(1, TimeUnit.SECONDS)
.matches(
response ->
response.getPayload().asInternalExecutionPayload().equals(payloadStatusResponse));
response.payload().asInternalExecutionPayload().equals(payloadStatusResponse));

final Map<String, Object> requestData = takeRequest();
verifyJsonRpcMethodCall(requestData, "engine_newPayloadV4");
Expand Down Expand Up @@ -397,7 +397,7 @@ public void getBlobsV1_shouldBuildRequestAndResponseSuccessfully() {

assertThat(futureResponse)
.succeedsWithin(1, TimeUnit.SECONDS)
.matches(response -> response.getPayload().equals(blobsAndProofsV1));
.matches(response -> response.payload().equals(blobsAndProofsV1));

final Map<String, Object> requestData = takeRequest();
verifyJsonRpcMethodCall(requestData, "engine_getBlobsV1");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,13 @@ public static <K> K unwrapResponseOrThrow(
if (response.isFailure()) {
final String errorMessage =
String.format(
"Invalid remote response from the %s: %s", executionType, response.getErrorMessage());
if (response.getErrorMessage().contains("Failed to connect")) {
"Invalid remote response from the %s: %s", executionType, response.errorMessage());
if (response.errorMessage().contains("Failed to connect")) {
throw new InvalidRemoteResponseException(
errorMessage, new ConnectException(response.getErrorMessage()));
errorMessage, new ConnectException(response.errorMessage()));
}
throw new InvalidRemoteResponseException(errorMessage);
}
return response.getPayload();
return response.payload();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/*
* Copyright Consensys Software Inc., 2025
*
* 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.ethereum.executionclient.rest;

import static tech.pegasys.teku.infrastructure.http.HttpStatusCodes.SC_UNSUPPORTED_MEDIA_TYPE;

import java.io.IOException;
import okhttp3.Request;
import okhttp3.ResponseBody;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import tech.pegasys.teku.ethereum.executionclient.schema.Response;
import tech.pegasys.teku.infrastructure.async.SafeFuture;

public abstract class AbstractResponseHandler {
private static final Logger LOG = LogManager.getLogger();

abstract void handleFailure(final IOException exception);

abstract void handleResponse(final Request request, final okhttp3.Response response);

protected <T> boolean handleResponseError(
final Request request,
final okhttp3.Response response,
final SafeFuture<Response<T>> futureResponse) {
LOG.trace("{} {} {}", request.method(), request.url(), response.code());
if (response.isSuccessful()) {
return false;
}
try {
if (response.code() == SC_UNSUPPORTED_MEDIA_TYPE) {
futureResponse.complete(Response.fromUnsupportedMediaTypeError());
} else {
final String errorMessage = getErrorMessageForFailedResponse(response);
futureResponse.complete(Response.fromErrorMessage(errorMessage));
}
} catch (final Throwable ex) {
futureResponse.completeExceptionally(ex);
}
return true;
}

private String getErrorMessageForFailedResponse(final okhttp3.Response response)
throws IOException {
try (final ResponseBody responseBody = response.body()) {
if (bodyIsEmpty(responseBody)) {
return response.code() + ": " + response.message();
}
return responseBody.string();
}
}

protected boolean bodyIsEmpty(final ResponseBody responseBody) {
return responseBody == null || responseBody.contentLength() == 0;
}
}
Loading

0 comments on commit 095c767

Please sign in to comment.