Skip to content

Commit

Permalink
Update PostBlock and PostBlindedBlock for Deneb
Browse files Browse the repository at this point in the history
  • Loading branch information
StefanBratanov committed May 30, 2023
1 parent d6a431f commit eff21af
Show file tree
Hide file tree
Showing 20 changed files with 339 additions and 66 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
import java.io.IOException;
import java.util.stream.Stream;
import okhttp3.Response;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
Expand All @@ -34,10 +33,12 @@
import tech.pegasys.teku.spec.SpecMilestone;
import tech.pegasys.teku.spec.datastructures.blocks.SignedBeaconBlock;
import tech.pegasys.teku.spec.datastructures.blocks.SignedBeaconBlockSchema;
import tech.pegasys.teku.spec.datastructures.blocks.SignedBlockContainer;
import tech.pegasys.teku.spec.datastructures.blocks.SignedBlockContainerSchema;
import tech.pegasys.teku.spec.util.DataStructureUtil;
import tech.pegasys.teku.validator.api.SendSignedBlockResult;

public class PostBlindedAndUnblindedBlock extends AbstractDataBackedRestAPIIntegrationTest {
public class PostBlindedAndUnblindedBlockTest extends AbstractDataBackedRestAPIIntegrationTest {
private DataStructureUtil dataStructureUtil;

public static Stream<Arguments> postBlockCases() {
Expand All @@ -48,16 +49,13 @@ public static Stream<Arguments> postBlockCases() {
Arguments.of(PostBlindedBlock.ROUTE, true, true));
}

@BeforeEach
void setup() {
startRestAPIAtGenesis(SpecMilestone.BELLATRIX);
dataStructureUtil = new DataStructureUtil(spec);
}

@ParameterizedTest(name = "blinded:{1}_ssz:{2}")
@MethodSource("postBlockCases")
void shouldReturnOk(final String route, final boolean isBlindedBlock, final boolean useSsz)
throws IOException {
startRestAPIAtGenesis(SpecMilestone.BELLATRIX);
dataStructureUtil = new DataStructureUtil(spec);

when(syncService.getCurrentSyncState()).thenReturn(SyncState.IN_SYNC);

final SignedBeaconBlockSchema signedBeaconBlockSchema;
Expand All @@ -77,17 +75,57 @@ void shouldReturnOk(final String route, final boolean isBlindedBlock, final bool
.thenReturn(SafeFuture.completedFuture(SendSignedBlockResult.success(request.getRoot())));

if (useSsz) {
try (Response response =
try (final Response response =
postSsz(route, signedBeaconBlockSchema.sszSerialize(request).toArrayUnsafe())) {
assertThat(response.code()).isEqualTo(SC_OK);
}
} else {
try (Response response =
try (final Response response =
post(
route,
JsonUtil.serialize(request, signedBeaconBlockSchema.getJsonTypeDefinition()))) {
assertThat(response.code()).isEqualTo(SC_OK);
}
}
}

@ParameterizedTest(name = "blinded:{1}_ssz:{2}")
@MethodSource("postBlockCases")
void shouldReturnOkPostDeneb(
final String route, final boolean isBlindedBlock, final boolean useSsz) throws IOException {
startRestAPIAtGenesis(SpecMilestone.DENEB);
dataStructureUtil = new DataStructureUtil(spec);

when(syncService.getCurrentSyncState()).thenReturn(SyncState.IN_SYNC);

final SignedBlockContainerSchema<SignedBlockContainer> signedBlockContainerSchema;
final SignedBlockContainer request;

if (isBlindedBlock) {
request = dataStructureUtil.randomSignedBlindedBlockContents(UInt64.ONE);
signedBlockContainerSchema =
spec.atSlot(UInt64.ONE).getSchemaDefinitions().getSignedBlindedBlockContainerSchema();
} else {
request = dataStructureUtil.randomSignedBlockContents(UInt64.ONE);
signedBlockContainerSchema =
spec.atSlot(UInt64.ONE).getSchemaDefinitions().getSignedBlockContainerSchema();
}

when(validatorApiChannel.sendSignedBlock(request))
.thenReturn(SafeFuture.completedFuture(SendSignedBlockResult.success(request.getRoot())));

if (useSsz) {
try (final Response response =
postSsz(route, signedBlockContainerSchema.sszSerialize(request).toArrayUnsafe())) {
assertThat(response.code()).isEqualTo(SC_OK);
}
} else {
String stuff =
JsonUtil.serialize(request, signedBlockContainerSchema.getJsonTypeDefinition());
System.out.println(stuff);
try (final Response response = post(route, stuff)) {
assertThat(response.code()).isEqualTo(SC_OK);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"tags" : [ "Validator", "Validator Required Api"],
"operationId" : "publishBlindedBlock",
"summary" : "Publish a signed blinded block",
"description" : "Submit a signed blinded beacon block to the beacon node to be imported. The beacon node performs the required validation.",
"description" : "Submit a signed blinded beacon block to the beacon node to be broadcast and imported. After Deneb, this additionally instructs the beacon node to broadcast and import all given signed blinded blobs. The beacon node performs the required validation.",
"requestBody" : {
"content" : {
"application/octet-stream" : {
Expand All @@ -25,7 +25,7 @@
}, {
"$ref" : "#/components/schemas/SignedBlindedBlockCapella"
}, {
"$ref" : "#/components/schemas/SignedBlindedBlockDeneb"
"$ref" : "#/components/schemas/SignedBlindedBlockContentsDeneb"
} ]
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"tags" : [ "Beacon", "Validator Required Api" ],
"operationId" : "publishBlock",
"summary" : "Publish a signed block",
"description" : "Submit a signed beacon block to the beacon node to be imported. The beacon node performs the required validation.",
"description" : "Submit a signed beacon block to the beacon node to be broadcast and imported. After Deneb, this additionally instructs the beacon node to broadcast and import all given signed blobs. The beacon node performs the required validation.",
"requestBody" : {
"content" : {
"application/octet-stream" : {
Expand All @@ -14,7 +14,7 @@
},
"application/json" : {
"schema" : {
"title" : "SignedBeaconBlock",
"title" : "SignedBlock",
"type" : "object",
"oneOf" : [ {
"$ref" : "#/components/schemas/SignedBeaconBlockPhase0"
Expand All @@ -25,7 +25,7 @@
}, {
"$ref" : "#/components/schemas/SignedBeaconBlockCapella"
}, {
"$ref" : "#/components/schemas/SignedBeaconBlockDeneb"
"$ref" : "#/components/schemas/SignedBlockContentsDeneb"
} ]
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"title" : "SignedBlindedBlobSidecar",
"type" : "object",
"required" : [ "message", "signature" ],
"properties" : {
"message" : {
"$ref" : "#/components/schemas/BlindedBlobSidecar"
},
"signature" : {
"type" : "string",
"pattern" : "^0x[a-fA-F0-9]{2,}$",
"description" : "SSZ hexadecimal",
"format" : "bytes"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"title" : "SignedBlindedBlockContentsDeneb",
"type" : "object",
"required" : [ "signed_blinded_block", "signed_blinded_blob_sidecars" ],
"properties" : {
"signed_blinded_block" : {
"$ref" : "#/components/schemas/SignedBlindedBlockDeneb"
},
"signed_blinded_blob_sidecars" : {
"type" : "array",
"items" : {
"$ref" : "#/components/schemas/SignedBlindedBlobSidecar"
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"title" : "SignedBlobSidecar",
"type" : "object",
"required" : [ "message", "signature" ],
"properties" : {
"message" : {
"$ref" : "#/components/schemas/BlobSidecar"
},
"signature" : {
"type" : "string",
"pattern" : "^0x[a-fA-F0-9]{2,}$",
"description" : "SSZ hexadecimal",
"format" : "bytes"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"title" : "SignedBlockContentsDeneb",
"type" : "object",
"required" : [ "signed_block", "signed_blob_sidecars" ],
"properties" : {
"signed_block" : {
"$ref" : "#/components/schemas/SignedBeaconBlockDeneb"
},
"signed_blob_sidecars" : {
"type" : "array",
"items" : {
"$ref" : "#/components/schemas/SignedBlobSidecar"
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ public static <T extends SszData> DeserializableTypeDefinition<? extends T> slot
final Function<SchemaDefinitions, SszSchema<? extends T>> getSchema) {
try {
final Optional<UInt64> slot =
JsonUtil.getAttribute(json, CoreTypes.UINT64_TYPE, "message", "slot");
JsonUtil.getAttribute(json, CoreTypes.UINT64_TYPE, true, "message", "slot");
final SpecMilestone milestone =
schemaDefinitionCache.milestoneAtSlot(
slot.orElseThrow(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
package tech.pegasys.teku.beaconrestapi.handlers.v1.beacon;

import static tech.pegasys.teku.beaconrestapi.handlers.v1.beacon.MilestoneDependentTypesUtil.getSchemaDefinitionForAllMilestones;
import static tech.pegasys.teku.beaconrestapi.handlers.v1.beacon.MilestoneDependentTypesUtil.slotBasedSelector;
import static tech.pegasys.teku.infrastructure.http.HttpStatusCodes.SC_ACCEPTED;
import static tech.pegasys.teku.infrastructure.http.HttpStatusCodes.SC_INTERNAL_SERVER_ERROR;
import static tech.pegasys.teku.infrastructure.http.HttpStatusCodes.SC_OK;
Expand Down Expand Up @@ -99,22 +100,25 @@ private static EndpointMetadata getEndpointMetaData(
.operationId("publishBlindedBlock")
.summary("Publish a signed blinded block")
.description(
"Submit a signed blinded beacon block to the beacon node to be imported."
"Submit a signed blinded beacon block to the beacon node to be broadcast and imported."
+ " After Deneb, this additionally instructs the beacon node to broadcast and import all given signed blinded blobs."
+ " The beacon node performs the required validation.")
.tags(TAG_VALIDATOR, TAG_VALIDATOR_REQUIRED)
.requestBodyType(
getSchemaDefinitionForAllMilestones(
schemaDefinitionCache,
"SignedBlindedBlock",
SchemaDefinitions::getSignedBlindedBeaconBlockSchema,
(block, milestone) ->
schemaDefinitionCache.milestoneAtSlot(block.getSlot()).equals(milestone)),
(json) ->
MilestoneDependentTypesUtil.slotBasedSelector(
SchemaDefinitions::getSignedBlindedBlockContainerSchema,
(blockContainer, milestone) ->
schemaDefinitionCache
.milestoneAtSlot(blockContainer.getSlot())
.equals(milestone)),
json ->
slotBasedSelector(
json,
schemaDefinitionCache,
SchemaDefinitions::getSignedBlindedBeaconBlockSchema),
spec::deserializeSignedBlindedBeaconBlock)
SchemaDefinitions::getSignedBlindedBlockContainerSchema),
spec::deserializeSignedBlindedBlockContainer)
.response(SC_OK, "Block has been successfully broadcast, validated and imported.")
.response(
SC_ACCEPTED,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,20 +70,23 @@ private static EndpointMetadata createMetadata(
.operationId("publishBlock")
.summary("Publish a signed block")
.description(
"Submit a signed beacon block to the beacon node to be imported."
"Submit a signed beacon block to the beacon node to be broadcast and imported."
+ " After Deneb, this additionally instructs the beacon node to broadcast and import all given signed blobs."
+ " The beacon node performs the required validation.")
.tags(TAG_BEACON, TAG_VALIDATOR_REQUIRED)
.requestBodyType(
getSchemaDefinitionForAllMilestones(
schemaDefinitionCache,
"SignedBeaconBlock",
SchemaDefinitions::getSignedBeaconBlockSchema,
(block, milestone) ->
schemaDefinitionCache.milestoneAtSlot(block.getSlot()).equals(milestone)),
"SignedBlock",
SchemaDefinitions::getSignedBlockContainerSchema,
(blockContainer, milestone) ->
schemaDefinitionCache
.milestoneAtSlot(blockContainer.getSlot())
.equals(milestone)),
json ->
slotBasedSelector(
json, schemaDefinitionCache, SchemaDefinitions::getSignedBeaconBlockSchema),
spec::deserializeSignedBeaconBlock)
json, schemaDefinitionCache, SchemaDefinitions::getSignedBlockContainerSchema),
spec::deserializeSignedBlockContainer)
.response(SC_OK, "Block has been successfully broadcast, validated and imported.")
.response(
SC_ACCEPTED,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,9 @@

public abstract class AbstractMigratedBeaconHandlerTest {
protected final Eth2P2PNetwork eth2P2PNetwork = mock(Eth2P2PNetwork.class);
protected Spec spec = TestSpecFactory.createMinimalPhase0();
protected UInt64 denebForkEpoch = UInt64.valueOf(12345);
protected Spec spec = TestSpecFactory.createMinimalWithDenebForkEpoch(denebForkEpoch);
protected UInt64 denebSlot = spec.computeStartSlotAtEpoch(denebForkEpoch);

protected final JsonProvider jsonProvider = new JsonProvider();
protected final NetworkDataProvider network = new NetworkDataProvider(eth2P2PNetwork);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@
import tech.pegasys.teku.api.schema.phase0.BeaconBlockPhase0;
import tech.pegasys.teku.beacon.sync.events.SyncState;
import tech.pegasys.teku.infrastructure.async.SafeFuture;
import tech.pegasys.teku.infrastructure.http.ContentTypes;
import tech.pegasys.teku.infrastructure.restapi.endpoints.RestApiEndpoint;
import tech.pegasys.teku.spec.datastructures.blocks.SignedBeaconBlock;
import tech.pegasys.teku.validator.api.SendSignedBlockResult;
Expand Down Expand Up @@ -97,18 +96,6 @@ void shouldReturnOkIfBlockImportSuccessful() throws Exception {
assertThat(request.getResponseBody()).isNull();
}

@Test
void shouldAcceptBlockAsSsz() throws Exception {
final SignedBeaconBlock data = dataStructureUtil.randomSignedBeaconBlock(3);
final SignedBeaconBlock result =
handler
.getMetadata()
.getRequestBody(
new ByteArrayInputStream(data.sszSerialize().toArrayUnsafe()),
Optional.of(ContentTypes.OCTET_STREAM));
assertThat(result).isEqualTo(data);
}

private void setupValidatorDataProviderSubmit(final SafeFuture<SendSignedBlockResult> future) {
if (isBlinded()) {
when(validatorDataProvider.submitSignedBlindedBlock(any())).thenReturn(future);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,19 @@

package tech.pegasys.teku.beaconrestapi.handlers.v1.beacon;

import static org.assertj.core.api.Assertions.assertThat;

import java.io.ByteArrayInputStream;
import java.util.Optional;
import org.junit.jupiter.api.Test;
import tech.pegasys.teku.beaconrestapi.AbstractPostBlockTest;
import tech.pegasys.teku.infrastructure.http.ContentTypes;
import tech.pegasys.teku.infrastructure.restapi.endpoints.RestApiEndpoint;
import tech.pegasys.teku.spec.datastructures.blocks.SignedBeaconBlock;
import tech.pegasys.teku.spec.datastructures.blocks.versions.deneb.SignedBlindedBlockContents;

public class PostBlindedBlockTest extends AbstractPostBlockTest {

@Override
public RestApiEndpoint getHandler() {
return new PostBlindedBlock(
Expand All @@ -27,4 +36,29 @@ public RestApiEndpoint getHandler() {
public boolean isBlinded() {
return true;
}

@Test
void shouldAcceptBlindedBlockAsSsz() throws Exception {
final SignedBeaconBlock data = dataStructureUtil.randomSignedBlindedBeaconBlock(3);
final SignedBeaconBlock result =
handler
.getMetadata()
.getRequestBody(
new ByteArrayInputStream(data.sszSerialize().toArrayUnsafe()),
Optional.of(ContentTypes.OCTET_STREAM));
assertThat(result).isEqualTo(data);
}

@Test
void shouldAcceptBlindedBlockContentsAsSsz() throws Exception {
final SignedBlindedBlockContents data =
dataStructureUtil.randomSignedBlindedBlockContents(denebSlot);
final SignedBlindedBlockContents result =
handler
.getMetadata()
.getRequestBody(
new ByteArrayInputStream(data.sszSerialize().toArrayUnsafe()),
Optional.of(ContentTypes.OCTET_STREAM));
assertThat(result).isEqualTo(data);
}
}
Loading

0 comments on commit eff21af

Please sign in to comment.