From cf87b92071bbb7bb14a57463693321745ab2460e Mon Sep 17 00:00:00 2001 From: Paul Harris Date: Mon, 21 Oct 2024 07:02:50 +1000 Subject: [PATCH] Expanded VC API tests fixes #8756 Added test cases for VC block requests, and added a validation to the Attestation request test. These were the 2 VC cases where we now require that header to be specified or we will fail. There was another case in DSL for AT, but we'll see those quickly if we use it. Signed-off-by: Paul Harris --- .../SendSignedAttestationsRequestTest.java | 2 + .../handlers/SendSignedBlockRequestTest.java | 107 ++++++++++++++++++ 2 files changed, 109 insertions(+) create mode 100644 validator/remote/src/integration-test/java/tech/pegasys/teku/validator/remote/typedef/handlers/SendSignedBlockRequestTest.java diff --git a/validator/remote/src/integration-test/java/tech/pegasys/teku/validator/remote/typedef/handlers/SendSignedAttestationsRequestTest.java b/validator/remote/src/integration-test/java/tech/pegasys/teku/validator/remote/typedef/handlers/SendSignedAttestationsRequestTest.java index 52cee239506..6123a8dfe86 100644 --- a/validator/remote/src/integration-test/java/tech/pegasys/teku/validator/remote/typedef/handlers/SendSignedAttestationsRequestTest.java +++ b/validator/remote/src/integration-test/java/tech/pegasys/teku/validator/remote/typedef/handlers/SendSignedAttestationsRequestTest.java @@ -117,5 +117,7 @@ void shouldUseV2ApiWhenUseAttestationsV2ApisEnabled() assertThat(recordedRequest.getMethod()).isEqualTo("POST"); assertThat(recordedRequest.getPath()) .contains(ValidatorApiMethod.SEND_SIGNED_ATTESTATION_V2.getPath(emptyMap())); + assertThat(recordedRequest.getHeader(HEADER_CONSENSUS_VERSION)) + .isEqualTo(specMilestone.name().toLowerCase(Locale.ROOT)); } } diff --git a/validator/remote/src/integration-test/java/tech/pegasys/teku/validator/remote/typedef/handlers/SendSignedBlockRequestTest.java b/validator/remote/src/integration-test/java/tech/pegasys/teku/validator/remote/typedef/handlers/SendSignedBlockRequestTest.java new file mode 100644 index 00000000000..fd5817d4a8e --- /dev/null +++ b/validator/remote/src/integration-test/java/tech/pegasys/teku/validator/remote/typedef/handlers/SendSignedBlockRequestTest.java @@ -0,0 +1,107 @@ +/* + * 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.validator.remote.typedef.handlers; + +import static java.util.Collections.emptyMap; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static tech.pegasys.teku.infrastructure.http.HttpStatusCodes.SC_BAD_REQUEST; +import static tech.pegasys.teku.infrastructure.http.HttpStatusCodes.SC_INTERNAL_SERVER_ERROR; +import static tech.pegasys.teku.infrastructure.http.HttpStatusCodes.SC_OK; +import static tech.pegasys.teku.infrastructure.http.RestApiConstants.HEADER_CONSENSUS_VERSION; + +import java.util.Locale; +import okhttp3.mockwebserver.MockResponse; +import okhttp3.mockwebserver.RecordedRequest; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.TestTemplate; +import tech.pegasys.teku.api.exceptions.RemoteServiceNotAvailableException; +import tech.pegasys.teku.spec.SpecMilestone; +import tech.pegasys.teku.spec.TestSpecContext; +import tech.pegasys.teku.spec.datastructures.blocks.SignedBlockContainer; +import tech.pegasys.teku.spec.datastructures.validator.BroadcastValidationLevel; +import tech.pegasys.teku.spec.networks.Eth2Network; +import tech.pegasys.teku.validator.remote.apiclient.ValidatorApiMethod; +import tech.pegasys.teku.validator.remote.typedef.AbstractTypeDefRequestTestBase; + +@TestSpecContext( + milestone = { + SpecMilestone.BELLATRIX, + SpecMilestone.CAPELLA, + SpecMilestone.DENEB, + SpecMilestone.ELECTRA + }, + network = Eth2Network.MINIMAL) +public class SendSignedBlockRequestTest extends AbstractTypeDefRequestTestBase { + private SignedBlockContainer block; + private SendSignedBlockRequest request; + + @BeforeEach + public void setup() { + request = new SendSignedBlockRequest(spec, mockWebServer.url("/"), okHttpClient, true); + this.block = + specMilestone.isGreaterThanOrEqualTo(SpecMilestone.DENEB) + ? dataStructureUtil.randomSignedBlockContents() + : dataStructureUtil.randomSignedBeaconBlock(); + } + + @TestTemplate + public void shouldIncludeConsensusHeaderInJsonRequest() throws InterruptedException { + request = new SendSignedBlockRequest(spec, mockWebServer.url("/"), okHttpClient, false); + mockWebServer.enqueue(new MockResponse().setResponseCode(SC_OK)); + + request.submit(block, BroadcastValidationLevel.NOT_REQUIRED); + + final RecordedRequest recordedRequest = mockWebServer.takeRequest(); + assertThat(recordedRequest.getMethod()).isEqualTo("POST"); + assertThat(recordedRequest.getPath()) + .contains(ValidatorApiMethod.SEND_SIGNED_BLOCK_V2.getPath(emptyMap())); + assertThat(recordedRequest.getHeader(HEADER_CONSENSUS_VERSION)) + .isEqualTo(specMilestone.name().toLowerCase(Locale.ROOT)); + assertThat(recordedRequest.getHeader("Content-Type")).contains("json"); + } + + @TestTemplate + public void shouldIncludeConsensusHeaderInSszRequest() throws InterruptedException { + mockWebServer.enqueue(new MockResponse().setResponseCode(SC_OK)); + + request.submit(block, BroadcastValidationLevel.NOT_REQUIRED); + + final RecordedRequest recordedRequest = mockWebServer.takeRequest(); + assertThat(recordedRequest.getMethod()).isEqualTo("POST"); + assertThat(recordedRequest.getPath()) + .contains(ValidatorApiMethod.SEND_SIGNED_BLOCK_V2.getPath(emptyMap())); + assertThat(recordedRequest.getHeader(HEADER_CONSENSUS_VERSION)) + .isEqualTo(specMilestone.name().toLowerCase(Locale.ROOT)); + assertThat(recordedRequest.getHeader("Content-Type")).contains("octet"); + } + + @TestTemplate + void handle500() { + mockWebServer.enqueue(new MockResponse().setResponseCode(SC_INTERNAL_SERVER_ERROR)); + assertThatThrownBy(() -> request.submit(block, BroadcastValidationLevel.NOT_REQUIRED)) + .isInstanceOf(RemoteServiceNotAvailableException.class); + } + + @TestTemplate + void handle400() { + mockWebServer.enqueue( + new MockResponse() + .setResponseCode(SC_BAD_REQUEST) + .setBody("{\"code\": 400,\"message\": \"z\"}")); + assertThatThrownBy(() -> request.submit(block, BroadcastValidationLevel.NOT_REQUIRED)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageStartingWith("Invalid params response from Beacon Node API"); + } +}