diff --git a/data/beaconrestapi/src/integration-test/java/tech/pegasys/teku/beaconrestapi/v1/validator/PostSyncDutiesIntegrationTest.java b/data/beaconrestapi/src/integration-test/java/tech/pegasys/teku/beaconrestapi/v1/validator/PostSyncDutiesIntegrationTest.java index 61983e41efe..7fda607c1bd 100644 --- a/data/beaconrestapi/src/integration-test/java/tech/pegasys/teku/beaconrestapi/v1/validator/PostSyncDutiesIntegrationTest.java +++ b/data/beaconrestapi/src/integration-test/java/tech/pegasys/teku/beaconrestapi/v1/validator/PostSyncDutiesIntegrationTest.java @@ -15,8 +15,10 @@ import static org.assertj.core.api.AssertionsForClassTypes.assertThat; import static org.mockito.Mockito.when; +import static tech.pegasys.teku.ethereum.json.types.validator.SyncCommitteeDutiesBuilder.SYNC_COMMITTEE_DUTIES_TYPE; import static tech.pegasys.teku.infrastructure.http.HttpStatusCodes.SC_BAD_REQUEST; import static tech.pegasys.teku.infrastructure.http.HttpStatusCodes.SC_OK; +import static tech.pegasys.teku.infrastructure.json.JsonUtil.parse; import static tech.pegasys.teku.infrastructure.unsigned.UInt64.ONE; import it.unimi.dsi.fastutil.ints.IntList; @@ -27,8 +29,6 @@ import okhttp3.Response; import org.assertj.core.api.Assertions; import org.junit.jupiter.api.Test; -import tech.pegasys.teku.api.response.v1.validator.PostSyncDutiesResponse; -import tech.pegasys.teku.api.schema.BLSPubKey; import tech.pegasys.teku.beacon.sync.events.SyncState; import tech.pegasys.teku.beaconrestapi.AbstractDataBackedRestAPIIntegrationTest; import tech.pegasys.teku.beaconrestapi.handlers.v1.validator.PostSyncDuties; @@ -68,11 +68,9 @@ void shouldGetSyncCommitteeDuties() throws IOException { post(PostSyncDuties.ROUTE.replace("{epoch}", "1"), jsonProvider.objectToJSON(validators)); Assertions.assertThat(response.code()).isEqualTo(SC_OK); - final PostSyncDutiesResponse dutiesResponse = - jsonProvider.jsonToObject(response.body().string(), PostSyncDutiesResponse.class); - assertThat(dutiesResponse.data.get(0)) - .isEqualTo( - new tech.pegasys.teku.api.response.v1.validator.SyncCommitteeDuty( - new BLSPubKey(VALIDATOR_KEYS.get(1).getPublicKey()), ONE, IntSet.of(11))); + final SyncCommitteeDuties committeeDuties = + parse(response.body().string(), SYNC_COMMITTEE_DUTIES_TYPE); + assertThat(committeeDuties.getDuties().get(0)) + .isEqualTo(new SyncCommitteeDuty(VALIDATOR_KEYS.get(1).getPublicKey(), 1, IntSet.of(11))); } } diff --git a/data/serializer/src/main/java/tech/pegasys/teku/api/response/v1/validator/PostSyncDutiesResponse.java b/data/serializer/src/main/java/tech/pegasys/teku/api/response/v1/validator/PostSyncDutiesResponse.java deleted file mode 100644 index 90cf84c4154..00000000000 --- a/data/serializer/src/main/java/tech/pegasys/teku/api/response/v1/validator/PostSyncDutiesResponse.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright Consensys Software Inc., 2022 - * - * 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.api.response.v1.validator; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.google.common.base.MoreObjects; -import java.util.List; -import java.util.Objects; - -public class PostSyncDutiesResponse { - public final List data; - - @JsonProperty("execution_optimistic") - public final boolean executionOptimistic; - - @JsonCreator - public PostSyncDutiesResponse( - @JsonProperty("data") final List data, - @JsonProperty("execution_optimistic") final boolean executionOptimistic) { - this.data = data; - this.executionOptimistic = executionOptimistic; - } - - @Override - public boolean equals(final Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - final PostSyncDutiesResponse that = (PostSyncDutiesResponse) o; - return Objects.equals(data, that.data); - } - - @Override - public int hashCode() { - return Objects.hash(data); - } - - @Override - public String toString() { - return MoreObjects.toStringHelper(this).add("data", data).toString(); - } -} diff --git a/data/serializer/src/main/java/tech/pegasys/teku/api/response/v1/validator/SyncCommitteeDuty.java b/data/serializer/src/main/java/tech/pegasys/teku/api/response/v1/validator/SyncCommitteeDuty.java deleted file mode 100644 index 477a6d4354b..00000000000 --- a/data/serializer/src/main/java/tech/pegasys/teku/api/response/v1/validator/SyncCommitteeDuty.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright Consensys Software Inc., 2022 - * - * 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.api.response.v1.validator; - -import static tech.pegasys.teku.api.schema.SchemaConstants.EXAMPLE_PUBKEY; -import static tech.pegasys.teku.api.schema.SchemaConstants.EXAMPLE_UINT64; -import static tech.pegasys.teku.api.schema.SchemaConstants.PATTERN_PUBKEY; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; -import io.swagger.v3.oas.annotations.media.ArraySchema; -import io.swagger.v3.oas.annotations.media.Schema; -import java.util.Objects; -import java.util.Set; -import java.util.stream.Collectors; -import tech.pegasys.teku.api.schema.BLSPubKey; -import tech.pegasys.teku.infrastructure.unsigned.UInt64; - -public class SyncCommitteeDuty { - @JsonProperty("pubkey") - @Schema( - type = "string", - pattern = PATTERN_PUBKEY, - example = EXAMPLE_PUBKEY, - description = - "The validator's BLS public key, uniquely identifying them. " - + "48-bytes, hex encoded with 0x prefix, case insensitive.") - public final BLSPubKey pubkey; - - @JsonProperty("validator_index") - @Schema( - type = "string", - example = EXAMPLE_UINT64, - description = "Index of validator in validator registry") - public final UInt64 validatorIndex; - - @JsonProperty("validator_sync_committee_indices") - @ArraySchema( - schema = - @Schema(type = "string", example = EXAMPLE_UINT64, description = "The committee index")) - public final Set committeeIndices; - - @JsonCreator - public SyncCommitteeDuty( - @JsonProperty("pubkey") final BLSPubKey pubkey, - @JsonProperty("validator_index") final UInt64 validatorIndex, - @JsonProperty("validator_sync_committee_indices") final Set committeeIndices) { - this.pubkey = pubkey; - this.validatorIndex = validatorIndex; - this.committeeIndices = - committeeIndices.stream().map(UInt64::valueOf).collect(Collectors.toSet()); - } - - @Override - public boolean equals(final Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - final SyncCommitteeDuty that = (SyncCommitteeDuty) o; - return Objects.equals(pubkey, that.pubkey) - && Objects.equals(validatorIndex, that.validatorIndex) - && Objects.equals(committeeIndices, that.committeeIndices); - } - - @Override - public int hashCode() { - return Objects.hash(pubkey, validatorIndex, committeeIndices); - } -} diff --git a/validator/remote/src/integration-test/java/tech/pegasys/teku/validator/remote/typedef/OkHttpValidatorTypeDefClientTest.java b/validator/remote/src/integration-test/java/tech/pegasys/teku/validator/remote/typedef/OkHttpValidatorTypeDefClientTest.java index ed14433720a..7d588896af6 100644 --- a/validator/remote/src/integration-test/java/tech/pegasys/teku/validator/remote/typedef/OkHttpValidatorTypeDefClientTest.java +++ b/validator/remote/src/integration-test/java/tech/pegasys/teku/validator/remote/typedef/OkHttpValidatorTypeDefClientTest.java @@ -20,17 +20,20 @@ import static org.assertj.core.api.Assumptions.assumeThat; import static tech.pegasys.teku.ethereum.json.types.beacon.StateValidatorDataBuilder.STATE_VALIDATORS_RESPONSE_TYPE; import static tech.pegasys.teku.ethereum.json.types.validator.AttesterDutiesBuilder.ATTESTER_DUTIES_RESPONSE_TYPE; +import static tech.pegasys.teku.ethereum.json.types.validator.SyncCommitteeDutiesBuilder.SYNC_COMMITTEE_DUTIES_TYPE; import static tech.pegasys.teku.infrastructure.http.HttpStatusCodes.SC_BAD_REQUEST; import static tech.pegasys.teku.infrastructure.http.HttpStatusCodes.SC_METHOD_NOT_ALLOWED; import static tech.pegasys.teku.infrastructure.http.HttpStatusCodes.SC_NOT_FOUND; import static tech.pegasys.teku.infrastructure.http.HttpStatusCodes.SC_NO_CONTENT; import static tech.pegasys.teku.infrastructure.http.HttpStatusCodes.SC_OK; import static tech.pegasys.teku.infrastructure.json.JsonUtil.serialize; +import static tech.pegasys.teku.infrastructure.unsigned.UInt64.ONE; import static tech.pegasys.teku.spec.config.SpecConfig.FAR_FUTURE_EPOCH; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import it.unimi.dsi.fastutil.ints.IntList; +import it.unimi.dsi.fastutil.ints.IntSet; import java.util.List; import java.util.Optional; import okhttp3.mockwebserver.MockResponse; @@ -44,6 +47,8 @@ import tech.pegasys.teku.ethereum.json.types.beacon.StateValidatorData; import tech.pegasys.teku.ethereum.json.types.validator.AttesterDuties; import tech.pegasys.teku.ethereum.json.types.validator.AttesterDuty; +import tech.pegasys.teku.ethereum.json.types.validator.SyncCommitteeDuties; +import tech.pegasys.teku.ethereum.json.types.validator.SyncCommitteeDuty; import tech.pegasys.teku.infrastructure.ssz.SszDataAssert; import tech.pegasys.teku.infrastructure.ssz.SszList; import tech.pegasys.teku.infrastructure.unsigned.UInt64; @@ -94,9 +99,9 @@ void blockProductionFallbacksToNonBlindedFlowIfBlindedEndpointIsNotAvailable() final BlockContainer blockContainer; if (specMilestone.isGreaterThanOrEqualTo(SpecMilestone.DENEB)) { - blockContainer = dataStructureUtil.randomBlockContents(UInt64.ONE); + blockContainer = dataStructureUtil.randomBlockContents(ONE); } else { - blockContainer = dataStructureUtil.randomBeaconBlock(UInt64.ONE); + blockContainer = dataStructureUtil.randomBeaconBlock(ONE); } mockWebServer.enqueue( @@ -159,7 +164,7 @@ void publishesBlindedBlockJsonEncoded() throws InterruptedException, JsonProcess final String expectedRequest = serialize( signedBeaconBlock, - spec.atSlot(UInt64.ONE) + spec.atSlot(ONE) .getSchemaDefinitions() .getSignedBlindedBlockContainerSchema() .getJsonTypeDefinition()); @@ -189,8 +194,8 @@ void getsSyncingStatus() { assertThat(result) .satisfies( syncingStatus -> { - assertThat(syncingStatus.getHeadSlot()).isEqualTo(UInt64.ONE); - assertThat(syncingStatus.getSyncDistance()).isEqualTo(UInt64.ONE); + assertThat(syncingStatus.getHeadSlot()).isEqualTo(ONE); + assertThat(syncingStatus.getSyncDistance()).isEqualTo(ONE); assertThat(syncingStatus.isSyncing()).isTrue(); assertThat(syncingStatus.getIsOptimistic()).hasValue(true); }); @@ -415,6 +420,36 @@ private StateValidatorData generateStateValidatorData() { validator); } + @TestTemplate + public void postSyncDuties_WhenSuccess_ReturnsResponse() + throws JsonProcessingException, InterruptedException { + final List duties = + List.of( + new SyncCommitteeDuty( + dataStructureUtil.randomPublicKey(), + dataStructureUtil.randomValidatorIndex().intValue(), + IntSet.of(1, 2))); + final SyncCommitteeDuties response = new SyncCommitteeDuties(true, duties); + + final String body = serialize(response, SYNC_COMMITTEE_DUTIES_TYPE); + mockWebServer.enqueue(new MockResponse().setResponseCode(SC_OK).setBody(body)); + + final UInt64 epoch = ONE; + final IntList validatorIndices = IntList.of(1, 2); + Optional result = + okHttpValidatorTypeDefClient.postSyncDuties(epoch, validatorIndices); + + final RecordedRequest recordedRequest = mockWebServer.takeRequest(); + assertThat(recordedRequest.getPath()).isEqualTo("/eth/v1/validator/duties/sync/" + epoch); + assertThat(recordedRequest.getMethod()).isEqualTo("POST"); + assertThat(recordedRequest.getHeader("Content-Type")).isEqualTo(JSON_CONTENT_TYPE); + assertThat(recordedRequest.getBody().readByteArray()) + .isEqualTo("[\"1\",\"2\"]".getBytes(UTF_8)); + + assertThat(result).isPresent(); + assertThat(result.get()).isEqualTo(response); + } + @TestTemplate public void postAttesterDuties_WhenSuccess_ReturnsResponse() throws JsonProcessingException, InterruptedException { @@ -425,7 +460,7 @@ public void postAttesterDuties_WhenSuccess_ReturnsResponse() final String body = serialize(response, ATTESTER_DUTIES_RESPONSE_TYPE); mockWebServer.enqueue(new MockResponse().setResponseCode(SC_OK).setBody(body)); - final UInt64 epoch = UInt64.ONE; + final UInt64 epoch = ONE; final IntList validatorIndices = IntList.of(1, 2); Optional result = okHttpValidatorTypeDefClient.postAttesterDuties(epoch, validatorIndices); diff --git a/validator/remote/src/main/java/tech/pegasys/teku/validator/remote/RemoteValidatorApiHandler.java b/validator/remote/src/main/java/tech/pegasys/teku/validator/remote/RemoteValidatorApiHandler.java index 2eace4705bf..13f93813165 100644 --- a/validator/remote/src/main/java/tech/pegasys/teku/validator/remote/RemoteValidatorApiHandler.java +++ b/validator/remote/src/main/java/tech/pegasys/teku/validator/remote/RemoteValidatorApiHandler.java @@ -19,7 +19,6 @@ import com.google.common.base.Throwables; import it.unimi.dsi.fastutil.ints.IntCollection; -import it.unimi.dsi.fastutil.ints.IntOpenHashSet; import java.time.Duration; import java.util.ArrayList; import java.util.Collection; @@ -39,7 +38,6 @@ import tech.pegasys.teku.api.migrated.ValidatorLivenessAtEpoch; import tech.pegasys.teku.api.response.v1.beacon.PostDataFailureResponse; import tech.pegasys.teku.api.response.v1.beacon.ValidatorStatus; -import tech.pegasys.teku.api.response.v1.validator.PostSyncDutiesResponse; import tech.pegasys.teku.api.response.v1.validator.PostValidatorLivenessResponse; import tech.pegasys.teku.api.schema.altair.ContributionAndProof; import tech.pegasys.teku.bls.BLSPublicKey; @@ -49,7 +47,6 @@ import tech.pegasys.teku.ethereum.json.types.validator.BeaconCommitteeSelectionProof; import tech.pegasys.teku.ethereum.json.types.validator.ProposerDuties; import tech.pegasys.teku.ethereum.json.types.validator.SyncCommitteeDuties; -import tech.pegasys.teku.ethereum.json.types.validator.SyncCommitteeDuty; import tech.pegasys.teku.ethereum.json.types.validator.SyncCommitteeSelectionProof; import tech.pegasys.teku.infrastructure.async.AsyncRunner; import tech.pegasys.teku.infrastructure.async.ExceptionThrowingRunnable; @@ -213,25 +210,7 @@ public SafeFuture> getAttestationDuties( @Override public SafeFuture> getSyncCommitteeDuties( final UInt64 epoch, final IntCollection validatorIndices) { - return sendRequest( - () -> - apiClient - .getSyncCommitteeDuties(epoch, validatorIndices) - .map(this::responseToSyncCommitteeDuties)); - } - - private SyncCommitteeDuties responseToSyncCommitteeDuties(final PostSyncDutiesResponse response) { - return new SyncCommitteeDuties( - response.executionOptimistic, - response.data.stream() - .map( - duty -> - new SyncCommitteeDuty( - duty.pubkey.asBLSPublicKey(), - duty.validatorIndex.intValue(), - IntOpenHashSet.toSet( - duty.committeeIndices.stream().mapToInt(UInt64::intValue)))) - .toList()); + return sendRequest(() -> typeDefClient.postSyncDuties(epoch, validatorIndices)); } @Override diff --git a/validator/remote/src/main/java/tech/pegasys/teku/validator/remote/apiclient/OkHttpValidatorRestApiClient.java b/validator/remote/src/main/java/tech/pegasys/teku/validator/remote/apiclient/OkHttpValidatorRestApiClient.java index 55de82c9008..6a2a7565f0f 100644 --- a/validator/remote/src/main/java/tech/pegasys/teku/validator/remote/apiclient/OkHttpValidatorRestApiClient.java +++ b/validator/remote/src/main/java/tech/pegasys/teku/validator/remote/apiclient/OkHttpValidatorRestApiClient.java @@ -20,7 +20,6 @@ import static tech.pegasys.teku.validator.remote.apiclient.ValidatorApiMethod.GET_GENESIS; import static tech.pegasys.teku.validator.remote.apiclient.ValidatorApiMethod.GET_PROPOSER_DUTIES; import static tech.pegasys.teku.validator.remote.apiclient.ValidatorApiMethod.GET_SYNC_COMMITTEE_CONTRIBUTION; -import static tech.pegasys.teku.validator.remote.apiclient.ValidatorApiMethod.GET_SYNC_COMMITTEE_DUTIES; import static tech.pegasys.teku.validator.remote.apiclient.ValidatorApiMethod.GET_VALIDATORS; import static tech.pegasys.teku.validator.remote.apiclient.ValidatorApiMethod.PREPARE_BEACON_PROPOSER; import static tech.pegasys.teku.validator.remote.apiclient.ValidatorApiMethod.SEND_CONTRIBUTION_AND_PROOF; @@ -37,7 +36,6 @@ import java.io.IOException; import java.io.UncheckedIOException; import java.net.URI; -import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -62,7 +60,6 @@ import tech.pegasys.teku.api.response.v1.validator.GetAggregatedAttestationResponse; import tech.pegasys.teku.api.response.v1.validator.GetProposerDutiesResponse; import tech.pegasys.teku.api.response.v1.validator.GetSyncCommitteeContributionResponse; -import tech.pegasys.teku.api.response.v1.validator.PostSyncDutiesResponse; import tech.pegasys.teku.api.response.v1.validator.PostValidatorLivenessResponse; import tech.pegasys.teku.api.schema.Attestation; import tech.pegasys.teku.api.schema.SignedAggregateAndProof; @@ -212,16 +209,6 @@ public Optional sendSyncCommitteeMessages( jsonProvider, PostDataFailureResponse.class)); } - @Override - public Optional getSyncCommitteeDuties( // todo remove - final UInt64 epoch, final Collection validatorIndices) { - return post( - GET_SYNC_COMMITTEE_DUTIES, - Map.of("epoch", epoch.toString()), - validatorIndices.stream().map(UInt64::valueOf).toList(), - createHandler(PostSyncDutiesResponse.class)); - } - @Override public void subscribeToSyncCommitteeSubnets( final List subnetSubscriptions) { diff --git a/validator/remote/src/main/java/tech/pegasys/teku/validator/remote/apiclient/ValidatorRestApiClient.java b/validator/remote/src/main/java/tech/pegasys/teku/validator/remote/apiclient/ValidatorRestApiClient.java index cd7f5ec83d6..72235d17381 100644 --- a/validator/remote/src/main/java/tech/pegasys/teku/validator/remote/apiclient/ValidatorRestApiClient.java +++ b/validator/remote/src/main/java/tech/pegasys/teku/validator/remote/apiclient/ValidatorRestApiClient.java @@ -13,7 +13,6 @@ package tech.pegasys.teku.validator.remote.apiclient; -import java.util.Collection; import java.util.List; import java.util.Optional; import java.util.Set; @@ -22,7 +21,6 @@ import tech.pegasys.teku.api.response.v1.beacon.PostDataFailureResponse; import tech.pegasys.teku.api.response.v1.beacon.ValidatorResponse; import tech.pegasys.teku.api.response.v1.validator.GetProposerDutiesResponse; -import tech.pegasys.teku.api.response.v1.validator.PostSyncDutiesResponse; import tech.pegasys.teku.api.response.v1.validator.PostValidatorLivenessResponse; import tech.pegasys.teku.api.schema.Attestation; import tech.pegasys.teku.api.schema.SignedAggregateAndProof; @@ -60,9 +58,6 @@ Optional sendAggregateAndProofs( Optional sendSyncCommitteeMessages( List syncCommitteeMessages); - Optional getSyncCommitteeDuties( - UInt64 epoch, Collection validatorIndices); - void subscribeToSyncCommitteeSubnets(List subnetSubscriptions); void sendContributionAndProofs( diff --git a/validator/remote/src/main/java/tech/pegasys/teku/validator/remote/typedef/OkHttpValidatorTypeDefClient.java b/validator/remote/src/main/java/tech/pegasys/teku/validator/remote/typedef/OkHttpValidatorTypeDefClient.java index c8e64fe7ec2..dd2942bf816 100644 --- a/validator/remote/src/main/java/tech/pegasys/teku/validator/remote/typedef/OkHttpValidatorTypeDefClient.java +++ b/validator/remote/src/main/java/tech/pegasys/teku/validator/remote/typedef/OkHttpValidatorTypeDefClient.java @@ -26,6 +26,7 @@ import tech.pegasys.teku.ethereum.json.types.validator.AttesterDuties; import tech.pegasys.teku.ethereum.json.types.validator.BeaconCommitteeSelectionProof; import tech.pegasys.teku.ethereum.json.types.validator.ProposerDuties; +import tech.pegasys.teku.ethereum.json.types.validator.SyncCommitteeDuties; import tech.pegasys.teku.ethereum.json.types.validator.SyncCommitteeSelectionProof; import tech.pegasys.teku.infrastructure.ssz.SszList; import tech.pegasys.teku.infrastructure.unsigned.UInt64; @@ -47,6 +48,7 @@ import tech.pegasys.teku.validator.remote.typedef.handlers.GetSyncingStatusRequest; import tech.pegasys.teku.validator.remote.typedef.handlers.PostAttesterDutiesRequest; import tech.pegasys.teku.validator.remote.typedef.handlers.PostStateValidatorsRequest; +import tech.pegasys.teku.validator.remote.typedef.handlers.PostSyncDutiesRequest; import tech.pegasys.teku.validator.remote.typedef.handlers.ProduceBlockRequest; import tech.pegasys.teku.validator.remote.typedef.handlers.RegisterValidatorsRequest; import tech.pegasys.teku.validator.remote.typedef.handlers.SendSignedBlockRequest; @@ -64,6 +66,7 @@ public class OkHttpValidatorTypeDefClient extends OkHttpValidatorMinimalTypeDefC private final GetStateValidatorsRequest getStateValidatorsRequest; private final PostAttesterDutiesRequest postAttesterDutiesRequest; private final PostStateValidatorsRequest postStateValidatorsRequest; + private final PostSyncDutiesRequest postSyncDutiesRequest; private final SendSignedBlockRequest sendSignedBlockRequest; private final RegisterValidatorsRequest registerValidatorsRequest; private final CreateAttestationDataRequest createAttestationDataRequest; @@ -83,6 +86,7 @@ public OkHttpValidatorTypeDefClient( this.getProposerDutiesRequest = new GetProposerDutiesRequest(baseEndpoint, okHttpClient); this.getStateValidatorsRequest = new GetStateValidatorsRequest(baseEndpoint, okHttpClient); this.postStateValidatorsRequest = new PostStateValidatorsRequest(baseEndpoint, okHttpClient); + this.postSyncDutiesRequest = new PostSyncDutiesRequest(baseEndpoint, okHttpClient); this.postAttesterDutiesRequest = new PostAttesterDutiesRequest(baseEndpoint, okHttpClient); this.sendSignedBlockRequest = new SendSignedBlockRequest(spec, baseEndpoint, okHttpClient, preferSszBlockEncoding); @@ -124,6 +128,11 @@ public Optional> postStateValidators(final List .map(ObjectAndMetaData::getData); } + public Optional postSyncDuties( + final UInt64 epoch, final Collection validatorIndices) { + return postSyncDutiesRequest.postSyncDuties(epoch, validatorIndices); + } + public Optional postAttesterDuties( final UInt64 epoch, final Collection validatorIndices) { return postAttesterDutiesRequest.postAttesterDuties(epoch, validatorIndices); diff --git a/validator/remote/src/main/java/tech/pegasys/teku/validator/remote/typedef/handlers/PostSyncDutiesRequest.java b/validator/remote/src/main/java/tech/pegasys/teku/validator/remote/typedef/handlers/PostSyncDutiesRequest.java new file mode 100644 index 00000000000..36916748bfe --- /dev/null +++ b/validator/remote/src/main/java/tech/pegasys/teku/validator/remote/typedef/handlers/PostSyncDutiesRequest.java @@ -0,0 +1,44 @@ +/* + * 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 tech.pegasys.teku.ethereum.json.types.validator.SyncCommitteeDutiesBuilder.SYNC_COMMITTEE_DUTIES_TYPE; +import static tech.pegasys.teku.infrastructure.json.types.CoreTypes.INTEGER_TYPE; +import static tech.pegasys.teku.infrastructure.json.types.DeserializableTypeDefinition.listOf; +import static tech.pegasys.teku.validator.remote.apiclient.ValidatorApiMethod.GET_SYNC_COMMITTEE_DUTIES; + +import java.util.Collection; +import java.util.Map; +import java.util.Optional; +import okhttp3.HttpUrl; +import okhttp3.OkHttpClient; +import tech.pegasys.teku.ethereum.json.types.validator.SyncCommitteeDuties; +import tech.pegasys.teku.infrastructure.unsigned.UInt64; +import tech.pegasys.teku.validator.remote.typedef.ResponseHandler; + +public class PostSyncDutiesRequest extends AbstractTypeDefRequest { + public PostSyncDutiesRequest(final HttpUrl baseEndpoint, final OkHttpClient okHttpClient) { + super(baseEndpoint, okHttpClient); + } + + public Optional postSyncDuties( + final UInt64 epoch, final Collection validatorIndices) { + return postJson( + GET_SYNC_COMMITTEE_DUTIES, + Map.of("epoch", epoch.toString()), + validatorIndices.stream().toList(), + listOf(INTEGER_TYPE, 1), + new ResponseHandler<>(SYNC_COMMITTEE_DUTIES_TYPE)); + } +}