diff --git a/data/beaconrestapi/src/integration-test/resources/tech/pegasys/teku/beaconrestapi/beacon/paths/_eth_v1_beacon_blinded_blocks.json b/data/beaconrestapi/src/integration-test/resources/tech/pegasys/teku/beaconrestapi/beacon/paths/_eth_v1_beacon_blinded_blocks.json index 7cf28015cd1..3a257f0a796 100644 --- a/data/beaconrestapi/src/integration-test/resources/tech/pegasys/teku/beaconrestapi/beacon/paths/_eth_v1_beacon_blinded_blocks.json +++ b/data/beaconrestapi/src/integration-test/resources/tech/pegasys/teku/beaconrestapi/beacon/paths/_eth_v1_beacon_blinded_blocks.json @@ -4,6 +4,15 @@ "operationId" : "publishBlindedBlock", "summary" : "Publish a signed blinded block", "description" : "Submit a signed blinded beacon block to the beacon node to be broadcast and imported. The beacon node performs the required validation.", + "parameters" : [ { + "name" : "Eth-Consensus-Version", + "in" : "header", + "schema" : { + "type" : "string", + "enum" : [ "phase0", "altair", "bellatrix", "capella", "deneb", "electra" ], + "description" : "Version of the block being submitted, if using SSZ encoding." + } + } ], "requestBody" : { "content" : { "application/octet-stream" : { diff --git a/data/beaconrestapi/src/integration-test/resources/tech/pegasys/teku/beaconrestapi/beacon/paths/_eth_v1_beacon_blocks.json b/data/beaconrestapi/src/integration-test/resources/tech/pegasys/teku/beaconrestapi/beacon/paths/_eth_v1_beacon_blocks.json index f98d7e10620..85e3ef12d04 100644 --- a/data/beaconrestapi/src/integration-test/resources/tech/pegasys/teku/beaconrestapi/beacon/paths/_eth_v1_beacon_blocks.json +++ b/data/beaconrestapi/src/integration-test/resources/tech/pegasys/teku/beaconrestapi/beacon/paths/_eth_v1_beacon_blocks.json @@ -4,6 +4,15 @@ "operationId" : "publishBlock", "summary" : "Publish a signed block", "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 blobs. The beacon node performs the required validation.", + "parameters" : [ { + "name" : "Eth-Consensus-Version", + "in" : "header", + "schema" : { + "type" : "string", + "enum" : [ "phase0", "altair", "bellatrix", "capella", "deneb", "electra" ], + "description" : "Version of the block being submitted, if using SSZ encoding." + } + } ], "requestBody" : { "content" : { "application/octet-stream" : { diff --git a/data/beaconrestapi/src/integration-test/resources/tech/pegasys/teku/beaconrestapi/beacon/paths/_eth_v2_beacon_blinded_blocks.json b/data/beaconrestapi/src/integration-test/resources/tech/pegasys/teku/beaconrestapi/beacon/paths/_eth_v2_beacon_blinded_blocks.json index 269d3764d46..f0a98e76d1f 100644 --- a/data/beaconrestapi/src/integration-test/resources/tech/pegasys/teku/beaconrestapi/beacon/paths/_eth_v2_beacon_blinded_blocks.json +++ b/data/beaconrestapi/src/integration-test/resources/tech/pegasys/teku/beaconrestapi/beacon/paths/_eth_v2_beacon_blinded_blocks.json @@ -13,6 +13,15 @@ "example" : "consensus_and_equivocation", "format" : "string" } + }, { + "name" : "Eth-Consensus-Version", + "required" : true, + "in" : "header", + "schema" : { + "type" : "string", + "enum" : [ "phase0", "altair", "bellatrix", "capella", "deneb", "electra" ], + "description" : "Version of the block being submitted." + } } ], "requestBody" : { "content" : { diff --git a/data/beaconrestapi/src/integration-test/resources/tech/pegasys/teku/beaconrestapi/beacon/paths/_eth_v2_beacon_blocks.json b/data/beaconrestapi/src/integration-test/resources/tech/pegasys/teku/beaconrestapi/beacon/paths/_eth_v2_beacon_blocks.json index b27886231de..c0e383d8aa1 100644 --- a/data/beaconrestapi/src/integration-test/resources/tech/pegasys/teku/beaconrestapi/beacon/paths/_eth_v2_beacon_blocks.json +++ b/data/beaconrestapi/src/integration-test/resources/tech/pegasys/teku/beaconrestapi/beacon/paths/_eth_v2_beacon_blocks.json @@ -13,6 +13,15 @@ "example" : "consensus_and_equivocation", "format" : "string" } + }, { + "name" : "Eth-Consensus-Version", + "required" : true, + "in" : "header", + "schema" : { + "type" : "string", + "enum" : [ "phase0", "altair", "bellatrix", "capella", "deneb", "electra" ], + "description" : "Version of the block being submitted." + } } ], "requestBody" : { "content" : { diff --git a/data/beaconrestapi/src/main/java/tech/pegasys/teku/beaconrestapi/BeaconRestApiTypes.java b/data/beaconrestapi/src/main/java/tech/pegasys/teku/beaconrestapi/BeaconRestApiTypes.java index 895a192a04d..400cd536a8a 100644 --- a/data/beaconrestapi/src/main/java/tech/pegasys/teku/beaconrestapi/BeaconRestApiTypes.java +++ b/data/beaconrestapi/src/main/java/tech/pegasys/teku/beaconrestapi/BeaconRestApiTypes.java @@ -13,6 +13,7 @@ package tech.pegasys.teku.beaconrestapi; +import static tech.pegasys.teku.ethereum.json.types.EthereumTypes.MILESTONE_TYPE; import static tech.pegasys.teku.ethereum.json.types.EthereumTypes.SIGNATURE_TYPE; import static tech.pegasys.teku.infrastructure.http.RestApiConstants.ATTESTATION_DATA_ROOT; import static tech.pegasys.teku.infrastructure.http.RestApiConstants.BEACON_BLOCK_ROOT; @@ -24,6 +25,7 @@ import static tech.pegasys.teku.infrastructure.http.RestApiConstants.EPOCH; import static tech.pegasys.teku.infrastructure.http.RestApiConstants.EPOCH_QUERY_DESCRIPTION; import static tech.pegasys.teku.infrastructure.http.RestApiConstants.GRAFFITI; +import static tech.pegasys.teku.infrastructure.http.RestApiConstants.HEADER_CONSENSUS_VERSION; import static tech.pegasys.teku.infrastructure.http.RestApiConstants.INDEX; import static tech.pegasys.teku.infrastructure.http.RestApiConstants.PARAM_BLOCK_ID; import static tech.pegasys.teku.infrastructure.http.RestApiConstants.PARAM_BLOCK_ID_DESCRIPTION; @@ -71,6 +73,7 @@ import tech.pegasys.teku.infrastructure.json.types.StringValueTypeDefinition; import tech.pegasys.teku.infrastructure.restapi.endpoints.ParameterMetadata; import tech.pegasys.teku.infrastructure.unsigned.UInt64; +import tech.pegasys.teku.spec.SpecMilestone; import tech.pegasys.teku.spec.datastructures.blocks.SignedBeaconBlockHeader; import tech.pegasys.teku.spec.datastructures.metadata.BlockAndMetaData; import tech.pegasys.teku.spec.datastructures.validator.BroadcastValidationLevel; @@ -241,6 +244,9 @@ public class BeaconRestApiTypes { PARAMETER_BROADCAST_VALIDATION = new ParameterMetadata<>(PARAM_BROADCAST_VALIDATION, BROADCAST_VALIDATION_VALUE); + public static final ParameterMetadata ETH_CONSENSUS_VERSION_TYPE = + new ParameterMetadata<>(HEADER_CONSENSUS_VERSION, MILESTONE_TYPE); + @SuppressWarnings("JavaCase") public enum BroadcastValidationParameter { gossip, diff --git a/data/beaconrestapi/src/main/java/tech/pegasys/teku/beaconrestapi/handlers/v1/beacon/PostBlindedBlock.java b/data/beaconrestapi/src/main/java/tech/pegasys/teku/beaconrestapi/handlers/v1/beacon/PostBlindedBlock.java index 1c65d03856b..54b5636d1bb 100644 --- a/data/beaconrestapi/src/main/java/tech/pegasys/teku/beaconrestapi/handlers/v1/beacon/PostBlindedBlock.java +++ b/data/beaconrestapi/src/main/java/tech/pegasys/teku/beaconrestapi/handlers/v1/beacon/PostBlindedBlock.java @@ -13,6 +13,7 @@ package tech.pegasys.teku.beaconrestapi.handlers.v1.beacon; +import static tech.pegasys.teku.beaconrestapi.BeaconRestApiTypes.ETH_CONSENSUS_VERSION_TYPE; import static tech.pegasys.teku.beaconrestapi.handlers.v1.beacon.MilestoneDependentTypesUtil.getSchemaDefinitionForAllSupportedMilestones; import static tech.pegasys.teku.beaconrestapi.handlers.v1.beacon.MilestoneDependentTypesUtil.slotBasedSelector; import static tech.pegasys.teku.infrastructure.http.HttpStatusCodes.SC_ACCEPTED; @@ -95,6 +96,9 @@ private static EndpointMetadata createMetadata( schemaDefinitionCache, SchemaDefinitions::getSignedBlindedBlockContainerSchema), spec::deserializeSignedBlindedBlockContainer) + .header( + ETH_CONSENSUS_VERSION_TYPE.withDescription( + "Version of the block being submitted, if using SSZ encoding.")) .response(SC_OK, "Block has been successfully broadcast, validated and imported.") .response( SC_ACCEPTED, diff --git a/data/beaconrestapi/src/main/java/tech/pegasys/teku/beaconrestapi/handlers/v1/beacon/PostBlock.java b/data/beaconrestapi/src/main/java/tech/pegasys/teku/beaconrestapi/handlers/v1/beacon/PostBlock.java index 90daf736ba8..d59b01f4590 100644 --- a/data/beaconrestapi/src/main/java/tech/pegasys/teku/beaconrestapi/handlers/v1/beacon/PostBlock.java +++ b/data/beaconrestapi/src/main/java/tech/pegasys/teku/beaconrestapi/handlers/v1/beacon/PostBlock.java @@ -13,6 +13,7 @@ package tech.pegasys.teku.beaconrestapi.handlers.v1.beacon; +import static tech.pegasys.teku.beaconrestapi.BeaconRestApiTypes.ETH_CONSENSUS_VERSION_TYPE; import static tech.pegasys.teku.beaconrestapi.handlers.v1.beacon.MilestoneDependentTypesUtil.getSchemaDefinitionForAllSupportedMilestones; import static tech.pegasys.teku.beaconrestapi.handlers.v1.beacon.MilestoneDependentTypesUtil.slotBasedSelector; import static tech.pegasys.teku.infrastructure.http.HttpStatusCodes.SC_ACCEPTED; @@ -98,6 +99,9 @@ private static EndpointMetadata createMetadata( schemaDefinitionCache, SchemaDefinitions::getSignedBlockContainerSchema), spec::deserializeSignedBlockContainer) + .header( + ETH_CONSENSUS_VERSION_TYPE.withDescription( + "Version of the block being submitted, if using SSZ encoding.")) .response(SC_OK, "Block has been successfully broadcast, validated and imported.") .response( SC_ACCEPTED, diff --git a/data/beaconrestapi/src/main/java/tech/pegasys/teku/beaconrestapi/handlers/v2/beacon/PostBlindedBlockV2.java b/data/beaconrestapi/src/main/java/tech/pegasys/teku/beaconrestapi/handlers/v2/beacon/PostBlindedBlockV2.java index 87c3d788136..5fe6da80e54 100644 --- a/data/beaconrestapi/src/main/java/tech/pegasys/teku/beaconrestapi/handlers/v2/beacon/PostBlindedBlockV2.java +++ b/data/beaconrestapi/src/main/java/tech/pegasys/teku/beaconrestapi/handlers/v2/beacon/PostBlindedBlockV2.java @@ -13,6 +13,7 @@ package tech.pegasys.teku.beaconrestapi.handlers.v2.beacon; +import static tech.pegasys.teku.beaconrestapi.BeaconRestApiTypes.ETH_CONSENSUS_VERSION_TYPE; import static tech.pegasys.teku.beaconrestapi.BeaconRestApiTypes.PARAMETER_BROADCAST_VALIDATION; import static tech.pegasys.teku.beaconrestapi.handlers.v1.beacon.MilestoneDependentTypesUtil.getSchemaDefinitionForAllSupportedMilestones; import static tech.pegasys.teku.beaconrestapi.handlers.v1.beacon.MilestoneDependentTypesUtil.slotBasedSelector; @@ -117,6 +118,8 @@ broadcast but a different status code is returned (202). Pre-Bellatrix, this end schemaDefinitionCache, SchemaDefinitions::getSignedBlindedBlockContainerSchema), spec::deserializeSignedBlindedBlockContainer) + .headerRequired( + ETH_CONSENSUS_VERSION_TYPE.withDescription("Version of the block being submitted.")) .response(SC_OK, "Block has been successfully broadcast, validated and imported.") .response( SC_ACCEPTED, diff --git a/data/beaconrestapi/src/main/java/tech/pegasys/teku/beaconrestapi/handlers/v2/beacon/PostBlockV2.java b/data/beaconrestapi/src/main/java/tech/pegasys/teku/beaconrestapi/handlers/v2/beacon/PostBlockV2.java index 4e55bac9921..78200d40670 100644 --- a/data/beaconrestapi/src/main/java/tech/pegasys/teku/beaconrestapi/handlers/v2/beacon/PostBlockV2.java +++ b/data/beaconrestapi/src/main/java/tech/pegasys/teku/beaconrestapi/handlers/v2/beacon/PostBlockV2.java @@ -13,6 +13,7 @@ package tech.pegasys.teku.beaconrestapi.handlers.v2.beacon; +import static tech.pegasys.teku.beaconrestapi.BeaconRestApiTypes.ETH_CONSENSUS_VERSION_TYPE; import static tech.pegasys.teku.beaconrestapi.BeaconRestApiTypes.PARAMETER_BROADCAST_VALIDATION; import static tech.pegasys.teku.beaconrestapi.handlers.v1.beacon.MilestoneDependentTypesUtil.getSchemaDefinitionForAllSupportedMilestones; import static tech.pegasys.teku.beaconrestapi.handlers.v1.beacon.MilestoneDependentTypesUtil.slotBasedSelector; @@ -117,6 +118,8 @@ validation, a separate success response code (202) is used to indicate that the schemaDefinitionCache, SchemaDefinitions::getSignedBlockContainerSchema), spec::deserializeSignedBlockContainer) + .headerRequired( + ETH_CONSENSUS_VERSION_TYPE.withDescription("Version of the block being submitted.")) .response(SC_OK, "Block has been successfully broadcast, validated and imported.") .response( SC_ACCEPTED, diff --git a/ethereum/json-types/src/main/java/tech/pegasys/teku/ethereum/json/types/EthereumTypes.java b/ethereum/json-types/src/main/java/tech/pegasys/teku/ethereum/json/types/EthereumTypes.java index fe635eeda04..7fac43c10aa 100644 --- a/ethereum/json-types/src/main/java/tech/pegasys/teku/ethereum/json/types/EthereumTypes.java +++ b/ethereum/json-types/src/main/java/tech/pegasys/teku/ethereum/json/types/EthereumTypes.java @@ -25,6 +25,7 @@ import tech.pegasys.teku.ethereum.execution.types.Eth1Address; import tech.pegasys.teku.infrastructure.http.RestApiConstants; import tech.pegasys.teku.infrastructure.json.types.DeserializableTypeDefinition; +import tech.pegasys.teku.infrastructure.json.types.EnumTypeDefinition; import tech.pegasys.teku.infrastructure.json.types.StringValueTypeDefinition; import tech.pegasys.teku.infrastructure.restapi.openapi.response.OctetStreamResponseContentTypeDefinition; import tech.pegasys.teku.infrastructure.restapi.openapi.response.ResponseContentTypeDefinition; @@ -91,8 +92,8 @@ public class EthereumTypes { .format("byte") .build(); - public static final DeserializableTypeDefinition MILESTONE_TYPE = - DeserializableTypeDefinition.enumOf( + public static final StringValueTypeDefinition MILESTONE_TYPE = + new EnumTypeDefinition<>( SpecMilestone.class, milestone -> milestone.name().toLowerCase(Locale.ROOT), Set.of()); public static >