From 93c87699775814ff02bacc798ba26eb6b2930557 Mon Sep 17 00:00:00 2001 From: Enrico Del Fante Date: Wed, 9 Oct 2024 11:07:31 +0200 Subject: [PATCH 1/9] clear changelog (#8690) --- CHANGELOG.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5835a0b182b..f9bffda3d31 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,5 +11,3 @@ ### Additions and Improvements ### Bug Fixes -- Fixed the proposer configuration file loading error at startup - From 82725a0d1e682977c365b6a7ac1c7b208af2c787 Mon Sep 17 00:00:00 2001 From: Enrico Del Fante Date: Wed, 9 Oct 2024 16:16:56 +0200 Subject: [PATCH 2/9] Migrate Attestation and AttnetsENR schemas to registry (#8692) * migrate Attestation and AttnetsENR schemas to registry * allow `addMilestoneMapping` with same `milestone` and `untilMilestone` --- .../schemas/AbstractSchemaDefinitions.java | 4 +- .../schemas/SchemaDefinitionsElectra.java | 7 +-- .../spec/schemas/SchemaDefinitionsPhase0.java | 8 +-- .../registry/AbstractSchemaProvider.java | 4 +- .../registry/AttestationSchemaProvider.java | 63 +++++++++++++++++++ .../AttnetsENRFieldSchemaProvider.java | 44 +++++++++++++ .../registry/SchemaRegistryBuilder.java | 4 +- .../spec/schemas/registry/SchemaTypes.java | 5 ++ 8 files changed, 124 insertions(+), 15 deletions(-) create mode 100644 ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/registry/AttestationSchemaProvider.java create mode 100644 ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/registry/AttnetsENRFieldSchemaProvider.java diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/AbstractSchemaDefinitions.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/AbstractSchemaDefinitions.java index 086f6587cc1..91145d621d4 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/AbstractSchemaDefinitions.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/AbstractSchemaDefinitions.java @@ -20,6 +20,7 @@ import tech.pegasys.teku.spec.datastructures.networking.libp2p.rpc.BeaconBlocksByRootRequestMessage; import tech.pegasys.teku.spec.datastructures.state.HistoricalBatch.HistoricalBatchSchema; import tech.pegasys.teku.spec.schemas.registry.SchemaRegistry; +import tech.pegasys.teku.spec.schemas.registry.SchemaTypes; public abstract class AbstractSchemaDefinitions implements SchemaDefinitions { protected SchemaRegistry schemaRegistry; @@ -39,8 +40,7 @@ public AbstractSchemaDefinitions(final SchemaRegistry schemaRegistry) { this.beaconBlocksByRootRequestMessageSchema = new BeaconBlocksByRootRequestMessage.BeaconBlocksByRootRequestMessageSchema( schemaRegistry.getSpecConfig()); - this.attnetsENRFieldSchema = - SszBitvectorSchema.create(schemaRegistry.getSpecConfig().getAttestationSubnetCount()); + this.attnetsENRFieldSchema = schemaRegistry.get(SchemaTypes.ATTNETS_ENR_FIELD_SCHEMA); } abstract long getMaxValidatorPerAttestation(SpecConfig specConfig); diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/SchemaDefinitionsElectra.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/SchemaDefinitionsElectra.java index 1f730bfad8a..6c858851a1e 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/SchemaDefinitionsElectra.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/SchemaDefinitionsElectra.java @@ -53,7 +53,6 @@ import tech.pegasys.teku.spec.datastructures.operations.IndexedAttestation; import tech.pegasys.teku.spec.datastructures.operations.IndexedAttestationSchema; import tech.pegasys.teku.spec.datastructures.operations.SignedAggregateAndProof.SignedAggregateAndProofSchema; -import tech.pegasys.teku.spec.datastructures.operations.versions.electra.AttestationElectraSchema; import tech.pegasys.teku.spec.datastructures.operations.versions.electra.AttesterSlashingElectraSchema; import tech.pegasys.teku.spec.datastructures.operations.versions.electra.IndexedAttestationElectraSchema; import tech.pegasys.teku.spec.datastructures.state.beaconstate.BeaconStateSchema; @@ -64,6 +63,7 @@ import tech.pegasys.teku.spec.datastructures.state.versions.electra.PendingDeposit; import tech.pegasys.teku.spec.datastructures.state.versions.electra.PendingPartialWithdrawal; import tech.pegasys.teku.spec.schemas.registry.SchemaRegistry; +import tech.pegasys.teku.spec.schemas.registry.SchemaTypes; public class SchemaDefinitionsElectra extends SchemaDefinitionsDeneb { @@ -114,10 +114,7 @@ public SchemaDefinitionsElectra(final SchemaRegistry schemaRegistry) { new AttesterSlashingElectraSchema(indexedAttestationSchema) .castTypeToAttesterSlashingSchema(); - this.attestationSchema = - new AttestationElectraSchema( - maxValidatorsPerAttestation, specConfig.getMaxCommitteesPerSlot()) - .castTypeToAttestationSchema(); + this.attestationSchema = schemaRegistry.get(SchemaTypes.ATTESTATION_SCHEMA); this.aggregateAndProofSchema = new AggregateAndProofSchema(attestationSchema); this.signedAggregateAndProofSchema = new SignedAggregateAndProofSchema(aggregateAndProofSchema); diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/SchemaDefinitionsPhase0.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/SchemaDefinitionsPhase0.java index 08387f63345..6176c070e32 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/SchemaDefinitionsPhase0.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/SchemaDefinitionsPhase0.java @@ -34,12 +34,12 @@ import tech.pegasys.teku.spec.datastructures.operations.IndexedAttestation; import tech.pegasys.teku.spec.datastructures.operations.IndexedAttestationSchema; import tech.pegasys.teku.spec.datastructures.operations.SignedAggregateAndProof.SignedAggregateAndProofSchema; -import tech.pegasys.teku.spec.datastructures.operations.versions.phase0.AttestationPhase0Schema; import tech.pegasys.teku.spec.datastructures.operations.versions.phase0.AttesterSlashingPhase0Schema; import tech.pegasys.teku.spec.datastructures.operations.versions.phase0.IndexedAttestationPhase0Schema; import tech.pegasys.teku.spec.datastructures.state.beaconstate.BeaconStateSchema; import tech.pegasys.teku.spec.datastructures.state.beaconstate.versions.phase0.BeaconStateSchemaPhase0; import tech.pegasys.teku.spec.schemas.registry.SchemaRegistry; +import tech.pegasys.teku.spec.schemas.registry.SchemaTypes; public class SchemaDefinitionsPhase0 extends AbstractSchemaDefinitions { private final IndexedAttestationSchema indexedAttestationSchema; @@ -63,10 +63,8 @@ public SchemaDefinitionsPhase0(final SchemaRegistry schemaRegistry) { new AttesterSlashingPhase0Schema(indexedAttestationSchema) .castTypeToAttesterSlashingSchema(); - this.aggregateAndProofSchema = - new AggregateAndProofSchema( - new AttestationPhase0Schema(getMaxValidatorPerAttestation(specConfig))); - this.attestationSchema = this.aggregateAndProofSchema.getAttestationSchema(); + this.attestationSchema = schemaRegistry.get(SchemaTypes.ATTESTATION_SCHEMA); + this.aggregateAndProofSchema = new AggregateAndProofSchema(attestationSchema); this.signedAggregateAndProofSchema = new SignedAggregateAndProofSchema(aggregateAndProofSchema); this.beaconStateSchema = BeaconStateSchemaPhase0.create(specConfig); this.beaconBlockBodySchema = diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/registry/AbstractSchemaProvider.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/registry/AbstractSchemaProvider.java index c1addf4d779..d7e023b76d5 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/registry/AbstractSchemaProvider.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/registry/AbstractSchemaProvider.java @@ -34,8 +34,8 @@ protected AbstractSchemaProvider(final SchemaId schemaId) { protected void addMilestoneMapping( final SpecMilestone milestone, final SpecMilestone untilMilestone) { checkArgument( - untilMilestone.isGreaterThan(milestone), - "%s must be earlier than %s", + untilMilestone.isGreaterThanOrEqualTo(milestone), + "%s must be earlier then or equal to %s", milestone, untilMilestone); diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/registry/AttestationSchemaProvider.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/registry/AttestationSchemaProvider.java new file mode 100644 index 00000000000..120d9d5ecbd --- /dev/null +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/registry/AttestationSchemaProvider.java @@ -0,0 +1,63 @@ +/* + * 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.spec.schemas.registry; + +import static tech.pegasys.teku.spec.SpecMilestone.DENEB; +import static tech.pegasys.teku.spec.SpecMilestone.ELECTRA; +import static tech.pegasys.teku.spec.SpecMilestone.PHASE0; +import static tech.pegasys.teku.spec.schemas.registry.SchemaTypes.ATTESTATION_SCHEMA; + +import java.util.Set; +import tech.pegasys.teku.spec.SpecMilestone; +import tech.pegasys.teku.spec.config.SpecConfig; +import tech.pegasys.teku.spec.datastructures.operations.Attestation; +import tech.pegasys.teku.spec.datastructures.operations.AttestationSchema; +import tech.pegasys.teku.spec.datastructures.operations.versions.electra.AttestationElectraSchema; +import tech.pegasys.teku.spec.datastructures.operations.versions.phase0.AttestationPhase0Schema; + +public class AttestationSchemaProvider + extends AbstractSchemaProvider> { + + public AttestationSchemaProvider() { + super(ATTESTATION_SCHEMA); + addMilestoneMapping(PHASE0, DENEB); + addMilestoneMapping(ELECTRA, SpecMilestone.getHighestMilestone()); + } + + @Override + protected AttestationSchema createSchema( + final SchemaRegistry registry, + final SpecMilestone effectiveMilestone, + final SpecConfig specConfig) { + return switch (effectiveMilestone) { + case PHASE0 -> + new AttestationPhase0Schema(specConfig.getMaxValidatorsPerCommittee()) + .castTypeToAttestationSchema(); + case ELECTRA -> + new AttestationElectraSchema( + (long) specConfig.getMaxValidatorsPerCommittee() + * specConfig.getMaxCommitteesPerSlot(), + specConfig.getMaxCommitteesPerSlot()) + .castTypeToAttestationSchema(); + default -> + throw new IllegalArgumentException( + "It is not supposed to create a specific version for " + effectiveMilestone); + }; + } + + @Override + public Set getSupportedMilestones() { + return ALL_MILESTONES; + } +} diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/registry/AttnetsENRFieldSchemaProvider.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/registry/AttnetsENRFieldSchemaProvider.java new file mode 100644 index 00000000000..bd01161eec4 --- /dev/null +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/registry/AttnetsENRFieldSchemaProvider.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.spec.schemas.registry; + +import static tech.pegasys.teku.spec.SpecMilestone.PHASE0; +import static tech.pegasys.teku.spec.schemas.registry.SchemaTypes.ATTNETS_ENR_FIELD_SCHEMA; + +import java.util.Set; +import tech.pegasys.teku.infrastructure.ssz.collections.SszBitvector; +import tech.pegasys.teku.infrastructure.ssz.schema.collections.SszBitvectorSchema; +import tech.pegasys.teku.spec.SpecMilestone; +import tech.pegasys.teku.spec.config.SpecConfig; + +public class AttnetsENRFieldSchemaProvider + extends AbstractSchemaProvider> { + public AttnetsENRFieldSchemaProvider() { + super(ATTNETS_ENR_FIELD_SCHEMA); + addMilestoneMapping(PHASE0, SpecMilestone.getHighestMilestone()); + } + + @Override + protected SszBitvectorSchema createSchema( + final SchemaRegistry registry, + final SpecMilestone effectiveMilestone, + final SpecConfig specConfig) { + return SszBitvectorSchema.create(specConfig.getAttestationSubnetCount()); + } + + @Override + public Set getSupportedMilestones() { + return ALL_MILESTONES; + } +} diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/registry/SchemaRegistryBuilder.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/registry/SchemaRegistryBuilder.java index e11bb1f6678..81788ca7d99 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/registry/SchemaRegistryBuilder.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/registry/SchemaRegistryBuilder.java @@ -26,7 +26,9 @@ public class SchemaRegistryBuilder { private final SchemaCache cache; public static SchemaRegistryBuilder create() { - return new SchemaRegistryBuilder(); + return new SchemaRegistryBuilder() + .addProvider(new AttnetsENRFieldSchemaProvider()) + .addProvider(new AttestationSchemaProvider()); } public SchemaRegistryBuilder() { diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/registry/SchemaTypes.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/registry/SchemaTypes.java index 68a82c8d4a9..69e783dd28f 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/registry/SchemaTypes.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/registry/SchemaTypes.java @@ -21,12 +21,17 @@ import tech.pegasys.teku.infrastructure.ssz.collections.SszBitvector; import tech.pegasys.teku.infrastructure.ssz.schema.collections.SszBitvectorSchema; import tech.pegasys.teku.spec.SpecMilestone; +import tech.pegasys.teku.spec.datastructures.operations.Attestation; +import tech.pegasys.teku.spec.datastructures.operations.AttestationSchema; public class SchemaTypes { // PHASE0 public static final SchemaId> ATTNETS_ENR_FIELD_SCHEMA = create("ATTNETS_ENR_FIELD_SCHEMA"); + public static final SchemaId> ATTESTATION_SCHEMA = + create("ATTESTATION_SCHEMA"); + // Altair // Bellatrix From f29119ae0b68f0ee44160c16c377ecb0a351e24b Mon Sep 17 00:00:00 2001 From: Paul Harris Date: Thu, 10 Oct 2024 07:35:20 +1000 Subject: [PATCH 3/9] Cleanup JsonProvider and unused serializers (#8689) Signed-off-by: Paul Harris --- .../teku/api/SchemaObjectProvider.java | 38 -- .../pegasys/teku/api/ConfigProviderTest.java | 42 -- .../pegasys/teku/api/schema/package-info.java | 5 + .../teku/provider/BLSPubKeyDeserializer.java | 29 -- .../teku/provider/BLSPubKeySerializer.java | 30 -- .../provider/BLSSignatureDeserializer.java | 28 -- .../teku/provider/BLSSignatureSerializer.java | 30 -- ...etNewBlindedBlockResponseDeserializer.java | 60 --- .../GetNewBlockResponseV1Deserializer.java | 40 -- .../GetNewBlockResponseV2Deserializer.java | 59 --- .../GetStateResponseV2Deserializer.java | 56 --- .../pegasys/teku/provider/JsonProvider.java | 135 ------ .../provider/KZGCommitmentDeserializer.java | 29 -- .../provider/KZGCommitmentSerializer.java | 30 -- .../teku/provider/KZGProofDeserializer.java | 29 -- .../teku/provider/KZGProofSerializer.java | 30 -- .../teku/provider/SszBitvectorSerializer.java | 30 -- .../provider/JsonProviderPropertyTest.java | 428 ------------------ .../teku/provider/JsonProviderTest.java | 183 -------- .../config/WeakSubjectivityConfigTest.java | 2 +- 20 files changed, 6 insertions(+), 1307 deletions(-) delete mode 100644 data/provider/src/test/java/tech/pegasys/teku/api/ConfigProviderTest.java create mode 100644 data/serializer/src/main/java/tech/pegasys/teku/api/schema/package-info.java delete mode 100644 data/serializer/src/main/java/tech/pegasys/teku/provider/BLSPubKeyDeserializer.java delete mode 100644 data/serializer/src/main/java/tech/pegasys/teku/provider/BLSPubKeySerializer.java delete mode 100644 data/serializer/src/main/java/tech/pegasys/teku/provider/BLSSignatureDeserializer.java delete mode 100644 data/serializer/src/main/java/tech/pegasys/teku/provider/BLSSignatureSerializer.java delete mode 100644 data/serializer/src/main/java/tech/pegasys/teku/provider/GetNewBlindedBlockResponseDeserializer.java delete mode 100644 data/serializer/src/main/java/tech/pegasys/teku/provider/GetNewBlockResponseV1Deserializer.java delete mode 100644 data/serializer/src/main/java/tech/pegasys/teku/provider/GetNewBlockResponseV2Deserializer.java delete mode 100644 data/serializer/src/main/java/tech/pegasys/teku/provider/GetStateResponseV2Deserializer.java delete mode 100644 data/serializer/src/main/java/tech/pegasys/teku/provider/JsonProvider.java delete mode 100644 data/serializer/src/main/java/tech/pegasys/teku/provider/KZGCommitmentDeserializer.java delete mode 100644 data/serializer/src/main/java/tech/pegasys/teku/provider/KZGCommitmentSerializer.java delete mode 100644 data/serializer/src/main/java/tech/pegasys/teku/provider/KZGProofDeserializer.java delete mode 100644 data/serializer/src/main/java/tech/pegasys/teku/provider/KZGProofSerializer.java delete mode 100644 data/serializer/src/main/java/tech/pegasys/teku/provider/SszBitvectorSerializer.java delete mode 100644 data/serializer/src/property-test/java/tech/pegasys/teku/provider/JsonProviderPropertyTest.java delete mode 100644 data/serializer/src/test/java/tech/pegasys/teku/provider/JsonProviderTest.java diff --git a/data/provider/src/main/java/tech/pegasys/teku/api/SchemaObjectProvider.java b/data/provider/src/main/java/tech/pegasys/teku/api/SchemaObjectProvider.java index d78fadf6b52..2c829b40b96 100644 --- a/data/provider/src/main/java/tech/pegasys/teku/api/SchemaObjectProvider.java +++ b/data/provider/src/main/java/tech/pegasys/teku/api/SchemaObjectProvider.java @@ -13,37 +13,27 @@ package tech.pegasys.teku.api; -import tech.pegasys.teku.api.schema.BLSSignature; import tech.pegasys.teku.api.schema.BeaconBlock; import tech.pegasys.teku.api.schema.BeaconBlockBody; -import tech.pegasys.teku.api.schema.BeaconState; -import tech.pegasys.teku.api.schema.SignedBeaconBlock; import tech.pegasys.teku.api.schema.altair.BeaconBlockAltair; import tech.pegasys.teku.api.schema.altair.BeaconBlockBodyAltair; -import tech.pegasys.teku.api.schema.altair.BeaconStateAltair; import tech.pegasys.teku.api.schema.bellatrix.BeaconBlockBellatrix; import tech.pegasys.teku.api.schema.bellatrix.BeaconBlockBodyBellatrix; -import tech.pegasys.teku.api.schema.bellatrix.BeaconStateBellatrix; import tech.pegasys.teku.api.schema.bellatrix.BlindedBeaconBlockBodyBellatrix; import tech.pegasys.teku.api.schema.bellatrix.BlindedBlockBellatrix; import tech.pegasys.teku.api.schema.capella.BeaconBlockBodyCapella; import tech.pegasys.teku.api.schema.capella.BeaconBlockCapella; -import tech.pegasys.teku.api.schema.capella.BeaconStateCapella; import tech.pegasys.teku.api.schema.capella.BlindedBeaconBlockBodyCapella; import tech.pegasys.teku.api.schema.capella.BlindedBlockCapella; import tech.pegasys.teku.api.schema.deneb.BeaconBlockBodyDeneb; import tech.pegasys.teku.api.schema.deneb.BeaconBlockDeneb; -import tech.pegasys.teku.api.schema.deneb.BeaconStateDeneb; import tech.pegasys.teku.api.schema.deneb.BlindedBeaconBlockBodyDeneb; import tech.pegasys.teku.api.schema.deneb.BlindedBlockDeneb; import tech.pegasys.teku.api.schema.electra.BeaconBlockBodyElectra; import tech.pegasys.teku.api.schema.electra.BeaconBlockElectra; -import tech.pegasys.teku.api.schema.electra.BeaconStateElectra; import tech.pegasys.teku.api.schema.electra.BlindedBeaconBlockBodyElectra; import tech.pegasys.teku.api.schema.electra.BlindedBlockElectra; import tech.pegasys.teku.api.schema.phase0.BeaconBlockPhase0; -import tech.pegasys.teku.api.schema.phase0.BeaconStatePhase0; -import tech.pegasys.teku.infrastructure.unsigned.UInt64; import tech.pegasys.teku.spec.Spec; import tech.pegasys.teku.spec.SpecMilestone; @@ -59,21 +49,6 @@ public SchemaObjectProvider(final Spec spec) { this.spec = spec; } - public SignedBeaconBlock getSignedBeaconBlock( - final tech.pegasys.teku.spec.datastructures.blocks.SignedBeaconBlock internalBlock) { - - return new SignedBeaconBlock( - getBeaconBlock(internalBlock.getMessage()), new BLSSignature(internalBlock.getSignature())); - } - - public SignedBeaconBlock getSignedBlindedBeaconBlock( - final tech.pegasys.teku.spec.datastructures.blocks.SignedBeaconBlock internalBlock) { - - return new SignedBeaconBlock( - getBlindedBlock(internalBlock.getMessage()), - new BLSSignature(internalBlock.getSignature())); - } - public BeaconBlock getBeaconBlock( final tech.pegasys.teku.spec.datastructures.blocks.BeaconBlock block) { return getBeaconBlock(block, spec.atSlot(block.getSlot()).getMilestone()); @@ -244,17 +219,4 @@ private BlindedBeaconBlockBodyElectra getBlindedBlockBodyElectra( tech.pegasys.teku.spec.datastructures.blocks.blockbody.versions.electra .BlindedBeaconBlockBodyElectra.required(body)); } - - public BeaconState getBeaconState( - final tech.pegasys.teku.spec.datastructures.state.beaconstate.BeaconState state) { - final UInt64 slot = state.getSlot(); - return switch (spec.atSlot(slot).getMilestone()) { - case PHASE0 -> new BeaconStatePhase0(state); - case ALTAIR -> new BeaconStateAltair(state); - case BELLATRIX -> new BeaconStateBellatrix(state); - case CAPELLA -> new BeaconStateCapella(state); - case DENEB -> new BeaconStateDeneb(state); - case ELECTRA -> new BeaconStateElectra(state); - }; - } } diff --git a/data/provider/src/test/java/tech/pegasys/teku/api/ConfigProviderTest.java b/data/provider/src/test/java/tech/pegasys/teku/api/ConfigProviderTest.java deleted file mode 100644 index db6878f874d..00000000000 --- a/data/provider/src/test/java/tech/pegasys/teku/api/ConfigProviderTest.java +++ /dev/null @@ -1,42 +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; - -import static org.assertj.core.api.Assertions.assertThat; - -import java.util.Map; -import org.junit.jupiter.api.Test; -import tech.pegasys.teku.spec.Spec; -import tech.pegasys.teku.spec.SpecFactory; -import tech.pegasys.teku.spec.config.SpecConfig; -import tech.pegasys.teku.spec.config.SpecConfigLoader; - -class ConfigProviderTest { - private final Spec spec = SpecFactory.create("holesky"); - - private final ConfigProvider configProvider = new ConfigProvider(spec); - - @Test - void shouldParseResultOfConfig() { - final Map configMap = configProvider.getConfig(); - final SpecConfig specConfig = SpecConfigLoader.loadRemoteConfig(configMap); - final SpecConfig expectedConfig = spec.getGenesisSpecConfig(); - assertThat(specConfig).isEqualToComparingFieldByField(expectedConfig); - } - - @Test - void nullInNullOut() { - assertThat(ConfigProvider.formatValue(null)).isNull(); - } -} diff --git a/data/serializer/src/main/java/tech/pegasys/teku/api/schema/package-info.java b/data/serializer/src/main/java/tech/pegasys/teku/api/schema/package-info.java new file mode 100644 index 00000000000..7a0ca0f4fc3 --- /dev/null +++ b/data/serializer/src/main/java/tech/pegasys/teku/api/schema/package-info.java @@ -0,0 +1,5 @@ +/** + * @deprecated As of release 2024.09.00, api.schema is not maintained any longer. + */ +@Deprecated +package tech.pegasys.teku.api.schema; diff --git a/data/serializer/src/main/java/tech/pegasys/teku/provider/BLSPubKeyDeserializer.java b/data/serializer/src/main/java/tech/pegasys/teku/provider/BLSPubKeyDeserializer.java deleted file mode 100644 index 21cddc4ac6a..00000000000 --- a/data/serializer/src/main/java/tech/pegasys/teku/provider/BLSPubKeyDeserializer.java +++ /dev/null @@ -1,29 +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.provider; - -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.JsonDeserializer; -import java.io.IOException; -import org.apache.tuweni.bytes.Bytes; -import tech.pegasys.teku.api.schema.BLSPubKey; - -public class BLSPubKeyDeserializer extends JsonDeserializer { - @Override - public BLSPubKey deserialize(final JsonParser p, final DeserializationContext ctxt) - throws IOException { - return new BLSPubKey(Bytes.fromHexString(p.getValueAsString())); - } -} diff --git a/data/serializer/src/main/java/tech/pegasys/teku/provider/BLSPubKeySerializer.java b/data/serializer/src/main/java/tech/pegasys/teku/provider/BLSPubKeySerializer.java deleted file mode 100644 index d6329260a65..00000000000 --- a/data/serializer/src/main/java/tech/pegasys/teku/provider/BLSPubKeySerializer.java +++ /dev/null @@ -1,30 +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.provider; - -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.databind.JsonSerializer; -import com.fasterxml.jackson.databind.SerializerProvider; -import java.io.IOException; -import java.util.Locale; -import tech.pegasys.teku.api.schema.BLSPubKey; - -public class BLSPubKeySerializer extends JsonSerializer { - @Override - public void serialize( - final BLSPubKey value, final JsonGenerator gen, final SerializerProvider serializers) - throws IOException { - gen.writeString(value.toHexString().toLowerCase(Locale.ROOT)); - } -} diff --git a/data/serializer/src/main/java/tech/pegasys/teku/provider/BLSSignatureDeserializer.java b/data/serializer/src/main/java/tech/pegasys/teku/provider/BLSSignatureDeserializer.java deleted file mode 100644 index 1b258b18a9e..00000000000 --- a/data/serializer/src/main/java/tech/pegasys/teku/provider/BLSSignatureDeserializer.java +++ /dev/null @@ -1,28 +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.provider; - -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.JsonDeserializer; -import java.io.IOException; -import tech.pegasys.teku.api.schema.BLSSignature; - -public class BLSSignatureDeserializer extends JsonDeserializer { - @Override - public BLSSignature deserialize(final JsonParser p, final DeserializationContext ctxt) - throws IOException { - return BLSSignature.fromHexString(p.getValueAsString()); - } -} diff --git a/data/serializer/src/main/java/tech/pegasys/teku/provider/BLSSignatureSerializer.java b/data/serializer/src/main/java/tech/pegasys/teku/provider/BLSSignatureSerializer.java deleted file mode 100644 index abd376ec189..00000000000 --- a/data/serializer/src/main/java/tech/pegasys/teku/provider/BLSSignatureSerializer.java +++ /dev/null @@ -1,30 +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.provider; - -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.databind.JsonSerializer; -import com.fasterxml.jackson.databind.SerializerProvider; -import java.io.IOException; -import java.util.Locale; -import tech.pegasys.teku.api.schema.BLSSignature; - -public class BLSSignatureSerializer extends JsonSerializer { - @Override - public void serialize( - final BLSSignature value, final JsonGenerator gen, final SerializerProvider serializers) - throws IOException { - gen.writeString(value.toHexString().toLowerCase(Locale.ROOT)); - } -} diff --git a/data/serializer/src/main/java/tech/pegasys/teku/provider/GetNewBlindedBlockResponseDeserializer.java b/data/serializer/src/main/java/tech/pegasys/teku/provider/GetNewBlindedBlockResponseDeserializer.java deleted file mode 100644 index 5debd77e176..00000000000 --- a/data/serializer/src/main/java/tech/pegasys/teku/provider/GetNewBlindedBlockResponseDeserializer.java +++ /dev/null @@ -1,60 +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.provider; - -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.JsonDeserializer; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import java.io.IOException; -import java.util.Locale; -import tech.pegasys.teku.api.response.v1.validator.GetNewBlindedBlockResponse; -import tech.pegasys.teku.api.schema.BeaconBlock; -import tech.pegasys.teku.api.schema.Version; -import tech.pegasys.teku.api.schema.altair.BeaconBlockAltair; -import tech.pegasys.teku.api.schema.bellatrix.BlindedBlockBellatrix; -import tech.pegasys.teku.api.schema.phase0.BeaconBlockPhase0; - -public class GetNewBlindedBlockResponseDeserializer - extends JsonDeserializer { - private final ObjectMapper mapper; - - public GetNewBlindedBlockResponseDeserializer(final ObjectMapper mapper) { - this.mapper = mapper; - } - - @Override - public GetNewBlindedBlockResponse deserialize( - final JsonParser jp, final DeserializationContext ctxt) throws IOException { - JsonNode node = jp.getCodec().readTree(jp); - final Version version = - Version.valueOf(node.findValue("version").asText().toLowerCase(Locale.ROOT)); - final BeaconBlock block; - switch (version) { - case bellatrix: - block = mapper.treeToValue(node.findValue("data"), BlindedBlockBellatrix.class); - break; - case altair: - block = mapper.treeToValue(node.findValue("data"), BeaconBlockAltair.class); - break; - case phase0: - block = mapper.treeToValue(node.findValue("data"), BeaconBlockPhase0.class); - break; - default: - throw new IOException("Milestone was not able to be decoded"); - } - return new GetNewBlindedBlockResponse(version, block); - } -} diff --git a/data/serializer/src/main/java/tech/pegasys/teku/provider/GetNewBlockResponseV1Deserializer.java b/data/serializer/src/main/java/tech/pegasys/teku/provider/GetNewBlockResponseV1Deserializer.java deleted file mode 100644 index 2b7a3eeee75..00000000000 --- a/data/serializer/src/main/java/tech/pegasys/teku/provider/GetNewBlockResponseV1Deserializer.java +++ /dev/null @@ -1,40 +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.provider; - -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.JsonDeserializer; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import java.io.IOException; -import tech.pegasys.teku.api.response.v1.validator.GetNewBlockResponse; -import tech.pegasys.teku.api.schema.BeaconBlock; -import tech.pegasys.teku.api.schema.phase0.BeaconBlockPhase0; - -public class GetNewBlockResponseV1Deserializer extends JsonDeserializer { - private final ObjectMapper mapper; - - public GetNewBlockResponseV1Deserializer(final ObjectMapper mapper) { - this.mapper = mapper; - } - - @Override - public GetNewBlockResponse deserialize(final JsonParser jp, final DeserializationContext ctxt) - throws IOException { - JsonNode node = jp.getCodec().readTree(jp); - final BeaconBlock block = mapper.treeToValue(node.findValue("data"), BeaconBlockPhase0.class); - return new GetNewBlockResponse(block); - } -} diff --git a/data/serializer/src/main/java/tech/pegasys/teku/provider/GetNewBlockResponseV2Deserializer.java b/data/serializer/src/main/java/tech/pegasys/teku/provider/GetNewBlockResponseV2Deserializer.java deleted file mode 100644 index 75c9af5af95..00000000000 --- a/data/serializer/src/main/java/tech/pegasys/teku/provider/GetNewBlockResponseV2Deserializer.java +++ /dev/null @@ -1,59 +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.provider; - -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.JsonDeserializer; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import java.io.IOException; -import java.util.Locale; -import tech.pegasys.teku.api.response.v2.validator.GetNewBlockResponseV2; -import tech.pegasys.teku.api.schema.BeaconBlock; -import tech.pegasys.teku.api.schema.Version; -import tech.pegasys.teku.api.schema.altair.BeaconBlockAltair; -import tech.pegasys.teku.api.schema.bellatrix.BeaconBlockBellatrix; -import tech.pegasys.teku.api.schema.phase0.BeaconBlockPhase0; - -public class GetNewBlockResponseV2Deserializer extends JsonDeserializer { - private final ObjectMapper mapper; - - public GetNewBlockResponseV2Deserializer(final ObjectMapper mapper) { - this.mapper = mapper; - } - - @Override - public GetNewBlockResponseV2 deserialize(final JsonParser jp, final DeserializationContext ctxt) - throws IOException { - JsonNode node = jp.getCodec().readTree(jp); - final Version version = - Version.valueOf(node.findValue("version").asText().toLowerCase(Locale.ROOT)); - final BeaconBlock block; - switch (version) { - case bellatrix: - block = mapper.treeToValue(node.findValue("data"), BeaconBlockBellatrix.class); - break; - case altair: - block = mapper.treeToValue(node.findValue("data"), BeaconBlockAltair.class); - break; - case phase0: - block = mapper.treeToValue(node.findValue("data"), BeaconBlockPhase0.class); - break; - default: - throw new IOException("Milestone was not able to be decoded"); - } - return new GetNewBlockResponseV2(version, block); - } -} diff --git a/data/serializer/src/main/java/tech/pegasys/teku/provider/GetStateResponseV2Deserializer.java b/data/serializer/src/main/java/tech/pegasys/teku/provider/GetStateResponseV2Deserializer.java deleted file mode 100644 index 23e71d11bdb..00000000000 --- a/data/serializer/src/main/java/tech/pegasys/teku/provider/GetStateResponseV2Deserializer.java +++ /dev/null @@ -1,56 +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.provider; - -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.JsonDeserializer; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import java.io.IOException; -import java.util.Locale; -import tech.pegasys.teku.api.response.v2.debug.GetStateResponseV2; -import tech.pegasys.teku.api.schema.BeaconState; -import tech.pegasys.teku.api.schema.Version; -import tech.pegasys.teku.api.schema.altair.BeaconStateAltair; -import tech.pegasys.teku.api.schema.phase0.BeaconStatePhase0; - -public class GetStateResponseV2Deserializer extends JsonDeserializer { - private final ObjectMapper mapper; - - public GetStateResponseV2Deserializer(final ObjectMapper mapper) { - this.mapper = mapper; - } - - @Override - public GetStateResponseV2 deserialize(final JsonParser jp, final DeserializationContext ctxt) - throws IOException { - JsonNode node = jp.getCodec().readTree(jp); - final Version version = - Version.valueOf(node.findValue("version").asText().toLowerCase(Locale.ROOT)); - final boolean executionOptimistic = node.findValue("execution_optimistic").asBoolean(); - final BeaconState state; - switch (version) { - case altair: - state = mapper.treeToValue(node.findValue("data"), BeaconStateAltair.class); - break; - case phase0: - state = mapper.treeToValue(node.findValue("data"), BeaconStatePhase0.class); - break; - default: - throw new IOException("Milestone was not able to be decoded"); - } - return new GetStateResponseV2(version, executionOptimistic, state); - } -} diff --git a/data/serializer/src/main/java/tech/pegasys/teku/provider/JsonProvider.java b/data/serializer/src/main/java/tech/pegasys/teku/provider/JsonProvider.java deleted file mode 100644 index 63ff0486c65..00000000000 --- a/data/serializer/src/main/java/tech/pegasys/teku/provider/JsonProvider.java +++ /dev/null @@ -1,135 +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.provider; - -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.core.Version; -import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.module.SimpleModule; -import org.apache.tuweni.bytes.Bytes; -import org.apache.tuweni.bytes.Bytes32; -import org.apache.tuweni.bytes.Bytes48; -import org.apache.tuweni.units.bigints.UInt256; -import tech.pegasys.teku.api.response.v1.validator.GetNewBlindedBlockResponse; -import tech.pegasys.teku.api.response.v1.validator.GetNewBlockResponse; -import tech.pegasys.teku.api.response.v2.debug.GetStateResponseV2; -import tech.pegasys.teku.api.response.v2.validator.GetNewBlockResponseV2; -import tech.pegasys.teku.api.schema.BLSPubKey; -import tech.pegasys.teku.api.schema.BLSSignature; -import tech.pegasys.teku.api.schema.KZGCommitment; -import tech.pegasys.teku.api.schema.KZGProof; -import tech.pegasys.teku.bls.BLSPublicKey; -import tech.pegasys.teku.ethereum.execution.types.Eth1Address; -import tech.pegasys.teku.ethereum.jackson.Eth1AddressDeserializer; -import tech.pegasys.teku.infrastructure.bytes.Bytes20; -import tech.pegasys.teku.infrastructure.bytes.Bytes4; -import tech.pegasys.teku.infrastructure.jackson.deserializers.bytes.ByteArrayDeserializer; -import tech.pegasys.teku.infrastructure.jackson.deserializers.bytes.ByteArraySerializer; -import tech.pegasys.teku.infrastructure.jackson.deserializers.bytes.Bytes20Deserializer; -import tech.pegasys.teku.infrastructure.jackson.deserializers.bytes.Bytes20Serializer; -import tech.pegasys.teku.infrastructure.jackson.deserializers.bytes.Bytes32Deserializer; -import tech.pegasys.teku.infrastructure.jackson.deserializers.bytes.Bytes48KeyDeserializer; -import tech.pegasys.teku.infrastructure.jackson.deserializers.bytes.Bytes4Deserializer; -import tech.pegasys.teku.infrastructure.jackson.deserializers.bytes.Bytes4Serializer; -import tech.pegasys.teku.infrastructure.jackson.deserializers.bytes.BytesDeserializer; -import tech.pegasys.teku.infrastructure.jackson.deserializers.bytes.BytesSerializer; -import tech.pegasys.teku.infrastructure.jackson.deserializers.bytes.DoubleDeserializer; -import tech.pegasys.teku.infrastructure.jackson.deserializers.bytes.DoubleSerializer; -import tech.pegasys.teku.infrastructure.jackson.deserializers.uints.UInt256Deserializer; -import tech.pegasys.teku.infrastructure.jackson.deserializers.uints.UInt256Serializer; -import tech.pegasys.teku.infrastructure.jackson.deserializers.uints.UInt64Deserializer; -import tech.pegasys.teku.infrastructure.jackson.deserializers.uints.UInt64Serializer; -import tech.pegasys.teku.infrastructure.ssz.collections.SszBitvector; -import tech.pegasys.teku.infrastructure.unsigned.UInt64; - -public class JsonProvider { - private void addTekuMappers() { - SimpleModule module = new SimpleModule("TekuJson", new Version(1, 0, 0, null, null, null)); - - module.addSerializer(SszBitvector.class, new SszBitvectorSerializer()); - - module.addSerializer(BLSPubKey.class, new BLSPubKeySerializer()); - module.addDeserializer(BLSPubKey.class, new BLSPubKeyDeserializer()); - module.addDeserializer(BLSPublicKey.class, new BLSPublicKeyDeserializer()); - module.addSerializer(BLSPublicKey.class, new BLSPublicKeySerializer()); - module.addDeserializer(BLSSignature.class, new BLSSignatureDeserializer()); - module.addSerializer(BLSSignature.class, new BLSSignatureSerializer()); - - module.addKeyDeserializer(Bytes48.class, new Bytes48KeyDeserializer()); - - module.addDeserializer(Bytes32.class, new Bytes32Deserializer()); - module.addDeserializer(Bytes4.class, new Bytes4Deserializer()); - module.addSerializer(Bytes4.class, new Bytes4Serializer()); - module.addDeserializer(Bytes20.class, new Bytes20Deserializer()); - module.addDeserializer(Eth1Address.class, new Eth1AddressDeserializer()); - - module.addSerializer(Bytes20.class, new Bytes20Serializer()); - module.addDeserializer(Bytes.class, new BytesDeserializer()); - module.addSerializer(Bytes.class, new BytesSerializer()); - module.addDeserializer(Double.class, new DoubleDeserializer()); - module.addSerializer(Double.class, new DoubleSerializer()); - - module.addDeserializer(UInt64.class, new UInt64Deserializer()); - module.addSerializer(UInt64.class, new UInt64Serializer()); - - module.addDeserializer(UInt256.class, new UInt256Deserializer()); - module.addSerializer(UInt256.class, new UInt256Serializer()); - - module.addSerializer(byte[].class, new ByteArraySerializer()); - module.addDeserializer(byte[].class, new ByteArrayDeserializer()); - - module.addSerializer(KZGCommitment.class, new KZGCommitmentSerializer()); - module.addDeserializer(KZGCommitment.class, new KZGCommitmentDeserializer()); - module.addDeserializer( - GetNewBlockResponse.class, new GetNewBlockResponseV1Deserializer(objectMapper)); - - module.addDeserializer( - GetNewBlockResponseV2.class, new GetNewBlockResponseV2Deserializer(objectMapper)); - module.addDeserializer( - GetStateResponseV2.class, new GetStateResponseV2Deserializer(objectMapper)); - module.addDeserializer( - GetNewBlindedBlockResponse.class, new GetNewBlindedBlockResponseDeserializer(objectMapper)); - - module.addSerializer(KZGProof.class, new KZGProofSerializer()); - module.addDeserializer(KZGProof.class, new KZGProofDeserializer()); - - objectMapper.registerModule(module); - } - - private final ObjectMapper objectMapper; - - public JsonProvider() { - objectMapper = new ObjectMapper(); - objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - addTekuMappers(); - } - - public String objectToJSON(final T object) throws JsonProcessingException { - return objectMapper.writeValueAsString(object); - } - - public String objectToPrettyJSON(final T object) throws JsonProcessingException { - return objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(object); - } - - public T jsonToObject(final String json, final Class clazz) - throws JsonProcessingException { - return objectMapper.readValue(json, clazz); - } - - public ObjectMapper getObjectMapper() { - return objectMapper; - } -} diff --git a/data/serializer/src/main/java/tech/pegasys/teku/provider/KZGCommitmentDeserializer.java b/data/serializer/src/main/java/tech/pegasys/teku/provider/KZGCommitmentDeserializer.java deleted file mode 100644 index 29c75ef3fd1..00000000000 --- a/data/serializer/src/main/java/tech/pegasys/teku/provider/KZGCommitmentDeserializer.java +++ /dev/null @@ -1,29 +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.provider; - -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.JsonDeserializer; -import java.io.IOException; -import org.apache.tuweni.bytes.Bytes; -import tech.pegasys.teku.api.schema.KZGCommitment; - -public class KZGCommitmentDeserializer extends JsonDeserializer { - @Override - public KZGCommitment deserialize(final JsonParser p, final DeserializationContext ctxt) - throws IOException { - return new KZGCommitment(Bytes.fromHexString(p.getValueAsString())); - } -} diff --git a/data/serializer/src/main/java/tech/pegasys/teku/provider/KZGCommitmentSerializer.java b/data/serializer/src/main/java/tech/pegasys/teku/provider/KZGCommitmentSerializer.java deleted file mode 100644 index ef219cfe2fc..00000000000 --- a/data/serializer/src/main/java/tech/pegasys/teku/provider/KZGCommitmentSerializer.java +++ /dev/null @@ -1,30 +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.provider; - -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.databind.JsonSerializer; -import com.fasterxml.jackson.databind.SerializerProvider; -import java.io.IOException; -import java.util.Locale; -import tech.pegasys.teku.api.schema.KZGCommitment; - -public class KZGCommitmentSerializer extends JsonSerializer { - @Override - public void serialize( - final KZGCommitment value, final JsonGenerator gen, final SerializerProvider serializers) - throws IOException { - gen.writeString(value.toHexString().toLowerCase(Locale.ROOT)); - } -} diff --git a/data/serializer/src/main/java/tech/pegasys/teku/provider/KZGProofDeserializer.java b/data/serializer/src/main/java/tech/pegasys/teku/provider/KZGProofDeserializer.java deleted file mode 100644 index 48a221df1e7..00000000000 --- a/data/serializer/src/main/java/tech/pegasys/teku/provider/KZGProofDeserializer.java +++ /dev/null @@ -1,29 +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.provider; - -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.JsonDeserializer; -import java.io.IOException; -import org.apache.tuweni.bytes.Bytes; -import tech.pegasys.teku.api.schema.KZGProof; - -public class KZGProofDeserializer extends JsonDeserializer { - @Override - public KZGProof deserialize(final JsonParser p, final DeserializationContext ignore) - throws IOException { - return new KZGProof(Bytes.fromHexString(p.getValueAsString())); - } -} diff --git a/data/serializer/src/main/java/tech/pegasys/teku/provider/KZGProofSerializer.java b/data/serializer/src/main/java/tech/pegasys/teku/provider/KZGProofSerializer.java deleted file mode 100644 index 60343505098..00000000000 --- a/data/serializer/src/main/java/tech/pegasys/teku/provider/KZGProofSerializer.java +++ /dev/null @@ -1,30 +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.provider; - -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.databind.JsonSerializer; -import com.fasterxml.jackson.databind.SerializerProvider; -import java.io.IOException; -import java.util.Locale; -import tech.pegasys.teku.api.schema.KZGProof; - -public class KZGProofSerializer extends JsonSerializer { - @Override - public void serialize( - final KZGProof value, final JsonGenerator gen, final SerializerProvider serializers) - throws IOException { - gen.writeString(value.toHexString().toLowerCase(Locale.ROOT)); - } -} diff --git a/data/serializer/src/main/java/tech/pegasys/teku/provider/SszBitvectorSerializer.java b/data/serializer/src/main/java/tech/pegasys/teku/provider/SszBitvectorSerializer.java deleted file mode 100644 index af7c94eb838..00000000000 --- a/data/serializer/src/main/java/tech/pegasys/teku/provider/SszBitvectorSerializer.java +++ /dev/null @@ -1,30 +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.provider; - -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.databind.JsonSerializer; -import com.fasterxml.jackson.databind.SerializerProvider; -import java.io.IOException; -import java.util.Locale; -import tech.pegasys.teku.infrastructure.ssz.collections.SszBitvector; - -public class SszBitvectorSerializer extends JsonSerializer { - @Override - public void serialize( - final SszBitvector value, final JsonGenerator gen, final SerializerProvider serializers) - throws IOException { - gen.writeString(value.sszSerialize().toHexString().toLowerCase(Locale.ROOT)); - } -} diff --git a/data/serializer/src/property-test/java/tech/pegasys/teku/provider/JsonProviderPropertyTest.java b/data/serializer/src/property-test/java/tech/pegasys/teku/provider/JsonProviderPropertyTest.java deleted file mode 100644 index 287565f5dba..00000000000 --- a/data/serializer/src/property-test/java/tech/pegasys/teku/provider/JsonProviderPropertyTest.java +++ /dev/null @@ -1,428 +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.provider; - -import static java.nio.charset.StandardCharsets.UTF_8; -import static org.apache.commons.lang3.StringEscapeUtils.unescapeJava; -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.assertEquals; - -import com.fasterxml.jackson.core.JsonProcessingException; -import java.lang.reflect.Constructor; -import java.util.Arrays; -import java.util.Locale; -import java.util.Map; -import net.jqwik.api.ForAll; -import net.jqwik.api.Property; -import net.jqwik.api.constraints.IntRange; -import net.jqwik.api.constraints.Size; -import org.apache.commons.lang3.ArrayUtils; -import org.apache.tuweni.bytes.Bytes; -import org.apache.tuweni.bytes.Bytes32; -import org.apache.tuweni.units.bigints.UInt256; -import tech.pegasys.teku.api.schema.Attestation; -import tech.pegasys.teku.api.schema.AttestationData; -import tech.pegasys.teku.api.schema.AttesterSlashing; -import tech.pegasys.teku.api.schema.BLSPubKey; -import tech.pegasys.teku.api.schema.BLSSignature; -import tech.pegasys.teku.api.schema.BeaconBlockHeader; -import tech.pegasys.teku.api.schema.BeaconState; -import tech.pegasys.teku.api.schema.Checkpoint; -import tech.pegasys.teku.api.schema.Deposit; -import tech.pegasys.teku.api.schema.DepositData; -import tech.pegasys.teku.api.schema.Eth1Data; -import tech.pegasys.teku.api.schema.Fork; -import tech.pegasys.teku.api.schema.IndexedAttestation; -import tech.pegasys.teku.api.schema.KZGCommitment; -import tech.pegasys.teku.api.schema.PendingAttestation; -import tech.pegasys.teku.api.schema.ProposerSlashing; -import tech.pegasys.teku.api.schema.SignedBeaconBlock; -import tech.pegasys.teku.api.schema.Validator; -import tech.pegasys.teku.api.schema.VoluntaryExit; -import tech.pegasys.teku.api.schema.altair.BeaconStateAltair; -import tech.pegasys.teku.api.schema.altair.SignedBeaconBlockAltair; -import tech.pegasys.teku.api.schema.bellatrix.BeaconStateBellatrix; -import tech.pegasys.teku.api.schema.bellatrix.SignedBeaconBlockBellatrix; -import tech.pegasys.teku.api.schema.capella.BeaconStateCapella; -import tech.pegasys.teku.api.schema.capella.SignedBeaconBlockCapella; -import tech.pegasys.teku.api.schema.deneb.BeaconStateDeneb; -import tech.pegasys.teku.api.schema.deneb.SignedBeaconBlockDeneb; -import tech.pegasys.teku.api.schema.electra.BeaconStateElectra; -import tech.pegasys.teku.api.schema.electra.SignedBeaconBlockElectra; -import tech.pegasys.teku.api.schema.phase0.BeaconStatePhase0; -import tech.pegasys.teku.api.schema.phase0.SignedBeaconBlockPhase0; -import tech.pegasys.teku.infrastructure.json.JsonUtil; -import tech.pegasys.teku.infrastructure.json.types.DeserializableTypeDefinition; -import tech.pegasys.teku.infrastructure.ssz.SszData; -import tech.pegasys.teku.infrastructure.ssz.collections.SszBitvector; -import tech.pegasys.teku.infrastructure.unsigned.UInt64; -import tech.pegasys.teku.spec.Spec; -import tech.pegasys.teku.spec.SpecMilestone; -import tech.pegasys.teku.spec.TestSpecFactory; -import tech.pegasys.teku.spec.networks.Eth2Network; -import tech.pegasys.teku.spec.propertytest.suppliers.SpecSupplier; -import tech.pegasys.teku.spec.util.DataStructureUtil; - -public class JsonProviderPropertyTest { - private static final String Q = "\""; - private final JsonProvider jsonProvider = new JsonProvider(); - - private static final Map> - SIGNED_BEACON_BLOCK_CLASS_MAP = - Map.of( - SpecMilestone.PHASE0, - SignedBeaconBlockPhase0.class, - SpecMilestone.ALTAIR, - SignedBeaconBlockAltair.class, - SpecMilestone.BELLATRIX, - SignedBeaconBlockBellatrix.class, - SpecMilestone.CAPELLA, - SignedBeaconBlockCapella.class, - SpecMilestone.DENEB, - SignedBeaconBlockDeneb.class, - SpecMilestone.ELECTRA, - SignedBeaconBlockElectra.class); - - private static final Map> BEACON_STATE_CLASS_MAP = - Map.of( - SpecMilestone.PHASE0, - BeaconStatePhase0.class, - SpecMilestone.ALTAIR, - BeaconStateAltair.class, - SpecMilestone.BELLATRIX, - BeaconStateBellatrix.class, - SpecMilestone.CAPELLA, - BeaconStateCapella.class, - SpecMilestone.DENEB, - BeaconStateDeneb.class, - SpecMilestone.ELECTRA, - BeaconStateElectra.class); - - @Property - void roundTripBytes32(@ForAll @Size(32) final byte[] value) throws JsonProcessingException { - Bytes32 data = Bytes32.wrap(value); - String serialized = jsonProvider.objectToJSON(data); - assertEquals(Q + data.toHexString().toLowerCase(Locale.ROOT) + Q, serialized); - Bytes32 deserialize = jsonProvider.jsonToObject(serialized, Bytes32.class); - assertEquals(data, deserialize); - } - - @Property - void roundTripUInt256(@ForAll @Size(32) final byte[] value) throws JsonProcessingException { - final Bytes bytes = Bytes.wrap(value); - final UInt256 original = UInt256.fromBytes(bytes); - final String serialized = jsonProvider.objectToJSON(original); - assertEquals(serialized, Q + original.toDecimalString() + Q); - final UInt256 deserialized = jsonProvider.jsonToObject(serialized, UInt256.class); - assertEquals(deserialized, original); - } - - @Property - void roundTripUInt64(@ForAll final long value) throws JsonProcessingException { - final UInt64 original = UInt64.fromLongBits(value); - final String serialized = jsonProvider.objectToJSON(original); - assertEquals(serialized, Q + original.toString() + Q); - final UInt64 deserialized = jsonProvider.jsonToObject(serialized, UInt64.class); - assertEquals(deserialized, original); - } - - @Property - void serializeString(@ForAll final String original) throws JsonProcessingException { - final String serialized = jsonProvider.objectToJSON(original); - assertThat(unescapeJava(serialized).getBytes(UTF_8)) - .isEqualTo((Q + original + Q).getBytes(UTF_8)); - } - - @Property - void roundTripByteArray(@ForAll final byte[] original) throws JsonProcessingException { - final String serialized = jsonProvider.objectToJSON(original); - assertEquals(serialized, byteArrayToUnsignedStringWithQuotesAndNoSpaces(original)); - final byte[] deserialized = jsonProvider.jsonToObject(serialized, byte[].class); - assertThat(deserialized).isEqualTo(original); - } - - static String byteArrayToUnsignedStringWithQuotesAndNoSpaces(final byte[] bytes) { - return Arrays.toString( - Arrays.asList(ArrayUtils.toObject(bytes)).stream() - .map(Byte::toUnsignedInt) - .map(s -> Q + s + Q) - .toArray()) - .replace(" ", ""); - } - - @Property - void roundTripBlsPubKey( - @ForAll final int seed, @ForAll(supplier = SpecSupplier.class) final Spec spec) - throws JsonProcessingException { - final DataStructureUtil dataStructureUtil = new DataStructureUtil(seed, spec); - final BLSPubKey original = new BLSPubKey(dataStructureUtil.randomPublicKey()); - final String serialized = jsonProvider.objectToJSON(original); - final BLSPubKey deserialized = jsonProvider.jsonToObject(serialized, BLSPubKey.class); - assertThat(deserialized).isEqualTo(original); - } - - @Property - void roundTripBlsSignature( - @ForAll final int seed, @ForAll(supplier = SpecSupplier.class) final Spec spec) - throws JsonProcessingException { - final DataStructureUtil dataStructureUtil = new DataStructureUtil(seed, spec); - final BLSSignature original = new BLSSignature(dataStructureUtil.randomSignature()); - final String serialized = jsonProvider.objectToJSON(original); - final BLSSignature deserialized = jsonProvider.jsonToObject(serialized, BLSSignature.class); - assertThat(deserialized).isEqualTo(original); - } - - @Property - public void roundTripBitVector( - @ForAll final int seed, - @ForAll(supplier = SpecSupplier.class) final Spec spec, - @ForAll @IntRange(min = 1, max = 1000) final int size) - throws JsonProcessingException { - final DataStructureUtil dataStructureUtil = new DataStructureUtil(seed, spec); - final SszBitvector original = dataStructureUtil.randomSszBitvector(size); - final String serialized = jsonProvider.objectToJSON(original); - final SszBitvector deserialized = - JsonUtil.parse(serialized, original.getSchema().getJsonTypeDefinition()); - assertThat(deserialized).isEqualTo(original); - } - - @Property - public void roundTripFork( - @ForAll final int seed, @ForAll(supplier = SpecSupplier.class) final Spec spec) - throws JsonProcessingException { - final DataStructureUtil dataStructureUtil = new DataStructureUtil(seed, spec); - final Fork original = new Fork(dataStructureUtil.randomFork()); - final String serialized = jsonProvider.objectToJSON(original); - final Object deserialized = jsonProvider.jsonToObject(serialized, Fork.class); - assertThat(deserialized).isEqualToComparingFieldByField(original); - } - - @Property - public void roundTripCheckpoint( - @ForAll final int seed, - @ForAll(supplier = SpecSupplier.class) final Spec spec, - @ForAll final long epoch) - throws JsonProcessingException { - final DataStructureUtil dataStructureUtil = new DataStructureUtil(seed, spec); - final Checkpoint original = - new Checkpoint(dataStructureUtil.randomCheckpoint(UInt64.fromLongBits(epoch))); - final String serialized = jsonProvider.objectToJSON(original); - final Object deserialized = jsonProvider.jsonToObject(serialized, Checkpoint.class); - assertThat(deserialized).isEqualToComparingFieldByField(original); - } - - @Property - public void roundTripValidator( - @ForAll final int seed, @ForAll(supplier = SpecSupplier.class) final Spec spec) - throws JsonProcessingException { - final DataStructureUtil dataStructureUtil = new DataStructureUtil(seed, spec); - final Validator original = new Validator(dataStructureUtil.randomValidator()); - final String serialized = jsonProvider.objectToJSON(original); - final Object deserialized = jsonProvider.jsonToObject(serialized, Validator.class); - assertThat(deserialized).isEqualToComparingFieldByField(original); - } - - @Property - public void roundTripAttestationData( - @ForAll final int seed, @ForAll(supplier = SpecSupplier.class) final Spec spec) - throws JsonProcessingException { - final DataStructureUtil dataStructureUtil = new DataStructureUtil(seed, spec); - final AttestationData original = new AttestationData(dataStructureUtil.randomAttestationData()); - final String serialized = jsonProvider.objectToJSON(original); - final Object deserialized = jsonProvider.jsonToObject(serialized, AttestationData.class); - assertThat(deserialized).isEqualToComparingFieldByField(original); - } - - @Property - public void roundTripIndexedAttestation( - @ForAll final int seed, @ForAll(supplier = SpecSupplier.class) final Spec spec) - throws JsonProcessingException { - final DataStructureUtil dataStructureUtil = new DataStructureUtil(seed, spec); - final IndexedAttestation original = - new IndexedAttestation(dataStructureUtil.randomIndexedAttestation()); - final String serialized = jsonProvider.objectToJSON(original); - final Object deserialized = jsonProvider.jsonToObject(serialized, IndexedAttestation.class); - assertThat(deserialized).isEqualToComparingFieldByField(original); - } - - @Property - public void roundTripPendingAttestation(@ForAll final int seed, @ForAll final Eth2Network network) - throws JsonProcessingException { - final SpecMilestone specMilestone = SpecMilestone.PHASE0; - final Spec spec = TestSpecFactory.create(specMilestone, network); - final DataStructureUtil dataStructureUtil = new DataStructureUtil(seed, spec); - final PendingAttestation original = - new PendingAttestation(dataStructureUtil.randomPendingAttestation()); - final String serialized = jsonProvider.objectToJSON(original); - final Object deserialized = jsonProvider.jsonToObject(serialized, PendingAttestation.class); - assertThat(deserialized).isEqualToComparingFieldByField(original); - } - - @Property - public void roundTripEth1Data( - @ForAll final int seed, @ForAll(supplier = SpecSupplier.class) final Spec spec) - throws JsonProcessingException { - final DataStructureUtil dataStructureUtil = new DataStructureUtil(seed, spec); - final Eth1Data original = new Eth1Data(dataStructureUtil.randomEth1Data()); - final String serialized = jsonProvider.objectToJSON(original); - final Object deserialized = jsonProvider.jsonToObject(serialized, Eth1Data.class); - assertThat(deserialized).isEqualToComparingFieldByField(original); - } - - @Property - public void roundTripDepositData( - @ForAll final int seed, @ForAll(supplier = SpecSupplier.class) final Spec spec) - throws JsonProcessingException { - final DataStructureUtil dataStructureUtil = new DataStructureUtil(seed, spec); - final DepositData original = new DepositData(dataStructureUtil.randomDepositData()); - final String serialized = jsonProvider.objectToJSON(original); - final Object deserialized = jsonProvider.jsonToObject(serialized, DepositData.class); - assertThat(deserialized).isEqualToComparingFieldByField(original); - } - - @Property - public void roundTripBeaconBlockHeader( - @ForAll final int seed, @ForAll(supplier = SpecSupplier.class) final Spec spec) - throws JsonProcessingException { - final DataStructureUtil dataStructureUtil = new DataStructureUtil(seed, spec); - final BeaconBlockHeader original = - new BeaconBlockHeader(dataStructureUtil.randomBeaconBlockHeader()); - final String serialized = jsonProvider.objectToJSON(original); - final Object deserialized = jsonProvider.jsonToObject(serialized, BeaconBlockHeader.class); - assertThat(deserialized).isEqualToComparingFieldByField(original); - } - - @Property - public void roundTripBeaconProposerSlashing( - @ForAll final int seed, @ForAll(supplier = SpecSupplier.class) final Spec spec) - throws JsonProcessingException { - final DataStructureUtil dataStructureUtil = new DataStructureUtil(seed, spec); - final ProposerSlashing original = - new ProposerSlashing(dataStructureUtil.randomProposerSlashing()); - final String serialized = jsonProvider.objectToJSON(original); - final Object deserialized = jsonProvider.jsonToObject(serialized, ProposerSlashing.class); - assertThat(deserialized).isEqualToComparingFieldByField(original); - } - - @Property - public void roundTripBeaconAttesterSlashing( - @ForAll final int seed, @ForAll(supplier = SpecSupplier.class) final Spec spec) - throws JsonProcessingException { - final DataStructureUtil dataStructureUtil = new DataStructureUtil(seed, spec); - final AttesterSlashing original = - new AttesterSlashing(dataStructureUtil.randomAttesterSlashing()); - final String serialized = jsonProvider.objectToJSON(original); - final Object deserialized = jsonProvider.jsonToObject(serialized, AttesterSlashing.class); - assertThat(deserialized).isEqualToComparingFieldByField(original); - } - - @Property - public void roundTripBeaconAttestation( - @ForAll final int seed, @ForAll(supplier = SpecSupplier.class) final Spec spec) - throws JsonProcessingException { - final DataStructureUtil dataStructureUtil = new DataStructureUtil(seed, spec); - final Attestation original = new Attestation(dataStructureUtil.randomAttestation()); - final String serialized = jsonProvider.objectToJSON(original); - final Object deserialized = jsonProvider.jsonToObject(serialized, Attestation.class); - assertThat(deserialized).isEqualToComparingFieldByField(original); - } - - @Property - public void roundTripDeposit( - @ForAll final int seed, @ForAll(supplier = SpecSupplier.class) final Spec spec) - throws JsonProcessingException { - final DataStructureUtil dataStructureUtil = new DataStructureUtil(seed, spec); - final Deposit original = new Deposit(dataStructureUtil.randomDeposit()); - final String serialized = jsonProvider.objectToJSON(original); - final Object deserialized = jsonProvider.jsonToObject(serialized, Deposit.class); - assertThat(deserialized).isEqualToComparingFieldByField(original); - } - - @Property - public void roundTripVoluntaryExit( - @ForAll final int seed, @ForAll(supplier = SpecSupplier.class) final Spec spec) - throws JsonProcessingException { - final DataStructureUtil dataStructureUtil = new DataStructureUtil(seed, spec); - final VoluntaryExit original = new VoluntaryExit(dataStructureUtil.randomVoluntaryExit()); - final String serialized = jsonProvider.objectToJSON(original); - final Object deserialized = jsonProvider.jsonToObject(serialized, VoluntaryExit.class); - assertThat(deserialized).isEqualToComparingFieldByField(original); - } - - @Property(tries = 100) - public void roundTripSignedBeaconBlock( - @ForAll final int seed, - @ForAll(supplier = SpecSupplier.class) final Spec spec, - @ForAll final long slot, - @ForAll @Size(32) final byte[] parentRoot, - @ForAll @Size(32) final byte[] stateRoot, - @ForAll final boolean isFull) - throws Exception { - final DataStructureUtil dataStructureUtil = new DataStructureUtil(seed, spec); - final Class clazz = - SIGNED_BEACON_BLOCK_CLASS_MAP.get(spec.getForkSchedule().getHighestSupportedMilestone()); - final Constructor constructor = - clazz.getConstructor(tech.pegasys.teku.spec.datastructures.blocks.SignedBeaconBlock.class); - final Object original = - constructor.newInstance( - dataStructureUtil.signedBlock( - dataStructureUtil.randomBeaconBlock( - UInt64.fromLongBits(slot), - Bytes32.wrap(parentRoot), - Bytes32.wrap(stateRoot), - isFull))); - final String serialized = jsonProvider.objectToJSON(original); - final Object deserialized = jsonProvider.jsonToObject(serialized, clazz); - assertThat(deserialized).isEqualToComparingFieldByField(original); - } - - @Property(tries = 100) - public void roundTripBeaconState( - @ForAll final int seed, - @ForAll(supplier = SpecSupplier.class) final Spec spec, - @ForAll @IntRange(max = 1000) final int validatorCount, - @ForAll @IntRange(max = 1000) final int numItemsInSSZLists) - throws Exception { - final SpecMilestone specMilestone = spec.getForkSchedule().getHighestSupportedMilestone(); - final DataStructureUtil dataStructureUtil = new DataStructureUtil(seed, spec); - final Class clazz = BEACON_STATE_CLASS_MAP.get(specMilestone); - final Constructor constructor = - clazz.getConstructor( - tech.pegasys.teku.spec.datastructures.state.beaconstate.BeaconState.class); - final BeaconState original = - constructor.newInstance( - dataStructureUtil.randomBeaconState(validatorCount, numItemsInSSZLists)); - final DeserializableTypeDefinition stateTypeDefinition = - spec.forMilestone(specMilestone) - .getSchemaDefinitions() - .getBeaconStateSchema() - .getJsonTypeDefinition(); - - final String serialized = jsonProvider.objectToJSON(original); - final SszData deserialized = JsonUtil.parse(serialized, stateTypeDefinition); - assertThat(deserialized.hashTreeRoot()) - .isEqualTo(original.asInternalBeaconState(spec).hashTreeRoot()); - } - - @Property - void roundTripKZGCommitment(@ForAll final int seed) throws JsonProcessingException { - final SpecMilestone specMilestone = SpecMilestone.DENEB; - final Spec spec = TestSpecFactory.create(specMilestone, Eth2Network.MINIMAL); - final DataStructureUtil dataStructureUtil = new DataStructureUtil(seed, spec); - final KZGCommitment original = new KZGCommitment(dataStructureUtil.randomKZGCommitment()); - final String serialized = jsonProvider.objectToJSON(original); - final KZGCommitment deserialized = jsonProvider.jsonToObject(serialized, KZGCommitment.class); - assertThat(deserialized).isEqualTo(original); - } -} diff --git a/data/serializer/src/test/java/tech/pegasys/teku/provider/JsonProviderTest.java b/data/serializer/src/test/java/tech/pegasys/teku/provider/JsonProviderTest.java deleted file mode 100644 index 0d093028591..00000000000 --- a/data/serializer/src/test/java/tech/pegasys/teku/provider/JsonProviderTest.java +++ /dev/null @@ -1,183 +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.provider; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import com.fasterxml.jackson.core.JsonProcessingException; -import java.util.Locale; -import org.apache.tuweni.bytes.Bytes; -import org.apache.tuweni.bytes.Bytes32; -import org.apache.tuweni.units.bigints.UInt256; -import org.junit.jupiter.api.Test; -import tech.pegasys.teku.api.schema.BeaconState; -import tech.pegasys.teku.api.schema.phase0.BeaconStatePhase0; -import tech.pegasys.teku.infrastructure.ssz.collections.SszBitvector; -import tech.pegasys.teku.infrastructure.unsigned.UInt64; -import tech.pegasys.teku.spec.TestSpecFactory; -import tech.pegasys.teku.spec.util.DataStructureUtil; - -class JsonProviderTest { - private static final String Q = "\""; - private final DataStructureUtil dataStructureUtil = - new DataStructureUtil(TestSpecFactory.createDefault()); - private final JsonProvider jsonProvider = new JsonProvider(); - - @Test - public void bytes32ShouldSerializeToJsonAndBack() throws JsonProcessingException { - Bytes32 data = Bytes32.random(); - String serialized = jsonProvider.objectToJSON(data); - assertEquals(Q + data.toHexString().toLowerCase(Locale.ROOT) + Q, serialized); - - Bytes32 deserialize = jsonProvider.jsonToObject(serialized, Bytes32.class); - assertEquals(data, deserialize); - } - - @Test - public void minUInt256ShouldSerializeAndDeserialize() throws JsonProcessingException { - final UInt256 data = UInt256.ZERO; - final String serialized = jsonProvider.objectToJSON(data); - assertEquals(serialized, Q + "0" + Q); - final UInt256 data2 = jsonProvider.jsonToObject(serialized, UInt256.class); - assertEquals(data2, data); - } - - @Test - public void UInt64ShouldSerializeAndDeserialize() throws JsonProcessingException { - final UInt64 data = dataStructureUtil.randomUInt64(); - final String serialized = jsonProvider.objectToJSON(data); - assertEquals(serialized, Q + data.toString() + Q); - final UInt64 data2 = jsonProvider.jsonToObject(serialized, UInt64.class); - assertEquals(data2, data); - } - - @Test - public void maxUInt64ShouldSerializeAndDeserialize() throws JsonProcessingException { - final UInt64 data = UInt64.MAX_VALUE; - final String serialized = jsonProvider.objectToJSON(data); - assertEquals(serialized, Q + data.toString() + Q); - final UInt64 data2 = jsonProvider.jsonToObject(serialized, UInt64.class); - assertEquals(data2, data); - } - - @Test - public void UInt256ShouldSerializeAndDeserialize() throws JsonProcessingException { - final UInt256 data = dataStructureUtil.randomUInt256(); - final String serialized = jsonProvider.objectToJSON(data); - assertEquals(serialized, Q + data.toDecimalString() + Q); - final UInt256 data2 = jsonProvider.jsonToObject(serialized, UInt256.class); - assertEquals(data2, data); - } - - @Test - public void maxUInt256ShouldSerializeAndDeserialize() throws JsonProcessingException { - final UInt256 data = UInt256.MAX_VALUE; - final String serialized = jsonProvider.objectToJSON(data); - assertEquals(serialized, Q + data.toDecimalString() + Q); - final UInt256 data2 = jsonProvider.jsonToObject(serialized, UInt256.class); - assertEquals(data2, data); - } - - @Test - public void UInt64ShouldDeserializeNonHex() throws JsonProcessingException { - final UInt256 data = jsonProvider.jsonToObject("10", UInt256.class); - assertEquals(data, UInt256.fromHexString("0xa")); - } - - @Test - public void bitVectorShouldSerializeAsSsz() throws JsonProcessingException { - final int bitvectorSize = 40; - final SszBitvector data = dataStructureUtil.randomSszBitvector(bitvectorSize); - final String asJson = jsonProvider.objectToJSON(data); - final String hexData = jsonProvider.jsonToObject(asJson, String.class); - final SszBitvector asData = data.getSchema().sszDeserialize(Bytes.fromHexString(hexData)); - - assertThat(data).isEqualTo(asData); - assertThat(asData.size()).isEqualTo(bitvectorSize); - } - - @Test - public void doubleShouldSerializeAndDeserialize() throws JsonProcessingException { - Double fewDecimals = 1.4; - final String serializedFewDecimals = jsonProvider.objectToJSON(fewDecimals); - final Double deserializedFewDecimals = - jsonProvider.jsonToObject(serializedFewDecimals, Double.class); - assertThat(fewDecimals).isEqualTo(deserializedFewDecimals); - - Double multipleDecimals = 1.41234; - Double truncatedMultipleDecimals = 1.4123; - final String serializedMultipleDecimals = jsonProvider.objectToJSON(multipleDecimals); - final Double deserializedMultipleDecimals = - jsonProvider.jsonToObject(serializedMultipleDecimals, Double.class); - assertThat(truncatedMultipleDecimals).isEqualTo(deserializedMultipleDecimals); - } - - @Test - public void stringShouldSerializeToJson() throws JsonProcessingException { - String data = "test"; - assertEquals(Q + data + Q, jsonProvider.objectToJSON(data)); - } - - @Test - public void byteArrayShouldSerializeToJson() throws JsonProcessingException { - final byte[] bytes = Bytes.fromHexString("0x00A0F0FF").toArray(); - assertEquals("[\"0\",\"160\",\"240\",\"255\"]", jsonProvider.objectToJSON(bytes)); - } - - @Test - public void zeroLengthByteArrayShouldSerializeToJson() throws JsonProcessingException { - assertEquals("[]", jsonProvider.objectToJSON(new byte[0])); - } - - @Test - public void deserializeToBytesShouldAllowZeroLengthArray() throws JsonProcessingException { - assertThat(jsonProvider.jsonToObject("[]", byte[].class)).isEqualTo(new byte[0]); - } - - @Test - public void deserializeToBytesShouldHandleSignedBits() throws JsonProcessingException { - assertThat(jsonProvider.jsonToObject("[\"0\",\"160\",\"240\",\"255\"]", byte[].class)) - .isEqualTo(Bytes.fromHexString("0x00A0F0FF").toArray()); - } - - @Test - public void deserializeToBytesShouldRejectValuesThatAreTooLarge() { - assertThatThrownBy(() -> jsonProvider.jsonToObject("[\"256\"]", byte[].class)) - .hasMessage("Expected \"256\" to be a byte value between 0 and 255 inclusive"); - } - - @Test - public void deserializeToBytesShouldRejectValuesThatAreBelowZero() { - assertThatThrownBy(() -> jsonProvider.jsonToObject("[\"-999\"]", byte[].class)) - .hasMessage("Expected \"-999\" to be a byte value between 0 and 255 inclusive"); - } - - @Test - public void deserializeToBytesShouldRejectValuesThatNotNumeric() { - assertThatThrownBy(() -> jsonProvider.jsonToObject("[\"a\"]", byte[].class)) - .hasMessage("Expected \"a\" to be a byte value between 0 and 255 inclusive"); - } - - @Test - void beaconStateJsonTest() throws JsonProcessingException { - tech.pegasys.teku.spec.datastructures.state.beaconstate.BeaconState stateInternal = - dataStructureUtil.randomBeaconState(UInt64.valueOf(16)); - BeaconState state = new BeaconStatePhase0(stateInternal); - String jsonState = jsonProvider.objectToJSON(state); - assertTrue(jsonState.length() > 0); - } -} diff --git a/ethereum/weaksubjectivity/src/test/java/tech/pegasys/teku/weaksubjectivity/config/WeakSubjectivityConfigTest.java b/ethereum/weaksubjectivity/src/test/java/tech/pegasys/teku/weaksubjectivity/config/WeakSubjectivityConfigTest.java index 00d7d4287fa..7c0c5fc1422 100644 --- a/ethereum/weaksubjectivity/src/test/java/tech/pegasys/teku/weaksubjectivity/config/WeakSubjectivityConfigTest.java +++ b/ethereum/weaksubjectivity/src/test/java/tech/pegasys/teku/weaksubjectivity/config/WeakSubjectivityConfigTest.java @@ -66,7 +66,7 @@ public void updated_shouldCloneAllProperties() { WeakSubjectivityConfig configB = configA.updated((__) -> {}); assertThat(configA).isEqualTo(configB); - assertThat(configA).isEqualToComparingFieldByField(configB); + assertThat(configA).isEqualTo(configB); } @Test From 73977371a7b179e181e854daac4c58f105619c5d Mon Sep 17 00:00:00 2001 From: Paul Harris Date: Thu, 10 Oct 2024 08:02:43 +1000 Subject: [PATCH 4/9] move deserializers that we use from api schema (#8699) Signed-off-by: Paul Harris --- .../proposerconfig/loader}/BLSPublicKeyDeserializer.java | 4 ++-- .../client/proposerconfig/loader}/BLSPublicKeySerializer.java | 4 ++-- .../client/proposerconfig/loader/ProposerConfigLoader.java | 2 -- 3 files changed, 4 insertions(+), 6 deletions(-) rename {data/serializer/src/main/java/tech/pegasys/teku/provider => validator/client/src/main/java/tech/pegasys/teku/validator/client/proposerconfig/loader}/BLSPublicKeyDeserializer.java (88%) rename {data/serializer/src/main/java/tech/pegasys/teku/provider => validator/client/src/main/java/tech/pegasys/teku/validator/client/proposerconfig/loader}/BLSPublicKeySerializer.java (89%) diff --git a/data/serializer/src/main/java/tech/pegasys/teku/provider/BLSPublicKeyDeserializer.java b/validator/client/src/main/java/tech/pegasys/teku/validator/client/proposerconfig/loader/BLSPublicKeyDeserializer.java similarity index 88% rename from data/serializer/src/main/java/tech/pegasys/teku/provider/BLSPublicKeyDeserializer.java rename to validator/client/src/main/java/tech/pegasys/teku/validator/client/proposerconfig/loader/BLSPublicKeyDeserializer.java index f99c5cfc50c..d859f3ef5a3 100644 --- a/data/serializer/src/main/java/tech/pegasys/teku/provider/BLSPublicKeyDeserializer.java +++ b/validator/client/src/main/java/tech/pegasys/teku/validator/client/proposerconfig/loader/BLSPublicKeyDeserializer.java @@ -11,7 +11,7 @@ * specific language governing permissions and limitations under the License. */ -package tech.pegasys.teku.provider; +package tech.pegasys.teku.validator.client.proposerconfig.loader; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.databind.DeserializationContext; @@ -19,7 +19,7 @@ import java.io.IOException; import tech.pegasys.teku.bls.BLSPublicKey; -public class BLSPublicKeyDeserializer extends JsonDeserializer { +class BLSPublicKeyDeserializer extends JsonDeserializer { @Override public BLSPublicKey deserialize(final JsonParser p, final DeserializationContext ctxt) throws IOException { diff --git a/data/serializer/src/main/java/tech/pegasys/teku/provider/BLSPublicKeySerializer.java b/validator/client/src/main/java/tech/pegasys/teku/validator/client/proposerconfig/loader/BLSPublicKeySerializer.java similarity index 89% rename from data/serializer/src/main/java/tech/pegasys/teku/provider/BLSPublicKeySerializer.java rename to validator/client/src/main/java/tech/pegasys/teku/validator/client/proposerconfig/loader/BLSPublicKeySerializer.java index a133ee4fe28..d7d48bea2dd 100644 --- a/data/serializer/src/main/java/tech/pegasys/teku/provider/BLSPublicKeySerializer.java +++ b/validator/client/src/main/java/tech/pegasys/teku/validator/client/proposerconfig/loader/BLSPublicKeySerializer.java @@ -11,7 +11,7 @@ * specific language governing permissions and limitations under the License. */ -package tech.pegasys.teku.provider; +package tech.pegasys.teku.validator.client.proposerconfig.loader; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.JsonSerializer; @@ -20,7 +20,7 @@ import java.util.Locale; import tech.pegasys.teku.bls.BLSPublicKey; -public class BLSPublicKeySerializer extends JsonSerializer { +class BLSPublicKeySerializer extends JsonSerializer { @Override public void serialize( final BLSPublicKey value, final JsonGenerator gen, final SerializerProvider serializers) diff --git a/validator/client/src/main/java/tech/pegasys/teku/validator/client/proposerconfig/loader/ProposerConfigLoader.java b/validator/client/src/main/java/tech/pegasys/teku/validator/client/proposerconfig/loader/ProposerConfigLoader.java index 5f871d9811a..543025c9317 100644 --- a/validator/client/src/main/java/tech/pegasys/teku/validator/client/proposerconfig/loader/ProposerConfigLoader.java +++ b/validator/client/src/main/java/tech/pegasys/teku/validator/client/proposerconfig/loader/ProposerConfigLoader.java @@ -28,8 +28,6 @@ import tech.pegasys.teku.infrastructure.exceptions.InvalidConfigurationException; import tech.pegasys.teku.infrastructure.http.UrlSanitizer; import tech.pegasys.teku.infrastructure.jackson.deserializers.bytes.Bytes48KeyDeserializer; -import tech.pegasys.teku.provider.BLSPublicKeyDeserializer; -import tech.pegasys.teku.provider.BLSPublicKeySerializer; import tech.pegasys.teku.validator.client.ProposerConfig; public class ProposerConfigLoader { From 21e76dda94ad723a85e36b7d0c43ff3cc4f627dd Mon Sep 17 00:00:00 2001 From: Lucas Saldanha Date: Thu, 10 Oct 2024 11:26:10 +1300 Subject: [PATCH 5/9] Updated GetPayloadV4 with executionRequests decoding (#8698) --- .../methods/EngineGetPayloadV4.java | 15 ++++++++- .../schema/GetPayloadV4Response.java | 22 +++++++++++-- .../methods/EngineGetPayloadV4Test.java | 27 +++++++++++++--- .../ElectraExecutionClientHandlerTest.java | 12 ++++--- .../execution/GetPayloadResponse.java | 32 +++++++++++++++++-- .../electra/ExecutionRequestsDataCodec.java | 32 ++++++++++++------- .../teku/spec/util/DataStructureUtil.java | 11 +++++++ 7 files changed, 125 insertions(+), 26 deletions(-) diff --git a/ethereum/executionclient/src/main/java/tech/pegasys/teku/ethereum/executionclient/methods/EngineGetPayloadV4.java b/ethereum/executionclient/src/main/java/tech/pegasys/teku/ethereum/executionclient/methods/EngineGetPayloadV4.java index cedf1fbe2aa..60a1fbd62fa 100644 --- a/ethereum/executionclient/src/main/java/tech/pegasys/teku/ethereum/executionclient/methods/EngineGetPayloadV4.java +++ b/ethereum/executionclient/src/main/java/tech/pegasys/teku/ethereum/executionclient/methods/EngineGetPayloadV4.java @@ -21,25 +21,35 @@ import tech.pegasys.teku.infrastructure.async.SafeFuture; import tech.pegasys.teku.infrastructure.unsigned.UInt64; import tech.pegasys.teku.spec.Spec; +import tech.pegasys.teku.spec.SpecMilestone; import tech.pegasys.teku.spec.datastructures.blobs.versions.deneb.BlobSchema; import tech.pegasys.teku.spec.datastructures.execution.BlobsBundle; import tech.pegasys.teku.spec.datastructures.execution.ExecutionPayload; import tech.pegasys.teku.spec.datastructures.execution.ExecutionPayloadContext; import tech.pegasys.teku.spec.datastructures.execution.ExecutionPayloadSchema; import tech.pegasys.teku.spec.datastructures.execution.GetPayloadResponse; +import tech.pegasys.teku.spec.datastructures.execution.versions.electra.ExecutionRequests; +import tech.pegasys.teku.spec.datastructures.execution.versions.electra.ExecutionRequestsDataCodec; import tech.pegasys.teku.spec.schemas.SchemaDefinitions; import tech.pegasys.teku.spec.schemas.SchemaDefinitionsBellatrix; import tech.pegasys.teku.spec.schemas.SchemaDefinitionsDeneb; +import tech.pegasys.teku.spec.schemas.SchemaDefinitionsElectra; public class EngineGetPayloadV4 extends AbstractEngineJsonRpcMethod { private static final Logger LOG = LogManager.getLogger(); private final Spec spec; + private final ExecutionRequestsDataCodec executionRequestsDataDecoder; public EngineGetPayloadV4(final ExecutionEngineClient executionEngineClient, final Spec spec) { super(executionEngineClient); this.spec = spec; + this.executionRequestsDataDecoder = + new ExecutionRequestsDataCodec( + SchemaDefinitionsElectra.required( + spec.forMilestone(SpecMilestone.ELECTRA).getSchemaDefinitions()) + .getExecutionRequestsSchema()); } @Override @@ -76,11 +86,14 @@ public SafeFuture execute(final JsonRpcRequestParams params) final ExecutionPayload executionPayload = response.executionPayload.asInternalExecutionPayload(payloadSchema); final BlobsBundle blobsBundle = getBlobsBundle(response, schemaDefinitions); + final ExecutionRequests executionRequests = + executionRequestsDataDecoder.decode(response.executionRequests); return new GetPayloadResponse( executionPayload, response.blockValue, blobsBundle, - response.shouldOverrideBuilder); + response.shouldOverrideBuilder, + executionRequests); }) .thenPeek( getPayloadResponse -> diff --git a/ethereum/executionclient/src/main/java/tech/pegasys/teku/ethereum/executionclient/schema/GetPayloadV4Response.java b/ethereum/executionclient/src/main/java/tech/pegasys/teku/ethereum/executionclient/schema/GetPayloadV4Response.java index e414321626b..8ee030d0c53 100644 --- a/ethereum/executionclient/src/main/java/tech/pegasys/teku/ethereum/executionclient/schema/GetPayloadV4Response.java +++ b/ethereum/executionclient/src/main/java/tech/pegasys/teku/ethereum/executionclient/schema/GetPayloadV4Response.java @@ -18,12 +18,18 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import java.util.List; +import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.units.bigints.UInt256; +import tech.pegasys.teku.ethereum.executionclient.serialization.BytesDeserializer; +import tech.pegasys.teku.ethereum.executionclient.serialization.BytesSerializer; import tech.pegasys.teku.ethereum.executionclient.serialization.UInt256AsHexDeserializer; import tech.pegasys.teku.ethereum.executionclient.serialization.UInt256AsHexSerializer; import tech.pegasys.teku.spec.datastructures.blobs.versions.deneb.BlobSchema; import tech.pegasys.teku.spec.datastructures.execution.ExecutionPayloadSchema; import tech.pegasys.teku.spec.datastructures.execution.GetPayloadResponse; +import tech.pegasys.teku.spec.datastructures.execution.versions.electra.ExecutionRequestsDataCodec; +import tech.pegasys.teku.spec.datastructures.execution.versions.electra.ExecutionRequestsSchema; public class GetPayloadV4Response { public final ExecutionPayloadV3 executionPayload; @@ -36,26 +42,36 @@ public class GetPayloadV4Response { public final boolean shouldOverrideBuilder; + @JsonSerialize(contentUsing = BytesSerializer.class) + @JsonDeserialize(contentUsing = BytesDeserializer.class) + public final List executionRequests; + public GetPayloadV4Response( final @JsonProperty("executionPayload") ExecutionPayloadV3 executionPayload, final @JsonProperty("blockValue") UInt256 blockValue, final @JsonProperty("blobsBundle") BlobsBundleV1 blobsBundle, - final @JsonProperty("shouldOverrideBuilder") boolean shouldOverrideBuilder) { + final @JsonProperty("shouldOverrideBuilder") boolean shouldOverrideBuilder, + final @JsonProperty("executionRequests") List executionRequests) { checkNotNull(executionPayload, "executionPayload"); checkNotNull(blockValue, "blockValue"); checkNotNull(blobsBundle, "blobsBundle"); + checkNotNull(executionRequests, "executionRequests"); this.executionPayload = executionPayload; this.blockValue = blockValue; this.blobsBundle = blobsBundle; this.shouldOverrideBuilder = shouldOverrideBuilder; + this.executionRequests = executionRequests; } public GetPayloadResponse asInternalGetPayloadResponse( - final ExecutionPayloadSchema executionPayloadSchema, final BlobSchema blobSchema) { + final ExecutionPayloadSchema executionPayloadSchema, + final BlobSchema blobSchema, + final ExecutionRequestsSchema executionRequestsSchema) { return new GetPayloadResponse( executionPayload.asInternalExecutionPayload(executionPayloadSchema), blockValue, blobsBundle.asInternalBlobsBundle(blobSchema), - shouldOverrideBuilder); + shouldOverrideBuilder, + new ExecutionRequestsDataCodec(executionRequestsSchema).decode(executionRequests)); } } diff --git a/ethereum/executionclient/src/test/java/tech/pegasys/teku/ethereum/executionclient/methods/EngineGetPayloadV4Test.java b/ethereum/executionclient/src/test/java/tech/pegasys/teku/ethereum/executionclient/methods/EngineGetPayloadV4Test.java index 160f7ba0d49..860e2c2bb51 100644 --- a/ethereum/executionclient/src/test/java/tech/pegasys/teku/ethereum/executionclient/methods/EngineGetPayloadV4Test.java +++ b/ethereum/executionclient/src/test/java/tech/pegasys/teku/ethereum/executionclient/methods/EngineGetPayloadV4Test.java @@ -23,8 +23,10 @@ import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; +import java.util.List; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; +import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.units.bigints.UInt256; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -37,12 +39,16 @@ import tech.pegasys.teku.infrastructure.async.SafeFuture; import tech.pegasys.teku.infrastructure.unsigned.UInt64; import tech.pegasys.teku.spec.Spec; +import tech.pegasys.teku.spec.SpecMilestone; import tech.pegasys.teku.spec.TestSpecFactory; import tech.pegasys.teku.spec.datastructures.execution.BlobsBundle; import tech.pegasys.teku.spec.datastructures.execution.ExecutionPayload; import tech.pegasys.teku.spec.datastructures.execution.ExecutionPayloadContext; import tech.pegasys.teku.spec.datastructures.execution.GetPayloadResponse; import tech.pegasys.teku.spec.datastructures.execution.versions.deneb.ExecutionPayloadDeneb; +import tech.pegasys.teku.spec.datastructures.execution.versions.electra.ExecutionRequests; +import tech.pegasys.teku.spec.datastructures.execution.versions.electra.ExecutionRequestsDataCodec; +import tech.pegasys.teku.spec.schemas.SchemaDefinitionsElectra; import tech.pegasys.teku.spec.util.DataStructureUtil; class EngineGetPayloadV4Test { @@ -50,6 +56,11 @@ class EngineGetPayloadV4Test { private final Spec spec = TestSpecFactory.createMinimalElectra(); private final DataStructureUtil dataStructureUtil = new DataStructureUtil(spec); private final ExecutionEngineClient executionEngineClient = mock(ExecutionEngineClient.class); + private final ExecutionRequestsDataCodec executionRequestsDataCodec = + new ExecutionRequestsDataCodec( + SchemaDefinitionsElectra.required( + spec.forMilestone(SpecMilestone.ELECTRA).getSchemaDefinitions()) + .getExecutionRequestsSchema()); private EngineGetPayloadV4 jsonRpcMethod; @BeforeEach @@ -117,10 +128,15 @@ public void shouldCallGetPayloadV4AndParseResponseSuccessfully() { final UInt256 blockValue = UInt256.MAX_VALUE; final BlobsBundle blobsBundle = dataStructureUtil.randomBlobsBundle(); final ExecutionPayload executionPayloadElectra = dataStructureUtil.randomExecutionPayload(); + final ExecutionRequests executionRequests = dataStructureUtil.randomExecutionRequests(); + final List encodedExecutionRequests = + executionRequestsDataCodec.encodeWithoutTypePrefix(executionRequests); assertThat(executionPayloadElectra).isInstanceOf(ExecutionPayloadDeneb.class); when(executionEngineClient.getPayloadV4(eq(executionPayloadContext.getPayloadId()))) - .thenReturn(dummySuccessfulResponse(executionPayloadElectra, blockValue, blobsBundle)); + .thenReturn( + dummySuccessfulResponse( + executionPayloadElectra, blockValue, blobsBundle, encodedExecutionRequests)); final JsonRpcRequestParams params = new JsonRpcRequestParams.Builder().add(executionPayloadContext).add(UInt64.ZERO).build(); @@ -128,7 +144,8 @@ public void shouldCallGetPayloadV4AndParseResponseSuccessfully() { jsonRpcMethod = new EngineGetPayloadV4(executionEngineClient, spec); final GetPayloadResponse expectedGetPayloadResponse = - new GetPayloadResponse(executionPayloadElectra, blockValue, blobsBundle, false); + new GetPayloadResponse( + executionPayloadElectra, blockValue, blobsBundle, false, executionRequests); assertThat(jsonRpcMethod.execute(params)).isCompletedWithValue(expectedGetPayloadResponse); verify(executionEngineClient).getPayloadV4(eq(executionPayloadContext.getPayloadId())); @@ -138,14 +155,16 @@ public void shouldCallGetPayloadV4AndParseResponseSuccessfully() { private SafeFuture> dummySuccessfulResponse( final ExecutionPayload executionPayload, final UInt256 blockValue, - final BlobsBundle blobsBundle) { + final BlobsBundle blobsBundle, + final List encodedExecutionRequests) { return SafeFuture.completedFuture( new Response<>( new GetPayloadV4Response( ExecutionPayloadV3.fromInternalExecutionPayload(executionPayload), blockValue, BlobsBundleV1.fromInternalBlobsBundle(blobsBundle), - false))); + false, + encodedExecutionRequests))); } private SafeFuture> dummyFailedResponse( diff --git a/ethereum/executionlayer/src/test/java/tech/pegasys/teku/ethereum/executionlayer/ElectraExecutionClientHandlerTest.java b/ethereum/executionlayer/src/test/java/tech/pegasys/teku/ethereum/executionlayer/ElectraExecutionClientHandlerTest.java index a0b10002bd7..0bd039d2d65 100644 --- a/ethereum/executionlayer/src/test/java/tech/pegasys/teku/ethereum/executionlayer/ElectraExecutionClientHandlerTest.java +++ b/ethereum/executionlayer/src/test/java/tech/pegasys/teku/ethereum/executionlayer/ElectraExecutionClientHandlerTest.java @@ -70,7 +70,8 @@ void engineGetPayload_shouldCallGetPayloadV4() { dataStructureUtil.randomExecutionPayload()), UInt256.MAX_VALUE, BlobsBundleV1.fromInternalBlobsBundle(dataStructureUtil.randomBlobsBundle()), - true); + true, + dataStructureUtil.randomEncodedExecutionRequests()); final SafeFuture> dummyResponse = SafeFuture.completedFuture(new Response<>(responseData)); when(executionEngineClient.getPayloadV4(context.getPayloadId())).thenReturn(dummyResponse); @@ -83,9 +84,12 @@ void engineGetPayload_shouldCallGetPayloadV4() { final ExecutionPayloadSchema executionPayloadSchema = schemaDefinitionElectra.getExecutionPayloadSchema(); final BlobSchema blobSchema = schemaDefinitionElectra.getBlobSchema(); - assertThat(future) - .isCompletedWithValue( - responseData.asInternalGetPayloadResponse(executionPayloadSchema, blobSchema)); + final GetPayloadResponse expectedGetPayloadResponse = + responseData.asInternalGetPayloadResponse( + executionPayloadSchema, + blobSchema, + schemaDefinitionElectra.getExecutionRequestsSchema()); + assertThat(future).isCompletedWithValue(expectedGetPayloadResponse); } @Test diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/execution/GetPayloadResponse.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/execution/GetPayloadResponse.java index 49076414a51..52ef3bb38ac 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/execution/GetPayloadResponse.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/execution/GetPayloadResponse.java @@ -17,6 +17,7 @@ import java.util.Objects; import java.util.Optional; import org.apache.tuweni.units.bigints.UInt256; +import tech.pegasys.teku.spec.datastructures.execution.versions.electra.ExecutionRequests; public class GetPayloadResponse { @@ -24,12 +25,14 @@ public class GetPayloadResponse { private final UInt256 executionPayloadValue; private final Optional blobsBundle; private final boolean shouldOverrideBuilder; + private final Optional executionRequests; public GetPayloadResponse(final ExecutionPayload executionPayload) { this.executionPayload = executionPayload; this.executionPayloadValue = UInt256.ZERO; this.blobsBundle = Optional.empty(); this.shouldOverrideBuilder = false; + this.executionRequests = Optional.empty(); } public GetPayloadResponse( @@ -38,6 +41,7 @@ public GetPayloadResponse( this.executionPayloadValue = executionPayloadValue; this.blobsBundle = Optional.empty(); this.shouldOverrideBuilder = false; + this.executionRequests = Optional.empty(); } public GetPayloadResponse( @@ -49,6 +53,20 @@ public GetPayloadResponse( this.executionPayloadValue = executionPayloadValue; this.blobsBundle = Optional.of(blobsBundle); this.shouldOverrideBuilder = shouldOverrideBuilder; + this.executionRequests = Optional.empty(); + } + + public GetPayloadResponse( + final ExecutionPayload executionPayload, + final UInt256 executionPayloadValue, + final BlobsBundle blobsBundle, + final boolean shouldOverrideBuilder, + final ExecutionRequests executionRequests) { + this.executionPayload = executionPayload; + this.executionPayloadValue = executionPayloadValue; + this.blobsBundle = Optional.of(blobsBundle); + this.shouldOverrideBuilder = shouldOverrideBuilder; + this.executionRequests = Optional.of(executionRequests); } public ExecutionPayload getExecutionPayload() { @@ -67,6 +85,10 @@ public boolean getShouldOverrideBuilder() { return shouldOverrideBuilder; } + public Optional getExecutionRequests() { + return executionRequests; + } + @Override public boolean equals(final Object o) { if (this == o) { @@ -79,13 +101,18 @@ public boolean equals(final Object o) { return shouldOverrideBuilder == that.shouldOverrideBuilder && Objects.equals(executionPayload, that.executionPayload) && Objects.equals(executionPayloadValue, that.executionPayloadValue) - && Objects.equals(blobsBundle, that.blobsBundle); + && Objects.equals(blobsBundle, that.blobsBundle) + && Objects.equals(executionRequests, that.executionRequests); } @Override public int hashCode() { return Objects.hash( - executionPayload, executionPayloadValue, blobsBundle, shouldOverrideBuilder); + executionPayload, + executionPayloadValue, + blobsBundle, + shouldOverrideBuilder, + executionRequests); } @Override @@ -95,6 +122,7 @@ public String toString() { .add("executionPayloadValue", executionPayloadValue) .add("blobsBundle", blobsBundle) .add("shouldOverrideBuilder", shouldOverrideBuilder) + .add("executionRequests", executionRequests) .toString(); } } diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/execution/versions/electra/ExecutionRequestsDataCodec.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/execution/versions/electra/ExecutionRequestsDataCodec.java index a31930f38c7..1e51ad64264 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/execution/versions/electra/ExecutionRequestsDataCodec.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/execution/versions/electra/ExecutionRequestsDataCodec.java @@ -78,8 +78,17 @@ public ExecutionRequests decode(final List executionRequestData) { return executionRequestsBuilder.build(); } + public Bytes32 hash(final ExecutionRequests executionRequests) { + final Bytes sortedEncodedRequests = + encodeWithTypePrefix(executionRequests).stream() + .map(Hash::sha256) + .map(Bytes.class::cast) + .reduce(Bytes.EMPTY, Bytes::concatenate); + return Hash.sha256(sortedEncodedRequests); + } + @VisibleForTesting - List encodeWithTypePrefix(final ExecutionRequests executionRequests) { + public List encodeWithoutTypePrefix(final ExecutionRequests executionRequests) { final SszList depositRequestsSszList = executionRequestsSchema .getDepositRequestsSchema() @@ -94,18 +103,17 @@ List encodeWithTypePrefix(final ExecutionRequests executionRequests) { .createFromElements(executionRequests.getConsolidations()); return List.of( - Bytes.concatenate(DEPOSIT_REQUEST_PREFIX, depositRequestsSszList.sszSerialize()), - Bytes.concatenate(WITHDRAWAL_REQUEST_PREFIX, withdrawalRequestsSszList.sszSerialize()), - Bytes.concatenate( - CONSOLIDATION_REQUEST_PREFIX, consolidationRequestsSszList.sszSerialize())); + depositRequestsSszList.sszSerialize(), + withdrawalRequestsSszList.sszSerialize(), + consolidationRequestsSszList.sszSerialize()); } - public Bytes32 hash(final ExecutionRequests executionRequests) { - final Bytes sortedEncodedRequests = - encodeWithTypePrefix(executionRequests).stream() - .map(Hash::sha256) - .map(Bytes.class::cast) - .reduce(Bytes.EMPTY, Bytes::concatenate); - return Hash.sha256(sortedEncodedRequests); + @VisibleForTesting + List encodeWithTypePrefix(final ExecutionRequests executionRequests) { + final List encodeWithoutTypePrefix = encodeWithoutTypePrefix(executionRequests); + return List.of( + Bytes.concatenate(DEPOSIT_REQUEST_PREFIX, encodeWithoutTypePrefix.get(0)), + Bytes.concatenate(WITHDRAWAL_REQUEST_PREFIX, encodeWithoutTypePrefix.get(1)), + Bytes.concatenate(CONSOLIDATION_REQUEST_PREFIX, encodeWithoutTypePrefix.get(2))); } } diff --git a/ethereum/spec/src/testFixtures/java/tech/pegasys/teku/spec/util/DataStructureUtil.java b/ethereum/spec/src/testFixtures/java/tech/pegasys/teku/spec/util/DataStructureUtil.java index 8a46648f436..98c31a885e7 100644 --- a/ethereum/spec/src/testFixtures/java/tech/pegasys/teku/spec/util/DataStructureUtil.java +++ b/ethereum/spec/src/testFixtures/java/tech/pegasys/teku/spec/util/DataStructureUtil.java @@ -132,6 +132,8 @@ import tech.pegasys.teku.spec.datastructures.execution.versions.electra.DepositRequest; import tech.pegasys.teku.spec.datastructures.execution.versions.electra.ExecutionRequests; import tech.pegasys.teku.spec.datastructures.execution.versions.electra.ExecutionRequestsBuilderElectra; +import tech.pegasys.teku.spec.datastructures.execution.versions.electra.ExecutionRequestsDataCodec; +import tech.pegasys.teku.spec.datastructures.execution.versions.electra.ExecutionRequestsSchema; import tech.pegasys.teku.spec.datastructures.execution.versions.electra.WithdrawalRequest; import tech.pegasys.teku.spec.datastructures.forkchoice.VoteTracker; import tech.pegasys.teku.spec.datastructures.lightclient.LightClientBootstrap; @@ -2504,6 +2506,15 @@ public ExecutionRequests randomExecutionRequests() { .build(); } + public List randomEncodedExecutionRequests() { + final ExecutionRequestsSchema executionRequestsSchema = + SchemaDefinitionsElectra.required( + spec.forMilestone(SpecMilestone.ELECTRA).getSchemaDefinitions()) + .getExecutionRequestsSchema(); + return new ExecutionRequestsDataCodec(executionRequestsSchema) + .encodeWithoutTypePrefix(randomExecutionRequests()); + } + public WithdrawalRequest randomWithdrawalRequest() { return getElectraSchemaDefinitions(randomSlot()) .getWithdrawalRequestSchema() From 0067d57e97dbe143c6e23a9b8d3925591e19dcf5 Mon Sep 17 00:00:00 2001 From: Lucas Saldanha Date: Thu, 10 Oct 2024 14:16:46 +1300 Subject: [PATCH 6/9] Add executionRequestHash to NewPayloadRequest as part of block validation flow (#8700) --- .../electra/block/BlockProcessorElectra.java | 30 +++++++++++ .../block/BlockProcessorElectraTest.java | 51 +++++++++++++++++++ 2 files changed, 81 insertions(+) diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/electra/block/BlockProcessorElectra.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/electra/block/BlockProcessorElectra.java index 83ce065d599..ed5a8a7b684 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/electra/block/BlockProcessorElectra.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/electra/block/BlockProcessorElectra.java @@ -30,6 +30,7 @@ import tech.pegasys.teku.bls.BLSSignature; import tech.pegasys.teku.ethereum.execution.types.Eth1Address; import tech.pegasys.teku.infrastructure.bytes.Bytes20; +import tech.pegasys.teku.infrastructure.ssz.SszList; import tech.pegasys.teku.infrastructure.ssz.SszMutableList; import tech.pegasys.teku.infrastructure.ssz.collections.SszBitlist; import tech.pegasys.teku.infrastructure.ssz.primitive.SszByte; @@ -41,11 +42,14 @@ import tech.pegasys.teku.spec.config.SpecConfigElectra; import tech.pegasys.teku.spec.datastructures.blocks.blockbody.BeaconBlockBody; import tech.pegasys.teku.spec.datastructures.blocks.blockbody.versions.electra.BeaconBlockBodyElectra; +import tech.pegasys.teku.spec.datastructures.execution.ExecutionPayload; import tech.pegasys.teku.spec.datastructures.execution.ExecutionPayloadSummary; import tech.pegasys.teku.spec.datastructures.execution.ExpectedWithdrawals; +import tech.pegasys.teku.spec.datastructures.execution.NewPayloadRequest; import tech.pegasys.teku.spec.datastructures.execution.versions.electra.ConsolidationRequest; import tech.pegasys.teku.spec.datastructures.execution.versions.electra.DepositRequest; import tech.pegasys.teku.spec.datastructures.execution.versions.electra.ExecutionRequests; +import tech.pegasys.teku.spec.datastructures.execution.versions.electra.ExecutionRequestsDataCodec; import tech.pegasys.teku.spec.datastructures.execution.versions.electra.WithdrawalRequest; import tech.pegasys.teku.spec.datastructures.operations.Attestation; import tech.pegasys.teku.spec.datastructures.operations.Deposit; @@ -56,6 +60,7 @@ import tech.pegasys.teku.spec.datastructures.state.beaconstate.versions.electra.MutableBeaconStateElectra; import tech.pegasys.teku.spec.datastructures.state.versions.electra.PendingConsolidation; import tech.pegasys.teku.spec.datastructures.state.versions.electra.PendingDeposit; +import tech.pegasys.teku.spec.datastructures.type.SszKZGCommitment; import tech.pegasys.teku.spec.datastructures.type.SszPublicKey; import tech.pegasys.teku.spec.datastructures.type.SszSignature; import tech.pegasys.teku.spec.logic.common.helpers.BeaconStateMutators.ValidatorExitContext; @@ -70,6 +75,7 @@ import tech.pegasys.teku.spec.logic.common.util.SyncCommitteeUtil; import tech.pegasys.teku.spec.logic.common.util.ValidatorsUtil; import tech.pegasys.teku.spec.logic.versions.deneb.block.BlockProcessorDeneb; +import tech.pegasys.teku.spec.logic.versions.deneb.types.VersionedHash; import tech.pegasys.teku.spec.logic.versions.electra.helpers.BeaconStateAccessorsElectra; import tech.pegasys.teku.spec.logic.versions.electra.helpers.BeaconStateMutatorsElectra; import tech.pegasys.teku.spec.logic.versions.electra.helpers.MiscHelpersElectra; @@ -85,6 +91,7 @@ public class BlockProcessorElectra extends BlockProcessorDeneb { private final BeaconStateMutatorsElectra beaconStateMutatorsElectra; private final BeaconStateAccessorsElectra beaconStateAccessorsElectra; private final SchemaDefinitionsElectra schemaDefinitionsElectra; + private final ExecutionRequestsDataCodec executionRequestsDataCodec; public BlockProcessorElectra( final SpecConfigElectra specConfig, @@ -117,6 +124,29 @@ public BlockProcessorElectra( this.beaconStateMutatorsElectra = beaconStateMutators; this.beaconStateAccessorsElectra = beaconStateAccessors; this.schemaDefinitionsElectra = schemaDefinitions; + this.executionRequestsDataCodec = + new ExecutionRequestsDataCodec(schemaDefinitions.getExecutionRequestsSchema()); + } + + @Override + public NewPayloadRequest computeNewPayloadRequest( + final BeaconState state, final BeaconBlockBody beaconBlockBody) + throws BlockProcessingException { + final ExecutionPayload executionPayload = extractExecutionPayload(beaconBlockBody); + final SszList blobKzgCommitments = extractBlobKzgCommitments(beaconBlockBody); + final List versionedHashes = + blobKzgCommitments.stream() + .map(SszKZGCommitment::getKZGCommitment) + .map(miscHelpers::kzgCommitmentToVersionedHash) + .toList(); + final Bytes32 parentBeaconBlockRoot = state.getLatestBlockHeader().getParentRoot(); + final ExecutionRequests executionRequests = + BeaconBlockBodyElectra.required(beaconBlockBody).getExecutionRequests(); + return new NewPayloadRequest( + executionPayload, + versionedHashes, + parentBeaconBlockRoot, + executionRequestsDataCodec.hash(executionRequests)); } @Override diff --git a/ethereum/spec/src/test/java/tech/pegasys/teku/spec/logic/versions/electra/block/BlockProcessorElectraTest.java b/ethereum/spec/src/test/java/tech/pegasys/teku/spec/logic/versions/electra/block/BlockProcessorElectraTest.java index 9d3dd4b9500..3add055fa7f 100644 --- a/ethereum/spec/src/test/java/tech/pegasys/teku/spec/logic/versions/electra/block/BlockProcessorElectraTest.java +++ b/ethereum/spec/src/test/java/tech/pegasys/teku/spec/logic/versions/electra/block/BlockProcessorElectraTest.java @@ -20,6 +20,7 @@ import java.util.List; import java.util.function.Supplier; +import java.util.stream.Collectors; import java.util.stream.IntStream; import org.apache.tuweni.bytes.Bytes32; import org.junit.jupiter.api.Test; @@ -28,11 +29,16 @@ import tech.pegasys.teku.infrastructure.ssz.primitive.SszUInt64; import tech.pegasys.teku.infrastructure.unsigned.UInt64; import tech.pegasys.teku.spec.Spec; +import tech.pegasys.teku.spec.SpecMilestone; import tech.pegasys.teku.spec.TestSpecFactory; +import tech.pegasys.teku.spec.config.SpecConfigDeneb; import tech.pegasys.teku.spec.config.SpecConfigElectra; import tech.pegasys.teku.spec.datastructures.blocks.Eth1Data; import tech.pegasys.teku.spec.datastructures.blocks.blockbody.BeaconBlockBody; +import tech.pegasys.teku.spec.datastructures.blocks.blockbody.versions.electra.BeaconBlockBodyElectra; +import tech.pegasys.teku.spec.datastructures.execution.NewPayloadRequest; import tech.pegasys.teku.spec.datastructures.execution.versions.electra.DepositRequest; +import tech.pegasys.teku.spec.datastructures.execution.versions.electra.ExecutionRequestsDataCodec; import tech.pegasys.teku.spec.datastructures.execution.versions.electra.WithdrawalRequest; import tech.pegasys.teku.spec.datastructures.operations.DepositData; import tech.pegasys.teku.spec.datastructures.state.Validator; @@ -40,10 +46,14 @@ import tech.pegasys.teku.spec.datastructures.state.beaconstate.versions.electra.BeaconStateElectra; import tech.pegasys.teku.spec.datastructures.state.beaconstate.versions.electra.MutableBeaconStateElectra; import tech.pegasys.teku.spec.datastructures.state.versions.electra.PendingPartialWithdrawal; +import tech.pegasys.teku.spec.datastructures.type.SszKZGCommitment; import tech.pegasys.teku.spec.logic.common.helpers.BeaconStateMutators.ValidatorExitContext; +import tech.pegasys.teku.spec.logic.common.helpers.MiscHelpers; import tech.pegasys.teku.spec.logic.common.statetransition.exceptions.BlockProcessingException; import tech.pegasys.teku.spec.logic.versions.deneb.block.BlockProcessorDenebTest; +import tech.pegasys.teku.spec.logic.versions.deneb.types.VersionedHash; import tech.pegasys.teku.spec.logic.versions.electra.util.AttestationUtilElectra; +import tech.pegasys.teku.spec.schemas.SchemaDefinitionsElectra; class BlockProcessorElectraTest extends BlockProcessorDenebTest { @@ -524,6 +534,40 @@ void shouldUseElectraAttestationUtil() { .isInstanceOf(AttestationUtilElectra.class); } + @Test + public void shouldCreateNewPayloadRequestWithExecutionRequestsHash() throws Exception { + final BeaconState preState = createBeaconState(); + final BeaconBlockBodyElectra blockBody = + BeaconBlockBodyElectra.required(dataStructureUtil.randomBeaconBlockBodyWithCommitments(3)); + final MiscHelpers miscHelpers = spec.atSlot(UInt64.ONE).miscHelpers(); + final List expectedVersionedHashes = + blockBody.getOptionalBlobKzgCommitments().orElseThrow().stream() + .map(SszKZGCommitment::getKZGCommitment) + .map(miscHelpers::kzgCommitmentToVersionedHash) + .collect(Collectors.toList()); + final Bytes32 expectedExecutionRequestsHash = + getExecutionRequestsDataCodec().hash(blockBody.getExecutionRequests()); + + final NewPayloadRequest newPayloadRequest = + spec.getBlockProcessor(UInt64.ONE).computeNewPayloadRequest(preState, blockBody); + + assertThat(newPayloadRequest.getExecutionPayload()) + .isEqualTo(blockBody.getOptionalExecutionPayload().orElseThrow()); + assertThat(newPayloadRequest.getVersionedHashes()).isPresent(); + assertThat(newPayloadRequest.getVersionedHashes().get()) + .hasSize(3) + .allSatisfy( + versionedHash -> + assertThat(versionedHash.getVersion()) + .isEqualTo(SpecConfigDeneb.VERSIONED_HASH_VERSION_KZG)) + .hasSameElementsAs(expectedVersionedHashes); + assertThat(newPayloadRequest.getParentBeaconBlockRoot()).isPresent(); + assertThat(newPayloadRequest.getParentBeaconBlockRoot().get()) + .isEqualTo(preState.getLatestBlockHeader().getParentRoot()); + assertThat(newPayloadRequest.getExecutionRequestsHash()) + .hasValue(expectedExecutionRequestsHash); + } + private Supplier validatorExitContextSupplier(final BeaconState state) { return spec.getGenesisSpec().beaconStateMutators().createValidatorExitContextSupplier(state); } @@ -531,4 +575,11 @@ private Supplier validatorExitContextSupplier(final Beacon private BlockProcessorElectra getBlockProcessor(final BeaconState state) { return (BlockProcessorElectra) spec.getBlockProcessor(state.getSlot()); } + + private ExecutionRequestsDataCodec getExecutionRequestsDataCodec() { + return new ExecutionRequestsDataCodec( + SchemaDefinitionsElectra.required( + spec.forMilestone(SpecMilestone.ELECTRA).getSchemaDefinitions()) + .getExecutionRequestsSchema()); + } } From a416449331439d559bf9a44ded43187bfeaafb55 Mon Sep 17 00:00:00 2001 From: Stefan Bratanov Date: Thu, 10 Oct 2024 10:38:44 +0800 Subject: [PATCH 7/9] Refactor ExecutionPayloadResult (#8702) --- .../execution/ExecutionPayloadResult.java | 93 ++++++++----------- 1 file changed, 39 insertions(+), 54 deletions(-) diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/execution/ExecutionPayloadResult.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/execution/ExecutionPayloadResult.java index c9f6b6e2364..497003d00b4 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/execution/ExecutionPayloadResult.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/execution/ExecutionPayloadResult.java @@ -21,31 +21,37 @@ import tech.pegasys.teku.spec.datastructures.builder.BuilderBid; /** - * In non-blinded flow, both {@link #executionPayloadFuture} and {@link #blobsBundleFuture} would be - * present. The {@link #blobsBundleFuture} will have a value when the future is complete only after - * Deneb, otherwise it will be empty. + * In non-blinded flow, {@link #getPayloadResponseFuture} will be present. * - *

In blinded flow, {@link #builderBidOrFallbackDataFuture} would be present + *

In blinded flow, {@link #builderBidOrFallbackDataFuture} would be present. */ public class ExecutionPayloadResult { private final ExecutionPayloadContext executionPayloadContext; - private final Optional> executionPayloadFuture; - private final Optional>> blobsBundleFuture; + private final Optional> getPayloadResponseFuture; private final Optional> builderBidOrFallbackDataFuture; - private final SafeFuture executionPayloadValueFuture; private ExecutionPayloadResult( final ExecutionPayloadContext executionPayloadContext, - final Optional> executionPayloadFuture, - final Optional>> blobsBundleFuture, - final Optional> builderBidOrFallbackDataFuture, - final SafeFuture executionPayloadValueFuture) { + final Optional> getPayloadResponseFuture, + final Optional> builderBidOrFallbackDataFuture) { this.executionPayloadContext = executionPayloadContext; - this.executionPayloadFuture = executionPayloadFuture; - this.blobsBundleFuture = blobsBundleFuture; + this.getPayloadResponseFuture = getPayloadResponseFuture; this.builderBidOrFallbackDataFuture = builderBidOrFallbackDataFuture; - this.executionPayloadValueFuture = executionPayloadValueFuture; + } + + public static ExecutionPayloadResult createForLocalFlow( + final ExecutionPayloadContext executionPayloadContext, + final SafeFuture getPayloadResponseFuture) { + return new ExecutionPayloadResult( + executionPayloadContext, Optional.of(getPayloadResponseFuture), Optional.empty()); + } + + public static ExecutionPayloadResult createForBuilderFlow( + final ExecutionPayloadContext executionPayloadContext, + final SafeFuture builderBidOrFallbackDataFuture) { + return new ExecutionPayloadResult( + executionPayloadContext, Optional.empty(), Optional.of(builderBidOrFallbackDataFuture)); } public ExecutionPayloadContext getExecutionPayloadContext() { @@ -53,11 +59,14 @@ public ExecutionPayloadContext getExecutionPayloadContext() { } public Optional> getExecutionPayloadFutureFromLocalFlow() { - return executionPayloadFuture; + return getPayloadResponseFuture.map( + getPayloadResponse -> + getPayloadResponse.thenApply(GetPayloadResponse::getExecutionPayload)); } public Optional>> getBlobsBundleFutureFromLocalFlow() { - return blobsBundleFuture; + return getPayloadResponseFuture.map( + getPayloadResponse -> getPayloadResponse.thenApply(GetPayloadResponse::getBlobsBundle)); } public Optional> getBuilderBidOrFallbackDataFuture() { @@ -68,31 +77,21 @@ public Optional> getBuilderBidOrFallbackDat * @return the value from the local payload, the builder bid or the local fallback payload */ public SafeFuture getExecutionPayloadValueFuture() { - return executionPayloadValueFuture; + return getPayloadResponseFuture + .map( + getPayloadResponse -> + getPayloadResponse.thenApply(GetPayloadResponse::getExecutionPayloadValue)) + .orElseGet(this::getExecutionPayloadValueFutureFromBuilderFlow); } public boolean isFromLocalFlow() { - return executionPayloadFuture.isPresent(); + return getPayloadResponseFuture.isPresent(); } - public static ExecutionPayloadResult createForLocalFlow( - final ExecutionPayloadContext executionPayloadContext, - final SafeFuture getPayloadResponseFuture) { - final SafeFuture executionPayloadValueFuture = - getPayloadResponseFuture.thenApply(GetPayloadResponse::getExecutionPayloadValue); - return new ExecutionPayloadResult( - executionPayloadContext, - Optional.of(getPayloadResponseFuture.thenApply(GetPayloadResponse::getExecutionPayload)), - Optional.of(getPayloadResponseFuture.thenApply(GetPayloadResponse::getBlobsBundle)), - Optional.empty(), - executionPayloadValueFuture); - } - - public static ExecutionPayloadResult createForBuilderFlow( - final ExecutionPayloadContext executionPayloadContext, - final SafeFuture builderBidOrFallbackDataFuture) { - final SafeFuture executionPayloadValueFuture = - builderBidOrFallbackDataFuture.thenApply( + private SafeFuture getExecutionPayloadValueFutureFromBuilderFlow() { + return builderBidOrFallbackDataFuture + .orElseThrow() + .thenApply( builderBidOrFallbackData -> builderBidOrFallbackData .getBuilderBid() @@ -104,12 +103,6 @@ public static ExecutionPayloadResult createForBuilderFlow( builderBidOrFallbackData .getFallbackDataRequired() .getExecutionPayloadValue())); - return new ExecutionPayloadResult( - executionPayloadContext, - Optional.empty(), - Optional.empty(), - Optional.of(builderBidOrFallbackDataFuture), - executionPayloadValueFuture); } @Override @@ -122,30 +115,22 @@ public boolean equals(final Object o) { } final ExecutionPayloadResult that = (ExecutionPayloadResult) o; return Objects.equals(executionPayloadContext, that.executionPayloadContext) - && Objects.equals(executionPayloadFuture, that.executionPayloadFuture) - && Objects.equals(blobsBundleFuture, that.blobsBundleFuture) - && Objects.equals(builderBidOrFallbackDataFuture, that.builderBidOrFallbackDataFuture) - && Objects.equals(executionPayloadValueFuture, that.executionPayloadValueFuture); + && Objects.equals(getPayloadResponseFuture, that.getPayloadResponseFuture) + && Objects.equals(builderBidOrFallbackDataFuture, that.builderBidOrFallbackDataFuture); } @Override public int hashCode() { return Objects.hash( - executionPayloadContext, - executionPayloadFuture, - blobsBundleFuture, - builderBidOrFallbackDataFuture, - executionPayloadValueFuture); + executionPayloadContext, getPayloadResponseFuture, builderBidOrFallbackDataFuture); } @Override public String toString() { return MoreObjects.toStringHelper(this) .add("executionPayloadContext", executionPayloadContext) - .add("executionPayloadFuture", executionPayloadFuture) - .add("blobsBundleFuture", blobsBundleFuture) + .add("getPayloadResponseFuture", getPayloadResponseFuture) .add("builderBidOrFallbackDataFuture", builderBidOrFallbackDataFuture) - .add("executionPayloadValueFuture", executionPayloadValueFuture) .toString(); } } From 22eb9acffc5a979579b30c417aa1999f622ac69a Mon Sep 17 00:00:00 2001 From: Justin Traglia <95511699+jtraglia@users.noreply.github.com> Date: Wed, 9 Oct 2024 22:16:42 -0500 Subject: [PATCH 8/9] Check that ExecutionRequests is not null in block body (#8697) Co-authored-by: Lucas Saldanha --- .../electra/BeaconBlockBodyElectra.java | 29 ++++++------------- .../BlindedBeaconBlockBodyElectra.java | 8 ++--- .../helpers/BeaconStateAccessorsElectra.java | 2 +- 3 files changed, 14 insertions(+), 25 deletions(-) diff --git a/data/serializer/src/main/java/tech/pegasys/teku/api/schema/electra/BeaconBlockBodyElectra.java b/data/serializer/src/main/java/tech/pegasys/teku/api/schema/electra/BeaconBlockBodyElectra.java index 18c78d7a68c..f8dcdd2772c 100644 --- a/data/serializer/src/main/java/tech/pegasys/teku/api/schema/electra/BeaconBlockBodyElectra.java +++ b/data/serializer/src/main/java/tech/pegasys/teku/api/schema/electra/BeaconBlockBodyElectra.java @@ -79,13 +79,13 @@ public BeaconBlockBodyElectra( deposits, voluntaryExits, syncAggregate); - checkNotNull(executionPayload, "Execution Payload is required for Electra blocks"); + checkNotNull(executionPayload, "ExecutionPayload is required for Electra blocks"); this.executionPayload = executionPayload; checkNotNull(blsToExecutionChanges, "BlsToExecutionChanges is required for Electra blocks"); this.blsToExecutionChanges = blsToExecutionChanges; - checkNotNull(blobKZGCommitments, "blobKZGCommitments is required for Electra blocks"); + checkNotNull(blobKZGCommitments, "BlobKZGCommitments is required for Electra blocks"); this.blobKZGCommitments = blobKZGCommitments; - checkNotNull(executionRequests, "Execution Requests is required for Electra blocks"); + checkNotNull(executionRequests, "ExecutionRequests is required for Electra blocks"); this.executionRequests = executionRequests; } @@ -94,33 +94,22 @@ public BeaconBlockBodyElectra( .BeaconBlockBodyElectra message) { super(message); - checkNotNull(message.getExecutionPayload(), "Execution Payload is required for Electra blocks"); + checkNotNull(message.getExecutionPayload(), "ExecutionPayload is required for Electra blocks"); this.executionPayload = new ExecutionPayloadDeneb(message.getExecutionPayload()); checkNotNull( - message.getBlsToExecutionChanges(), - "BlsToExecutionChanges are required for Electra blocks"); + message.getBlsToExecutionChanges(), "BlsToExecutionChanges is required for Electra blocks"); this.blsToExecutionChanges = message.getBlsToExecutionChanges().stream().map(SignedBlsToExecutionChange::new).toList(); checkNotNull( - message.getBlobKzgCommitments(), "BlobKzgCommitments are required for Electra blocks"); + message.getBlobKzgCommitments(), "BlobKzgCommitments is required for Electra blocks"); this.blobKZGCommitments = message.getBlobKzgCommitments().stream() .map(SszKZGCommitment::getKZGCommitment) .map(KZGCommitment::new) .toList(); - - final List depositRequests = - message.getExecutionRequests().getDeposits().stream().map(DepositRequest::new).toList(); - final List withdrawalRequests = - message.getExecutionRequests().getWithdrawals().stream() - .map(WithdrawalRequest::new) - .toList(); - final List consolidationRequests = - message.getExecutionRequests().getConsolidations().stream() - .map(ConsolidationRequest::new) - .toList(); - this.executionRequests = - new ExecutionRequests(depositRequests, withdrawalRequests, consolidationRequests); + checkNotNull( + message.getExecutionRequests(), "ExecutionRequests is required for Electra blocks"); + this.executionRequests = new ExecutionRequests(message.getExecutionRequests()); } @Override diff --git a/data/serializer/src/main/java/tech/pegasys/teku/api/schema/electra/BlindedBeaconBlockBodyElectra.java b/data/serializer/src/main/java/tech/pegasys/teku/api/schema/electra/BlindedBeaconBlockBodyElectra.java index f97d0e48caa..2e61c080721 100644 --- a/data/serializer/src/main/java/tech/pegasys/teku/api/schema/electra/BlindedBeaconBlockBodyElectra.java +++ b/data/serializer/src/main/java/tech/pegasys/teku/api/schema/electra/BlindedBeaconBlockBodyElectra.java @@ -84,15 +84,15 @@ public BlindedBeaconBlockBodyElectra( voluntaryExits, syncAggregate); checkNotNull( - executionPayloadHeader, "Execution Payload Header is required for Electra blinded blocks"); + executionPayloadHeader, "ExecutionPayloadHeader is required for Electra blinded blocks"); this.executionPayloadHeader = executionPayloadHeader; checkNotNull( - blsToExecutionChanges, "blsToExecutionChanges is required for Electra blinded blocks"); + blsToExecutionChanges, "BlsToExecutionChanges is required for Electra blinded blocks"); this.blsToExecutionChanges = blsToExecutionChanges; - checkNotNull(blobKZGCommitments, "blobKZGCommitments is required for Electra blinded blocks"); + checkNotNull(blobKZGCommitments, "BlobKZGCommitments is required for Electra blinded blocks"); this.blobKZGCommitments = blobKZGCommitments; checkNotNull( - executionRequestsRoot, "execution_requests_root is required for Electra blinded blocks"); + executionRequestsRoot, "ExecutionRequestsRoot is required for Electra blinded blocks"); this.executionRequestsRoot = executionRequestsRoot; } diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/electra/helpers/BeaconStateAccessorsElectra.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/electra/helpers/BeaconStateAccessorsElectra.java index 49bf6eca7ea..9aa6cc60272 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/electra/helpers/BeaconStateAccessorsElectra.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/electra/helpers/BeaconStateAccessorsElectra.java @@ -70,7 +70,7 @@ public UInt64 getActiveBalance(final BeaconState state, final int validatorIndex * * @param state The state * @param validatorIndex The index of the validator - * @return The sum of the withdrawal amounts for the validator in the partial withdrawal queue + * @return The sum of the withdrawal amounts for the validator in the partial withdrawal queue. */ public UInt64 getPendingBalanceToWithdraw( final BeaconStateElectra state, final int validatorIndex) { From e38dcce2eea1a42fff699d58aa27b5db37038ad9 Mon Sep 17 00:00:00 2001 From: Stefan Bratanov Date: Thu, 10 Oct 2024 21:14:14 +0800 Subject: [PATCH 9/9] Exclude old incompatible jc-kzg-4844 artefact (#8704) --- build.gradle | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/build.gradle b/build.gradle index 703421eb619..d59bfffd00f 100644 --- a/build.gradle +++ b/build.gradle @@ -844,6 +844,11 @@ subprojects { propertyTestRuntimeOnly.extendsFrom testRuntimeOnly referenceTestRuntimeOnly.extendsFrom testRuntimeOnly + // exclude until Besu dependencies start using io.consensys.protocols:jc-kzg-4844 + implementation { + exclude(group: "tech.pegasys", module: "jc-kzg-4844") + } + // Details at https://github.com/Hakky54/log-captor#using-log-captor-alongside-with-other-logging-libraries testImplementation { exclude(group: "org.apache.logging.log4j", module: "log4j-slf4j-impl")