Skip to content

Commit

Permalink
7390 block v2 fallback (Consensys#7637)
Browse files Browse the repository at this point in the history
* Add block v2 fallback
  • Loading branch information
mehdi-aouadi authored Nov 2, 2023
1 parent 451573b commit bb895e2
Show file tree
Hide file tree
Showing 7 changed files with 84 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,12 @@ public SafeFuture<BeaconBlockAndState> createNewUnsignedBlock(
final Bytes32 parentBlockSigningRoot,
final Consumer<BeaconBlockBodyBuilder> bodyBuilder) {
return createNewUnsignedBlock(
newSlot, proposerIndex, blockSlotState, parentBlockSigningRoot, bodyBuilder, true);
newSlot,
proposerIndex,
blockSlotState,
parentBlockSigningRoot,
bodyBuilder,
ValidatorsUtil.DEFAULT_PRODUCE_BLINDED_BLOCK);
}

private SafeFuture<? extends BeaconBlockBody> createBeaconBlockBody(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@

public class ValidatorsUtil {

public static final boolean DEFAULT_PRODUCE_BLINDED_BLOCK = true;
private final SpecConfig specConfig;
private final MiscHelpers miscHelpers;
private final BeaconStateAccessors beaconStateAccessors;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ private SafeFuture<BLSSignature> createRandaoReveal(final ForkInfo forkInfo) {

private SafeFuture<Optional<BlockContainer>> createUnsignedBlock(
final BLSSignature randaoReveal) {
if (this.blockV3Enabled) {
if (blockV3Enabled) {
return validatorApiChannel.createUnsignedBlock(slot, randaoReveal, validator.getGraffiti());
} else {
return validatorApiChannel.createUnsignedBlock(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assumptions.assumeThat;
import static tech.pegasys.teku.infrastructure.unsigned.UInt64.ONE;
import static tech.pegasys.teku.spec.SpecMilestone.DENEB;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
Expand Down Expand Up @@ -296,6 +298,44 @@ void registerValidators_fallbacksToJsonIfSszNotSupported() throws InterruptedExc
verifyRegisterValidatorsPostRequest(mockWebServer.takeRequest(), JSON_CONTENT_TYPE);
}

@TestTemplate
void blockV3ShouldFallbacksToBlockV2WhenNotFound()
throws JsonProcessingException, InterruptedException {
mockWebServer.enqueue(new MockResponse().setResponseCode(404));

final BlockContainer blockContainer;
if (specMilestone.isGreaterThanOrEqualTo(DENEB)) {
blockContainer = dataStructureUtil.randomBlindedBlockContents(ONE);
} else {
blockContainer = dataStructureUtil.randomBlindedBeaconBlock(ONE);
}

mockWebServer.enqueue(
new MockResponse()
.setResponseCode(200)
.setBody(
"{\"data\": "
+ serializeBlockContainer(blockContainer)
+ ", \"version\": \""
+ specMilestone
+ "\"}"));

final Optional<BlockContainer> producedBlock =
okHttpValidatorTypeDefClient.createUnsignedBlock(
dataStructureUtil.randomUInt64(),
dataStructureUtil.randomSignature(),
Optional.empty());

assertThat(producedBlock).hasValue(blockContainer);

assertThat(mockWebServer.getRequestCount()).isEqualTo(2);

final RecordedRequest firstRequest = mockWebServer.takeRequest();
assertThat(firstRequest.getPath()).startsWith("/eth/v3/validator/blocks");
final RecordedRequest secondRequest = mockWebServer.takeRequest();
assertThat(secondRequest.getPath()).startsWith("/eth/v1/validator/blinded_blocks");
}

private void verifyRegisterValidatorsPostRequest(
final RecordedRequest recordedRequest, final String expectedContentType) {
assertThat(recordedRequest.getPath()).isEqualTo("/eth/v1/validator/register_validator");
Expand All @@ -315,6 +355,9 @@ private void assertJsonEquals(final String actual, final String expected) {
private String serializeBlockContainer(final BlockContainer blockContainer)
throws JsonProcessingException {
return JsonUtil.serialize(
blockContainer, schemaDefinitions.getBlockContainerSchema().getJsonTypeDefinition());
blockContainer,
blockContainer.isBlinded()
? schemaDefinitions.getBlindedBlockContainerSchema().getJsonTypeDefinition()
: schemaDefinitions.getBlockContainerSchema().getJsonTypeDefinition());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/*
* Copyright Consensys Software Inc., 2023
*
* 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;

public class BlockProductionV3FailedException extends RuntimeException {}
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import tech.pegasys.teku.spec.datastructures.builder.SignedValidatorRegistration;
import tech.pegasys.teku.spec.datastructures.genesis.GenesisData;
import tech.pegasys.teku.spec.datastructures.operations.AttestationData;
import tech.pegasys.teku.spec.logic.common.util.ValidatorsUtil;
import tech.pegasys.teku.validator.api.SendSignedBlockResult;
import tech.pegasys.teku.validator.api.required.SyncingStatus;
import tech.pegasys.teku.validator.remote.typedef.handlers.CreateAttestationDataRequest;
Expand Down Expand Up @@ -111,7 +112,13 @@ public Optional<BlockContainer> createUnsignedBlock(
final UInt64 slot, final BLSSignature randaoReveal, final Optional<Bytes32> graffiti) {
final ProduceBlockRequest produceBlockRequest =
new ProduceBlockRequest(baseEndpoint, okHttpClient, spec, slot, preferSszBlockEncoding);
return produceBlockRequest.createUnsignedBlock(randaoReveal, graffiti);
try {
return produceBlockRequest.createUnsignedBlock(randaoReveal, graffiti);
} catch (final BlockProductionV3FailedException ex) {
LOG.warn("Produce Block V3 request failed at slot {}. Retrying with Block V2", slot);
return createUnsignedBlock(
slot, randaoReveal, graffiti, ValidatorsUtil.DEFAULT_PRODUCE_BLINDED_BLOCK);
}
}

public void registerValidators(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

package tech.pegasys.teku.validator.remote.typedef.handlers;

import static tech.pegasys.teku.infrastructure.http.HttpStatusCodes.SC_NOT_FOUND;
import static tech.pegasys.teku.infrastructure.http.HttpStatusCodes.SC_OK;
import static tech.pegasys.teku.infrastructure.http.RestApiConstants.CONSENSUS_BLOCK_VALUE;
import static tech.pegasys.teku.infrastructure.http.RestApiConstants.EXECUTION_PAYLOAD_BLINDED;
Expand Down Expand Up @@ -45,6 +46,7 @@
import tech.pegasys.teku.spec.SpecMilestone;
import tech.pegasys.teku.spec.datastructures.blocks.BlockContainer;
import tech.pegasys.teku.spec.datastructures.blocks.BlockContainerSchema;
import tech.pegasys.teku.validator.remote.typedef.BlockProductionV3FailedException;
import tech.pegasys.teku.validator.remote.typedef.ResponseHandler;

public class ProduceBlockRequest extends AbstractTypeDefRequest {
Expand All @@ -56,7 +58,6 @@ public class ProduceBlockRequest extends AbstractTypeDefRequest {
private final BlockContainerSchema<BlockContainer> blockContainerSchema;
private final BlockContainerSchema<BlockContainer> blindedBlockContainerSchema;
private final ResponseHandler<ProduceBlockResponse> responseHandler;

public final DeserializableOneOfTypeDefinition<ProduceBlockResponse> produceBlockTypeDefinition;

public ProduceBlockRequest(
Expand Down Expand Up @@ -91,7 +92,12 @@ public ProduceBlockRequest(

this.responseHandler =
new ResponseHandler<>(produceBlockTypeDefinition)
.withHandler(SC_OK, this::handleBlockContainerResult);
.withHandler(SC_OK, this::handleBlockContainerResult)
.withHandler(
SC_NOT_FOUND,
(__, ___) -> {
throw new BlockProductionV3FailedException();
});
}

public Optional<BlockContainer> createUnsignedBlock(
Expand Down

0 comments on commit bb895e2

Please sign in to comment.