diff --git a/data/beaconrestapi/src/integration-test/resources/tech/pegasys/teku/beaconrestapi/beacon/paths/_eth_v1_debug_fork_choice.json b/data/beaconrestapi/src/integration-test/resources/tech/pegasys/teku/beaconrestapi/beacon/paths/_eth_v1_debug_fork_choice.json index 7657d7ee73c..c0d7bfb15f2 100644 --- a/data/beaconrestapi/src/integration-test/resources/tech/pegasys/teku/beaconrestapi/beacon/paths/_eth_v1_debug_fork_choice.json +++ b/data/beaconrestapi/src/integration-test/resources/tech/pegasys/teku/beaconrestapi/beacon/paths/_eth_v1_debug_fork_choice.json @@ -63,7 +63,7 @@ }, "validity" : { "type" : "string", - "enum" : [ "VALID", "INVALID", "OPTIMISTIC" ] + "enum" : [ "valid", "invalid", "optimistic" ] }, "execution_block_hash" : { "type" : "string", diff --git a/data/beaconrestapi/src/main/java/tech/pegasys/teku/beaconrestapi/handlers/v1/debug/GetForkChoice.java b/data/beaconrestapi/src/main/java/tech/pegasys/teku/beaconrestapi/handlers/v1/debug/GetForkChoice.java index cd051969a9c..439af4e1f37 100644 --- a/data/beaconrestapi/src/main/java/tech/pegasys/teku/beaconrestapi/handlers/v1/debug/GetForkChoice.java +++ b/data/beaconrestapi/src/main/java/tech/pegasys/teku/beaconrestapi/handlers/v1/debug/GetForkChoice.java @@ -72,7 +72,7 @@ public class GetForkChoice extends RestApiEndpoint { .withField("weight", UINT64_TYPE, ProtoNodeData::getWeight) .withField( "validity", - DeserializableTypeDefinition.enumOf(ProtoNodeValidationStatus.class), + DeserializableTypeDefinition.enumOf(ProtoNodeValidationStatus.class, true), ProtoNodeData::getValidationStatus) .withField( "execution_block_hash", diff --git a/data/beaconrestapi/src/test/resources/tech/pegasys/teku/beaconrestapi/handlers/v1/debug/getForkChoice.json b/data/beaconrestapi/src/test/resources/tech/pegasys/teku/beaconrestapi/handlers/v1/debug/getForkChoice.json index c6f0ec4ceb7..a1e65ee71b2 100644 --- a/data/beaconrestapi/src/test/resources/tech/pegasys/teku/beaconrestapi/handlers/v1/debug/getForkChoice.json +++ b/data/beaconrestapi/src/test/resources/tech/pegasys/teku/beaconrestapi/handlers/v1/debug/getForkChoice.json @@ -1 +1 @@ -{"justified_checkpoint":{"epoch":"1","root":"0x0000000000000000000000000000000000000000000000000000000000001111"},"finalized_checkpoint":{"epoch":"0","root":"0x0000000000000000000000000000000000000000000000000000000000002222"},"fork_choice_nodes":[{"slot":"32","block_root":"0x0000000000000000000000000000000000000000000000000000000000003333","parent_root":"0x0000000000000000000000000000000000000000000000000000000000004444","justified_epoch":"10","finalized_epoch":"11","weight":"409600000000","validity":"OPTIMISTIC","execution_block_hash":"0x0000000000000000000000000000000000000000000000000000000000006666","extra_data":{"state_root":"0x0000000000000000000000000000000000000000000000000000000000005555","justified_root":"0x0000000000000000000000000000000000000000000000000000000000007777","unrealised_justified_epoch":"12","unrealized_justified_root":"0x0000000000000000000000000000000000000000000000000000000000009999","unrealised_finalized_epoch":"13","unrealized_finalized_root":"0x0000000000000000000000000000000000000000000000000000000000000000"}}],"extra_data":{}} \ No newline at end of file +{"justified_checkpoint":{"epoch":"1","root":"0x0000000000000000000000000000000000000000000000000000000000001111"},"finalized_checkpoint":{"epoch":"0","root":"0x0000000000000000000000000000000000000000000000000000000000002222"},"fork_choice_nodes":[{"slot":"32","block_root":"0x0000000000000000000000000000000000000000000000000000000000003333","parent_root":"0x0000000000000000000000000000000000000000000000000000000000004444","justified_epoch":"10","finalized_epoch":"11","weight":"409600000000","validity":"optimistic","execution_block_hash":"0x0000000000000000000000000000000000000000000000000000000000006666","extra_data":{"state_root":"0x0000000000000000000000000000000000000000000000000000000000005555","justified_root":"0x0000000000000000000000000000000000000000000000000000000000007777","unrealised_justified_epoch":"12","unrealized_justified_root":"0x0000000000000000000000000000000000000000000000000000000000009999","unrealised_finalized_epoch":"13","unrealized_finalized_root":"0x0000000000000000000000000000000000000000000000000000000000000000"}}],"extra_data":{}} \ No newline at end of file diff --git a/infrastructure/json/src/main/java/tech/pegasys/teku/infrastructure/json/types/DeserializableTypeDefinition.java b/infrastructure/json/src/main/java/tech/pegasys/teku/infrastructure/json/types/DeserializableTypeDefinition.java index a5b3fe5fef7..79123ba9586 100644 --- a/infrastructure/json/src/main/java/tech/pegasys/teku/infrastructure/json/types/DeserializableTypeDefinition.java +++ b/infrastructure/json/src/main/java/tech/pegasys/teku/infrastructure/json/types/DeserializableTypeDefinition.java @@ -60,7 +60,12 @@ static DeserializableTypeDefinition> mapOf( static > EnumTypeDefinition enumOf( final Class itemType) { - return new EnumTypeDefinition.EnumTypeBuilder<>(itemType).build(); + return new EnumTypeDefinition.EnumTypeBuilder<>(itemType, false).build(); + } + + static > EnumTypeDefinition enumOf( + final Class itemType, final boolean forceLowercase) { + return new EnumTypeDefinition.EnumTypeBuilder<>(itemType, forceLowercase).build(); } static DeserializableObjectTypeDefinitionBuilder object( diff --git a/infrastructure/json/src/main/java/tech/pegasys/teku/infrastructure/json/types/EnumTypeDefinition.java b/infrastructure/json/src/main/java/tech/pegasys/teku/infrastructure/json/types/EnumTypeDefinition.java index 19c70d500af..b15f5071012 100644 --- a/infrastructure/json/src/main/java/tech/pegasys/teku/infrastructure/json/types/EnumTypeDefinition.java +++ b/infrastructure/json/src/main/java/tech/pegasys/teku/infrastructure/json/types/EnumTypeDefinition.java @@ -17,6 +17,7 @@ import com.fasterxml.jackson.core.JsonParser; import java.io.IOException; import java.util.HashSet; +import java.util.Locale; import java.util.Objects; import java.util.Optional; import java.util.Set; @@ -135,8 +136,13 @@ public EnumTypeBuilder(final Class itemType, final Function serial } public EnumTypeBuilder(final Class itemType) { - this.itemType = itemType; - this.serializer = Enum::toString; + this(itemType, false); + } + + public EnumTypeBuilder(final Class itemType, final boolean forceLowercase) { + this( + itemType, + forceLowercase ? (val) -> val.toString().toLowerCase(Locale.ROOT) : Enum::toString); } public EnumTypeBuilder parser(final Class itemType) { diff --git a/infrastructure/json/src/test/java/tech/pegasys/teku/infrastructure/json/types/EnumTypeDefinitionTest.java b/infrastructure/json/src/test/java/tech/pegasys/teku/infrastructure/json/types/EnumTypeDefinitionTest.java index e4085791b08..c241cb810ba 100644 --- a/infrastructure/json/src/test/java/tech/pegasys/teku/infrastructure/json/types/EnumTypeDefinitionTest.java +++ b/infrastructure/json/src/test/java/tech/pegasys/teku/infrastructure/json/types/EnumTypeDefinitionTest.java @@ -31,6 +31,18 @@ void shouldSerializeEnum() throws Exception { assertThat(json).isEqualTo("\"yes\""); } + @Test + void shouldSerializeEnumForceLowerCase() throws Exception { + DeserializableTypeDefinition definition = + DeserializableTypeDefinition.enumOf(YES_NO.class); + String json = JsonUtil.serialize(YES_NO.YES, definition); + assertThat(json).isEqualTo("\"YES\""); + + definition = DeserializableTypeDefinition.enumOf(YES_NO.class, true); + json = JsonUtil.serialize(YES_NO.YES, definition); + assertThat(json).isEqualTo("\"yes\""); + } + @Test void shouldParseEnum() throws Exception { assertThat(JsonUtil.parse("\"no\"", definition)).isEqualTo(YesNo.NO); @@ -73,4 +85,10 @@ public String toString() { return displayName; } } + + @SuppressWarnings("JavaCase") + private enum YES_NO { + YES, + NO + } }