diff --git a/data/serializer/src/main/java/tech/pegasys/teku/api/schema/Attestation.java b/data/serializer/src/main/java/tech/pegasys/teku/api/schema/Attestation.java index 0741720a7a0..7bcf59a86ce 100644 --- a/data/serializer/src/main/java/tech/pegasys/teku/api/schema/Attestation.java +++ b/data/serializer/src/main/java/tech/pegasys/teku/api/schema/Attestation.java @@ -48,7 +48,8 @@ public Attestation( final tech.pegasys.teku.spec.datastructures.operations.Attestation attestation) { this.aggregation_bits = attestation.getAggregationBits().sszSerialize(); this.data = new AttestationData(attestation.getData()); - this.committee_bits = attestation.getCommitteeBits().map(SszData::sszSerialize).orElse(null); + this.committee_bits = + attestation.getCommitteeBitsOptional().map(SszData::sszSerialize).orElse(null); this.signature = new BLSSignature(attestation.getAggregateSignature()); } @@ -78,7 +79,7 @@ public tech.pegasys.teku.spec.datastructures.operations.Attestation asInternalAt data.asInternalAttestationData(), signature.asInternalBLSSignature(), attestationSchema - .getCommitteeBitsSchema() + .getCommitteeBitsSchemaOptional() .map( committeeBits -> (Supplier) () -> committeeBits.sszDeserialize(committee_bits)) diff --git a/ethereum/spec/build.gradle b/ethereum/spec/build.gradle index be9b639afe6..e1b40fc3f93 100644 --- a/ethereum/spec/build.gradle +++ b/ethereum/spec/build.gradle @@ -12,6 +12,8 @@ dependencies { implementation 'org.apache.tuweni:tuweni-bytes' implementation 'org.apache.tuweni:tuweni-ssz' implementation 'org.apache.tuweni:tuweni-units' + implementation 'org.javassist:javassist' + implementation 'org.apache.commons:commons-text' implementation project(':ethereum:performance-trackers') implementation project(':ethereum:execution-types') implementation project(':ethereum:pow:api') @@ -25,12 +27,14 @@ dependencies { implementation project(':infrastructure:kzg') implementation project(':infrastructure:logging') implementation project(':infrastructure:ssz') + implementation project(':infrastructure:ssz:generator') implementation project(':infrastructure:time') testFixturesApi 'com.google.guava:guava' testFixturesApi 'org.apache.tuweni:tuweni-bytes' testFixturesApi project(':ethereum:pow:api') testFixturesApi project(':infrastructure:ssz') + testFixturesApi project(':infrastructure:ssz:generator') testFixturesApi project(':infrastructure:unsigned') testFixturesImplementation 'com.fasterxml.jackson.core:jackson-databind' @@ -65,6 +69,7 @@ dependencies { testImplementation 'org.junit.jupiter:junit-jupiter-api' testImplementation 'org.junit.jupiter:junit-jupiter-params' testImplementation 'org.mockito:mockito-core' + testImplementation project(':infrastructure:ssz:generator') testImplementation testFixtures(project(':ethereum:statetransition')) testImplementation testFixtures(project(':infrastructure:async')) testImplementation testFixtures(project(':infrastructure:bls')) diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/SpecMilestone.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/SpecMilestone.java index fc8585d9987..a624747d776 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/SpecMilestone.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/SpecMilestone.java @@ -46,6 +46,14 @@ public boolean isGreaterThanOrEqualTo(final SpecMilestone other) { return compareTo(other) >= 0; } + public boolean isGreaterThan(final SpecMilestone other) { + return compareTo(other) > 0; + } + + public boolean isLessThanOrEqualTo(final SpecMilestone other) { + return compareTo(other) <= 0; + } + /** Returns the milestone prior to this milestone */ public SpecMilestone getPreviousMilestone() { if (equals(PHASE0)) { diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/SpecVersion.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/SpecVersion.java index 029d0b247e8..d62ac4a475c 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/SpecVersion.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/SpecVersion.java @@ -37,6 +37,8 @@ import tech.pegasys.teku.spec.schemas.SchemaDefinitionsDeneb; import tech.pegasys.teku.spec.schemas.SchemaDefinitionsElectra; import tech.pegasys.teku.spec.schemas.SchemaDefinitionsPhase0; +import tech.pegasys.teku.spec.schemas.SchemaRegistry; +import tech.pegasys.teku.spec.schemas.SchemaRegistryBuilder; public class SpecVersion extends DelegatingSpecLogic { private final SpecMilestone milestone; @@ -56,53 +58,90 @@ private SpecVersion( public static Optional create( final SpecMilestone milestone, final SpecConfig specConfig) { + final SchemaRegistryBuilder schemaRegistryBuilder = SchemaRegistryBuilder.create(); return switch (milestone) { - case PHASE0 -> Optional.of(createPhase0(specConfig)); - case ALTAIR -> specConfig.toVersionAltair().map(SpecVersion::createAltair); - case BELLATRIX -> specConfig.toVersionBellatrix().map(SpecVersion::createBellatrix); - case CAPELLA -> specConfig.toVersionCapella().map(SpecVersion::createCapella); - case DENEB -> specConfig.toVersionDeneb().map(SpecVersion::createDeneb); - case ELECTRA -> specConfig.toVersionElectra().map(SpecVersion::createElectra); + case PHASE0 -> Optional.of(createPhase0(specConfig, schemaRegistryBuilder)); + case ALTAIR -> + specConfig + .toVersionAltair() + .map(specConfigAltair -> createAltair(specConfigAltair, schemaRegistryBuilder)); + case BELLATRIX -> + specConfig + .toVersionBellatrix() + .map( + specConfigBellatrix -> + createBellatrix(specConfigBellatrix, schemaRegistryBuilder)); + case CAPELLA -> + specConfig + .toVersionCapella() + .map(specConfigCapella -> createCapella(specConfigCapella, schemaRegistryBuilder)); + case DENEB -> + specConfig + .toVersionDeneb() + .map(specConfigDeneb -> createDeneb(specConfigDeneb, schemaRegistryBuilder)); + case ELECTRA -> + specConfig + .toVersionElectra() + .map(specConfigElectra -> createElectra(specConfigElectra, schemaRegistryBuilder)); }; } - static SpecVersion createPhase0(final SpecConfig specConfig) { - final SchemaDefinitions schemaDefinitions = new SchemaDefinitionsPhase0(specConfig); + static SpecVersion createPhase0( + final SpecConfig specConfig, final SchemaRegistryBuilder schemaRegistryBuilder) { + final SchemaRegistry schemaRegistry = + schemaRegistryBuilder.build(SpecMilestone.PHASE0, specConfig); + final SchemaDefinitions schemaDefinitions = new SchemaDefinitionsPhase0(schemaRegistry); final SpecLogic specLogic = SpecLogicPhase0.create(specConfig, schemaDefinitions, SYSTEM_TIME_PROVIDER); return new SpecVersion(SpecMilestone.PHASE0, specConfig, schemaDefinitions, specLogic); } - static SpecVersion createAltair(final SpecConfigAltair specConfig) { - final SchemaDefinitionsAltair schemaDefinitions = new SchemaDefinitionsAltair(specConfig); + static SpecVersion createAltair( + final SpecConfigAltair specConfig, final SchemaRegistryBuilder schemaRegistryBuilder) { + final SchemaRegistry schemaRegistry = + schemaRegistryBuilder.build(SpecMilestone.ALTAIR, specConfig); + final SchemaDefinitionsAltair schemaDefinitions = new SchemaDefinitionsAltair(schemaRegistry); final SpecLogic specLogic = SpecLogicAltair.create(specConfig, schemaDefinitions, SYSTEM_TIME_PROVIDER); return new SpecVersion(SpecMilestone.ALTAIR, specConfig, schemaDefinitions, specLogic); } - static SpecVersion createBellatrix(final SpecConfigBellatrix specConfig) { - final SchemaDefinitionsBellatrix schemaDefinitions = new SchemaDefinitionsBellatrix(specConfig); + static SpecVersion createBellatrix( + final SpecConfigBellatrix specConfig, final SchemaRegistryBuilder schemaRegistryBuilder) { + final SchemaRegistry schemaRegistry = + schemaRegistryBuilder.build(SpecMilestone.BELLATRIX, specConfig); + final SchemaDefinitionsBellatrix schemaDefinitions = + new SchemaDefinitionsBellatrix(schemaRegistry); final SpecLogic specLogic = SpecLogicBellatrix.create(specConfig, schemaDefinitions, SYSTEM_TIME_PROVIDER); return new SpecVersion(SpecMilestone.BELLATRIX, specConfig, schemaDefinitions, specLogic); } - static SpecVersion createCapella(final SpecConfigCapella specConfig) { - final SchemaDefinitionsCapella schemaDefinitions = new SchemaDefinitionsCapella(specConfig); + static SpecVersion createCapella( + final SpecConfigCapella specConfig, final SchemaRegistryBuilder schemaRegistryBuilder) { + final SchemaRegistry schemaRegistry = + schemaRegistryBuilder.build(SpecMilestone.CAPELLA, specConfig); + final SchemaDefinitionsCapella schemaDefinitions = new SchemaDefinitionsCapella(schemaRegistry); final SpecLogicCapella specLogic = SpecLogicCapella.create(specConfig, schemaDefinitions, SYSTEM_TIME_PROVIDER); return new SpecVersion(SpecMilestone.CAPELLA, specConfig, schemaDefinitions, specLogic); } - static SpecVersion createDeneb(final SpecConfigDeneb specConfig) { - final SchemaDefinitionsDeneb schemaDefinitions = new SchemaDefinitionsDeneb(specConfig); + static SpecVersion createDeneb( + final SpecConfigDeneb specConfig, final SchemaRegistryBuilder schemaRegistryBuilder) { + final SchemaRegistry schemaRegistry = + schemaRegistryBuilder.build(SpecMilestone.DENEB, specConfig); + final SchemaDefinitionsDeneb schemaDefinitions = new SchemaDefinitionsDeneb(schemaRegistry); final SpecLogicDeneb specLogic = SpecLogicDeneb.create(specConfig, schemaDefinitions, SYSTEM_TIME_PROVIDER); return new SpecVersion(SpecMilestone.DENEB, specConfig, schemaDefinitions, specLogic); } - static SpecVersion createElectra(final SpecConfigElectra specConfig) { - final SchemaDefinitionsElectra schemaDefinitions = new SchemaDefinitionsElectra(specConfig); + static SpecVersion createElectra( + final SpecConfigElectra specConfig, final SchemaRegistryBuilder schemaRegistryBuilder) { + final SchemaRegistry schemaRegistry = + schemaRegistryBuilder.build(SpecMilestone.ELECTRA, specConfig); + final SchemaDefinitionsElectra schemaDefinitions = new SchemaDefinitionsElectra(schemaRegistry); final SpecLogicElectra specLogic = SpecLogicElectra.create(specConfig, schemaDefinitions, SYSTEM_TIME_PROVIDER); return new SpecVersion(SpecMilestone.ELECTRA, specConfig, schemaDefinitions, specLogic); diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/blocks/blockbody/versions/altair/BeaconBlockBodySchemaAltairImpl.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/blocks/blockbody/versions/altair/BeaconBlockBodySchemaAltairImpl.java index b3ac966058f..0778bfebefc 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/blocks/blockbody/versions/altair/BeaconBlockBodySchemaAltairImpl.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/blocks/blockbody/versions/altair/BeaconBlockBodySchemaAltairImpl.java @@ -13,6 +13,9 @@ package tech.pegasys.teku.spec.datastructures.blocks.blockbody.versions.altair; +import static tech.pegasys.teku.spec.schemas.SchemaTypes.ATTESTATION_SCHEMA; +import static tech.pegasys.teku.spec.schemas.SchemaTypes.ATTESTER_SLASHING_SCHEMA; + import it.unimi.dsi.fastutil.longs.LongList; import java.util.function.Function; import tech.pegasys.teku.infrastructure.async.SafeFuture; @@ -32,11 +35,9 @@ import tech.pegasys.teku.spec.datastructures.operations.Deposit; import tech.pegasys.teku.spec.datastructures.operations.ProposerSlashing; import tech.pegasys.teku.spec.datastructures.operations.SignedVoluntaryExit; -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.type.SszSignature; import tech.pegasys.teku.spec.datastructures.type.SszSignatureSchema; +import tech.pegasys.teku.spec.schemas.SchemaRegistry; public class BeaconBlockBodySchemaAltairImpl extends ContainerSchema9< @@ -78,7 +79,7 @@ private BeaconBlockBodySchemaAltairImpl( public static BeaconBlockBodySchemaAltairImpl create( final SpecConfig specConfig, - final long maxValidatorsPerAttestation, + final SchemaRegistry schemaRegistry, final String containerName) { return new BeaconBlockBodySchemaAltairImpl( containerName, @@ -92,17 +93,12 @@ public static BeaconBlockBodySchemaAltairImpl create( namedSchema( BlockBodyFields.ATTESTER_SLASHINGS, SszListSchema.create( - new AttesterSlashingPhase0Schema( - new IndexedAttestationPhase0Schema(maxValidatorsPerAttestation) - .castTypeToIndexedAttestationSchema()) - .castTypeToAttesterSlashingSchema(), + schemaRegistry.get(ATTESTER_SLASHING_SCHEMA), specConfig.getMaxAttesterSlashings())), namedSchema( BlockBodyFields.ATTESTATIONS, SszListSchema.create( - new AttestationPhase0Schema(maxValidatorsPerAttestation) - .castTypeToAttestationSchema(), - specConfig.getMaxAttestations())), + schemaRegistry.get(ATTESTATION_SCHEMA), specConfig.getMaxAttestations())), namedSchema( BlockBodyFields.DEPOSITS, SszListSchema.create(Deposit.SSZ_SCHEMA, specConfig.getMaxDeposits())), diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/blocks/blockbody/versions/bellatrix/BeaconBlockBodySchemaBellatrixImpl.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/blocks/blockbody/versions/bellatrix/BeaconBlockBodySchemaBellatrixImpl.java index 176bb09c500..3c640995152 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/blocks/blockbody/versions/bellatrix/BeaconBlockBodySchemaBellatrixImpl.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/blocks/blockbody/versions/bellatrix/BeaconBlockBodySchemaBellatrixImpl.java @@ -13,6 +13,10 @@ package tech.pegasys.teku.spec.datastructures.blocks.blockbody.versions.bellatrix; +import static tech.pegasys.teku.spec.schemas.SchemaTypes.ATTESTATION_SCHEMA; +import static tech.pegasys.teku.spec.schemas.SchemaTypes.ATTESTER_SLASHING_SCHEMA; +import static tech.pegasys.teku.spec.schemas.SchemaTypes.EXECUTION_PAYLOAD_SCHEMA; + import it.unimi.dsi.fastutil.longs.LongList; import java.util.function.Function; import tech.pegasys.teku.infrastructure.async.SafeFuture; @@ -38,11 +42,9 @@ import tech.pegasys.teku.spec.datastructures.operations.Deposit; import tech.pegasys.teku.spec.datastructures.operations.ProposerSlashing; import tech.pegasys.teku.spec.datastructures.operations.SignedVoluntaryExit; -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.type.SszSignature; import tech.pegasys.teku.spec.datastructures.type.SszSignatureSchema; +import tech.pegasys.teku.spec.schemas.SchemaRegistry; public class BeaconBlockBodySchemaBellatrixImpl extends ContainerSchema10< @@ -87,10 +89,8 @@ private BeaconBlockBodySchemaBellatrixImpl( public static BeaconBlockBodySchemaBellatrixImpl create( final SpecConfigBellatrix specConfig, - final long maxValidatorsPerAttestation, + final SchemaRegistry schemaRegistry, final String containerName) { - final ExecutionPayloadSchemaBellatrix executionPayloadSchemaBellatrix = - new ExecutionPayloadSchemaBellatrix(specConfig); return new BeaconBlockBodySchemaBellatrixImpl( containerName, namedSchema(BlockBodyFields.RANDAO_REVEAL, SszSignatureSchema.INSTANCE), @@ -103,17 +103,12 @@ public static BeaconBlockBodySchemaBellatrixImpl create( namedSchema( BlockBodyFields.ATTESTER_SLASHINGS, SszListSchema.create( - new AttesterSlashingPhase0Schema( - new IndexedAttestationPhase0Schema(maxValidatorsPerAttestation) - .castTypeToIndexedAttestationSchema()) - .castTypeToAttesterSlashingSchema(), + schemaRegistry.get(ATTESTER_SLASHING_SCHEMA), specConfig.getMaxAttesterSlashings())), namedSchema( BlockBodyFields.ATTESTATIONS, SszListSchema.create( - new AttestationPhase0Schema(maxValidatorsPerAttestation) - .castTypeToAttestationSchema(), - specConfig.getMaxAttestations())), + schemaRegistry.get(ATTESTATION_SCHEMA), specConfig.getMaxAttestations())), namedSchema( BlockBodyFields.DEPOSITS, SszListSchema.create(Deposit.SSZ_SCHEMA, specConfig.getMaxDeposits())), @@ -124,7 +119,9 @@ public static BeaconBlockBodySchemaBellatrixImpl create( namedSchema( BlockBodyFields.SYNC_AGGREGATE, SyncAggregateSchema.create(specConfig.getSyncCommitteeSize())), - namedSchema(BlockBodyFields.EXECUTION_PAYLOAD, executionPayloadSchemaBellatrix)); + namedSchema( + BlockBodyFields.EXECUTION_PAYLOAD, + (ExecutionPayloadSchemaBellatrix) schemaRegistry.get(EXECUTION_PAYLOAD_SCHEMA))); } @Override diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/blocks/blockbody/versions/bellatrix/BlindedBeaconBlockBodySchemaBellatrixImpl.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/blocks/blockbody/versions/bellatrix/BlindedBeaconBlockBodySchemaBellatrixImpl.java index 55da354e6e2..4f53aa2bf73 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/blocks/blockbody/versions/bellatrix/BlindedBeaconBlockBodySchemaBellatrixImpl.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/blocks/blockbody/versions/bellatrix/BlindedBeaconBlockBodySchemaBellatrixImpl.java @@ -13,6 +13,10 @@ package tech.pegasys.teku.spec.datastructures.blocks.blockbody.versions.bellatrix; +import static tech.pegasys.teku.spec.schemas.SchemaTypes.ATTESTATION_SCHEMA; +import static tech.pegasys.teku.spec.schemas.SchemaTypes.ATTESTER_SLASHING_SCHEMA; +import static tech.pegasys.teku.spec.schemas.SchemaTypes.EXECUTION_PAYLOAD_HEADER_SCHEMA; + import it.unimi.dsi.fastutil.longs.LongList; import java.util.function.Function; import tech.pegasys.teku.infrastructure.async.SafeFuture; @@ -37,11 +41,9 @@ import tech.pegasys.teku.spec.datastructures.operations.Deposit; import tech.pegasys.teku.spec.datastructures.operations.ProposerSlashing; import tech.pegasys.teku.spec.datastructures.operations.SignedVoluntaryExit; -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.type.SszSignature; import tech.pegasys.teku.spec.datastructures.type.SszSignatureSchema; +import tech.pegasys.teku.spec.schemas.SchemaRegistry; public class BlindedBeaconBlockBodySchemaBellatrixImpl extends ContainerSchema10< @@ -86,9 +88,8 @@ private BlindedBeaconBlockBodySchemaBellatrixImpl( public static BlindedBeaconBlockBodySchemaBellatrixImpl create( final SpecConfigBellatrix specConfig, - final long maxValidatorsPerAttestation, - final String containerName, - final ExecutionPayloadHeaderSchemaBellatrix executionPayloadHeaderSchema) { + final SchemaRegistry schemaRegistry, + final String containerName) { return new BlindedBeaconBlockBodySchemaBellatrixImpl( containerName, namedSchema(BlockBodyFields.RANDAO_REVEAL, SszSignatureSchema.INSTANCE), @@ -101,17 +102,12 @@ public static BlindedBeaconBlockBodySchemaBellatrixImpl create( namedSchema( BlockBodyFields.ATTESTER_SLASHINGS, SszListSchema.create( - new AttesterSlashingPhase0Schema( - new IndexedAttestationPhase0Schema(maxValidatorsPerAttestation) - .castTypeToIndexedAttestationSchema()) - .castTypeToAttesterSlashingSchema(), + schemaRegistry.get(ATTESTER_SLASHING_SCHEMA), specConfig.getMaxAttesterSlashings())), namedSchema( BlockBodyFields.ATTESTATIONS, SszListSchema.create( - new AttestationPhase0Schema(maxValidatorsPerAttestation) - .castTypeToAttestationSchema(), - specConfig.getMaxAttestations())), + schemaRegistry.get(ATTESTATION_SCHEMA), specConfig.getMaxAttestations())), namedSchema( BlockBodyFields.DEPOSITS, SszListSchema.create(Deposit.SSZ_SCHEMA, specConfig.getMaxDeposits())), @@ -122,7 +118,10 @@ public static BlindedBeaconBlockBodySchemaBellatrixImpl create( namedSchema( BlockBodyFields.SYNC_AGGREGATE, SyncAggregateSchema.create(specConfig.getSyncCommitteeSize())), - namedSchema(BlockBodyFields.EXECUTION_PAYLOAD_HEADER, executionPayloadHeaderSchema)); + namedSchema( + BlockBodyFields.EXECUTION_PAYLOAD_HEADER, + (ExecutionPayloadHeaderSchemaBellatrix) + schemaRegistry.get(EXECUTION_PAYLOAD_HEADER_SCHEMA))); } @Override diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/blocks/blockbody/versions/capella/BeaconBlockBodySchemaCapellaImpl.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/blocks/blockbody/versions/capella/BeaconBlockBodySchemaCapellaImpl.java index 0221fb8e64e..2818d2ebd97 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/blocks/blockbody/versions/capella/BeaconBlockBodySchemaCapellaImpl.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/blocks/blockbody/versions/capella/BeaconBlockBodySchemaCapellaImpl.java @@ -13,6 +13,11 @@ package tech.pegasys.teku.spec.datastructures.blocks.blockbody.versions.capella; +import static tech.pegasys.teku.spec.schemas.SchemaTypes.ATTESTATION_SCHEMA; +import static tech.pegasys.teku.spec.schemas.SchemaTypes.ATTESTER_SLASHING_SCHEMA; +import static tech.pegasys.teku.spec.schemas.SchemaTypes.EXECUTION_PAYLOAD_SCHEMA; +import static tech.pegasys.teku.spec.schemas.SchemaTypes.SIGNED_BLS_TO_EXECUTION_CHANGE_SCHEMA; + import it.unimi.dsi.fastutil.longs.LongList; import java.util.function.Function; import tech.pegasys.teku.infrastructure.async.SafeFuture; @@ -38,13 +43,10 @@ import tech.pegasys.teku.spec.datastructures.operations.Deposit; import tech.pegasys.teku.spec.datastructures.operations.ProposerSlashing; import tech.pegasys.teku.spec.datastructures.operations.SignedBlsToExecutionChange; -import tech.pegasys.teku.spec.datastructures.operations.SignedBlsToExecutionChangeSchema; import tech.pegasys.teku.spec.datastructures.operations.SignedVoluntaryExit; -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.type.SszSignature; import tech.pegasys.teku.spec.datastructures.type.SszSignatureSchema; +import tech.pegasys.teku.spec.schemas.SchemaRegistry; public class BeaconBlockBodySchemaCapellaImpl extends ContainerSchema11< @@ -92,8 +94,7 @@ protected BeaconBlockBodySchemaCapellaImpl( public static BeaconBlockBodySchemaCapellaImpl create( final SpecConfigCapella specConfig, - final SignedBlsToExecutionChangeSchema blsToExecutionChangeSchema, - final long maxValidatorsPerAttestation, + final SchemaRegistry schemaRegistry, final String containerName) { return new BeaconBlockBodySchemaCapellaImpl( containerName, @@ -107,17 +108,12 @@ public static BeaconBlockBodySchemaCapellaImpl create( namedSchema( BlockBodyFields.ATTESTER_SLASHINGS, SszListSchema.create( - new AttesterSlashingPhase0Schema( - new IndexedAttestationPhase0Schema(maxValidatorsPerAttestation) - .castTypeToIndexedAttestationSchema()) - .castTypeToAttesterSlashingSchema(), + schemaRegistry.get(ATTESTER_SLASHING_SCHEMA), specConfig.getMaxAttesterSlashings())), namedSchema( BlockBodyFields.ATTESTATIONS, SszListSchema.create( - new AttestationPhase0Schema(maxValidatorsPerAttestation) - .castTypeToAttestationSchema(), - specConfig.getMaxAttestations())), + schemaRegistry.get(ATTESTATION_SCHEMA), specConfig.getMaxAttestations())), namedSchema( BlockBodyFields.DEPOSITS, SszListSchema.create(Deposit.SSZ_SCHEMA, specConfig.getMaxDeposits())), @@ -129,11 +125,13 @@ public static BeaconBlockBodySchemaCapellaImpl create( BlockBodyFields.SYNC_AGGREGATE, SyncAggregateSchema.create(specConfig.getSyncCommitteeSize())), namedSchema( - BlockBodyFields.EXECUTION_PAYLOAD, new ExecutionPayloadSchemaCapella(specConfig)), + BlockBodyFields.EXECUTION_PAYLOAD, + (ExecutionPayloadSchemaCapella) schemaRegistry.get(EXECUTION_PAYLOAD_SCHEMA)), namedSchema( BlockBodyFields.BLS_TO_EXECUTION_CHANGES, SszListSchema.create( - blsToExecutionChangeSchema, specConfig.getMaxBlsToExecutionChanges()))); + schemaRegistry.get(SIGNED_BLS_TO_EXECUTION_CHANGE_SCHEMA), + specConfig.getMaxBlsToExecutionChanges()))); } @Override diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/blocks/blockbody/versions/capella/BlindedBeaconBlockBodySchemaCapellaImpl.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/blocks/blockbody/versions/capella/BlindedBeaconBlockBodySchemaCapellaImpl.java index 93528343630..7608dc6904c 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/blocks/blockbody/versions/capella/BlindedBeaconBlockBodySchemaCapellaImpl.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/blocks/blockbody/versions/capella/BlindedBeaconBlockBodySchemaCapellaImpl.java @@ -13,6 +13,11 @@ package tech.pegasys.teku.spec.datastructures.blocks.blockbody.versions.capella; +import static tech.pegasys.teku.spec.schemas.SchemaTypes.ATTESTATION_SCHEMA; +import static tech.pegasys.teku.spec.schemas.SchemaTypes.ATTESTER_SLASHING_SCHEMA; +import static tech.pegasys.teku.spec.schemas.SchemaTypes.EXECUTION_PAYLOAD_HEADER_SCHEMA; +import static tech.pegasys.teku.spec.schemas.SchemaTypes.SIGNED_BLS_TO_EXECUTION_CHANGE_SCHEMA; + import it.unimi.dsi.fastutil.longs.LongList; import java.util.function.Function; import tech.pegasys.teku.infrastructure.async.SafeFuture; @@ -37,13 +42,10 @@ import tech.pegasys.teku.spec.datastructures.operations.Deposit; import tech.pegasys.teku.spec.datastructures.operations.ProposerSlashing; import tech.pegasys.teku.spec.datastructures.operations.SignedBlsToExecutionChange; -import tech.pegasys.teku.spec.datastructures.operations.SignedBlsToExecutionChangeSchema; import tech.pegasys.teku.spec.datastructures.operations.SignedVoluntaryExit; -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.type.SszSignature; import tech.pegasys.teku.spec.datastructures.type.SszSignatureSchema; +import tech.pegasys.teku.spec.schemas.SchemaRegistry; public class BlindedBeaconBlockBodySchemaCapellaImpl extends ContainerSchema11< @@ -91,8 +93,7 @@ private BlindedBeaconBlockBodySchemaCapellaImpl( public static BlindedBeaconBlockBodySchemaCapellaImpl create( final SpecConfigCapella specConfig, - final SignedBlsToExecutionChangeSchema signedBlsToExecutionChangeSchema, - final long maxValidatorsPerAttestation, + final SchemaRegistry schemaRegistry, final String containerName) { return new BlindedBeaconBlockBodySchemaCapellaImpl( containerName, @@ -106,17 +107,12 @@ public static BlindedBeaconBlockBodySchemaCapellaImpl create( namedSchema( BlockBodyFields.ATTESTER_SLASHINGS, SszListSchema.create( - new AttesterSlashingPhase0Schema( - new IndexedAttestationPhase0Schema(maxValidatorsPerAttestation) - .castTypeToIndexedAttestationSchema()) - .castTypeToAttesterSlashingSchema(), + schemaRegistry.get(ATTESTER_SLASHING_SCHEMA), specConfig.getMaxAttesterSlashings())), namedSchema( BlockBodyFields.ATTESTATIONS, SszListSchema.create( - new AttestationPhase0Schema(maxValidatorsPerAttestation) - .castTypeToAttestationSchema(), - specConfig.getMaxAttestations())), + schemaRegistry.get(ATTESTATION_SCHEMA), specConfig.getMaxAttestations())), namedSchema( BlockBodyFields.DEPOSITS, SszListSchema.create(Deposit.SSZ_SCHEMA, specConfig.getMaxDeposits())), @@ -129,11 +125,13 @@ public static BlindedBeaconBlockBodySchemaCapellaImpl create( SyncAggregateSchema.create(specConfig.getSyncCommitteeSize())), namedSchema( BlockBodyFields.EXECUTION_PAYLOAD_HEADER, - new ExecutionPayloadHeaderSchemaCapella(specConfig)), + (ExecutionPayloadHeaderSchemaCapella) + schemaRegistry.get(EXECUTION_PAYLOAD_HEADER_SCHEMA)), namedSchema( BlockBodyFields.BLS_TO_EXECUTION_CHANGES, SszListSchema.create( - signedBlsToExecutionChangeSchema, specConfig.getMaxBlsToExecutionChanges()))); + schemaRegistry.get(SIGNED_BLS_TO_EXECUTION_CHANGE_SCHEMA), + specConfig.getMaxBlsToExecutionChanges()))); } @Override diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/blocks/blockbody/versions/deneb/BeaconBlockBodySchemaDenebImpl.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/blocks/blockbody/versions/deneb/BeaconBlockBodySchemaDenebImpl.java index 4a022890bff..060b6732276 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/blocks/blockbody/versions/deneb/BeaconBlockBodySchemaDenebImpl.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/blocks/blockbody/versions/deneb/BeaconBlockBodySchemaDenebImpl.java @@ -13,6 +13,12 @@ package tech.pegasys.teku.spec.datastructures.blocks.blockbody.versions.deneb; +import static tech.pegasys.teku.spec.schemas.SchemaTypes.ATTESTATION_SCHEMA; +import static tech.pegasys.teku.spec.schemas.SchemaTypes.ATTESTER_SLASHING_SCHEMA; +import static tech.pegasys.teku.spec.schemas.SchemaTypes.BLOB_KZG_COMMITMENTS_SCHEMA; +import static tech.pegasys.teku.spec.schemas.SchemaTypes.EXECUTION_PAYLOAD_SCHEMA; +import static tech.pegasys.teku.spec.schemas.SchemaTypes.SIGNED_BLS_TO_EXECUTION_CHANGE_SCHEMA; + import it.unimi.dsi.fastutil.longs.LongList; import java.util.function.Function; import tech.pegasys.teku.infrastructure.async.SafeFuture; @@ -24,7 +30,6 @@ import tech.pegasys.teku.infrastructure.ssz.tree.GIndexUtil; import tech.pegasys.teku.infrastructure.ssz.tree.TreeNode; import tech.pegasys.teku.spec.config.SpecConfigDeneb; -import tech.pegasys.teku.spec.datastructures.blobs.versions.deneb.BlobKzgCommitmentsSchema; 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.BeaconBlockBodyBuilder; @@ -39,14 +44,11 @@ import tech.pegasys.teku.spec.datastructures.operations.Deposit; import tech.pegasys.teku.spec.datastructures.operations.ProposerSlashing; import tech.pegasys.teku.spec.datastructures.operations.SignedBlsToExecutionChange; -import tech.pegasys.teku.spec.datastructures.operations.SignedBlsToExecutionChangeSchema; import tech.pegasys.teku.spec.datastructures.operations.SignedVoluntaryExit; -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.type.SszKZGCommitment; import tech.pegasys.teku.spec.datastructures.type.SszSignature; import tech.pegasys.teku.spec.datastructures.type.SszSignatureSchema; +import tech.pegasys.teku.spec.schemas.SchemaRegistry; public class BeaconBlockBodySchemaDenebImpl extends ContainerSchema12< @@ -97,9 +99,7 @@ protected BeaconBlockBodySchemaDenebImpl( public static BeaconBlockBodySchemaDenebImpl create( final SpecConfigDeneb specConfig, - final SignedBlsToExecutionChangeSchema blsToExecutionChangeSchema, - final BlobKzgCommitmentsSchema blobKzgCommitmentsSchema, - final long maxValidatorsPerAttestation, + final SchemaRegistry schemaRegistry, final String containerName) { return new BeaconBlockBodySchemaDenebImpl( containerName, @@ -113,17 +113,12 @@ public static BeaconBlockBodySchemaDenebImpl create( namedSchema( BlockBodyFields.ATTESTER_SLASHINGS, SszListSchema.create( - new AttesterSlashingPhase0Schema( - new IndexedAttestationPhase0Schema(maxValidatorsPerAttestation) - .castTypeToIndexedAttestationSchema()) - .castTypeToAttesterSlashingSchema(), + schemaRegistry.get(ATTESTER_SLASHING_SCHEMA), specConfig.getMaxAttesterSlashings())), namedSchema( BlockBodyFields.ATTESTATIONS, SszListSchema.create( - new AttestationPhase0Schema(maxValidatorsPerAttestation) - .castTypeToAttestationSchema(), - specConfig.getMaxAttestations())), + schemaRegistry.get(ATTESTATION_SCHEMA), specConfig.getMaxAttestations())), namedSchema( BlockBodyFields.DEPOSITS, SszListSchema.create(Deposit.SSZ_SCHEMA, specConfig.getMaxDeposits())), @@ -134,12 +129,16 @@ public static BeaconBlockBodySchemaDenebImpl create( namedSchema( BlockBodyFields.SYNC_AGGREGATE, SyncAggregateSchema.create(specConfig.getSyncCommitteeSize())), - namedSchema(BlockBodyFields.EXECUTION_PAYLOAD, new ExecutionPayloadSchemaDeneb(specConfig)), + namedSchema( + BlockBodyFields.EXECUTION_PAYLOAD, + (ExecutionPayloadSchemaDeneb) schemaRegistry.get(EXECUTION_PAYLOAD_SCHEMA)), namedSchema( BlockBodyFields.BLS_TO_EXECUTION_CHANGES, SszListSchema.create( - blsToExecutionChangeSchema, specConfig.getMaxBlsToExecutionChanges())), - namedSchema(BlockBodyFields.BLOB_KZG_COMMITMENTS, blobKzgCommitmentsSchema)); + schemaRegistry.get(SIGNED_BLS_TO_EXECUTION_CHANGE_SCHEMA), + specConfig.getMaxBlsToExecutionChanges())), + namedSchema( + BlockBodyFields.BLOB_KZG_COMMITMENTS, schemaRegistry.get(BLOB_KZG_COMMITMENTS_SCHEMA))); } @Override diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/blocks/blockbody/versions/deneb/BlindedBeaconBlockBodySchemaDenebImpl.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/blocks/blockbody/versions/deneb/BlindedBeaconBlockBodySchemaDenebImpl.java index 2537eae37c7..0522d509f88 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/blocks/blockbody/versions/deneb/BlindedBeaconBlockBodySchemaDenebImpl.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/blocks/blockbody/versions/deneb/BlindedBeaconBlockBodySchemaDenebImpl.java @@ -13,6 +13,12 @@ package tech.pegasys.teku.spec.datastructures.blocks.blockbody.versions.deneb; +import static tech.pegasys.teku.spec.schemas.SchemaTypes.ATTESTATION_SCHEMA; +import static tech.pegasys.teku.spec.schemas.SchemaTypes.ATTESTER_SLASHING_SCHEMA; +import static tech.pegasys.teku.spec.schemas.SchemaTypes.BLOB_KZG_COMMITMENTS_SCHEMA; +import static tech.pegasys.teku.spec.schemas.SchemaTypes.EXECUTION_PAYLOAD_HEADER_SCHEMA; +import static tech.pegasys.teku.spec.schemas.SchemaTypes.SIGNED_BLS_TO_EXECUTION_CHANGE_SCHEMA; + import it.unimi.dsi.fastutil.longs.LongList; import java.util.function.Function; import tech.pegasys.teku.infrastructure.async.SafeFuture; @@ -24,7 +30,6 @@ import tech.pegasys.teku.infrastructure.ssz.tree.GIndexUtil; import tech.pegasys.teku.infrastructure.ssz.tree.TreeNode; import tech.pegasys.teku.spec.config.SpecConfigDeneb; -import tech.pegasys.teku.spec.datastructures.blobs.versions.deneb.BlobKzgCommitmentsSchema; 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.BeaconBlockBodyBuilder; @@ -38,14 +43,11 @@ import tech.pegasys.teku.spec.datastructures.operations.Deposit; import tech.pegasys.teku.spec.datastructures.operations.ProposerSlashing; import tech.pegasys.teku.spec.datastructures.operations.SignedBlsToExecutionChange; -import tech.pegasys.teku.spec.datastructures.operations.SignedBlsToExecutionChangeSchema; import tech.pegasys.teku.spec.datastructures.operations.SignedVoluntaryExit; -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.type.SszKZGCommitment; import tech.pegasys.teku.spec.datastructures.type.SszSignature; import tech.pegasys.teku.spec.datastructures.type.SszSignatureSchema; +import tech.pegasys.teku.spec.schemas.SchemaRegistry; public class BlindedBeaconBlockBodySchemaDenebImpl extends ContainerSchema12< @@ -96,9 +98,7 @@ private BlindedBeaconBlockBodySchemaDenebImpl( public static BlindedBeaconBlockBodySchemaDenebImpl create( final SpecConfigDeneb specConfig, - final SignedBlsToExecutionChangeSchema signedBlsToExecutionChangeSchema, - final BlobKzgCommitmentsSchema blobKzgCommitmentsSchema, - final long maxValidatorsPerAttestation, + final SchemaRegistry schemaRegistry, final String containerName) { return new BlindedBeaconBlockBodySchemaDenebImpl( containerName, @@ -112,17 +112,12 @@ public static BlindedBeaconBlockBodySchemaDenebImpl create( namedSchema( BlockBodyFields.ATTESTER_SLASHINGS, SszListSchema.create( - new AttesterSlashingPhase0Schema( - new IndexedAttestationPhase0Schema(maxValidatorsPerAttestation) - .castTypeToIndexedAttestationSchema()) - .castTypeToAttesterSlashingSchema(), + schemaRegistry.get(ATTESTER_SLASHING_SCHEMA), specConfig.getMaxAttesterSlashings())), namedSchema( BlockBodyFields.ATTESTATIONS, SszListSchema.create( - new AttestationPhase0Schema(maxValidatorsPerAttestation) - .castTypeToAttestationSchema(), - specConfig.getMaxAttestations())), + schemaRegistry.get(ATTESTATION_SCHEMA), specConfig.getMaxAttestations())), namedSchema( BlockBodyFields.DEPOSITS, SszListSchema.create(Deposit.SSZ_SCHEMA, specConfig.getMaxDeposits())), @@ -135,12 +130,15 @@ public static BlindedBeaconBlockBodySchemaDenebImpl create( SyncAggregateSchema.create(specConfig.getSyncCommitteeSize())), namedSchema( BlockBodyFields.EXECUTION_PAYLOAD_HEADER, - new ExecutionPayloadHeaderSchemaDeneb(specConfig)), + (ExecutionPayloadHeaderSchemaDeneb) + schemaRegistry.get(EXECUTION_PAYLOAD_HEADER_SCHEMA)), namedSchema( BlockBodyFields.BLS_TO_EXECUTION_CHANGES, SszListSchema.create( - signedBlsToExecutionChangeSchema, specConfig.getMaxBlsToExecutionChanges())), - namedSchema(BlockBodyFields.BLOB_KZG_COMMITMENTS, blobKzgCommitmentsSchema)); + schemaRegistry.get(SIGNED_BLS_TO_EXECUTION_CHANGE_SCHEMA), + specConfig.getMaxBlsToExecutionChanges())), + namedSchema( + BlockBodyFields.BLOB_KZG_COMMITMENTS, schemaRegistry.get(BLOB_KZG_COMMITMENTS_SCHEMA))); } @Override diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/blocks/blockbody/versions/electra/BeaconBlockBodySchemaElectraImpl.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/blocks/blockbody/versions/electra/BeaconBlockBodySchemaElectraImpl.java index ced354e0051..8a22a38d01f 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/blocks/blockbody/versions/electra/BeaconBlockBodySchemaElectraImpl.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/blocks/blockbody/versions/electra/BeaconBlockBodySchemaElectraImpl.java @@ -13,6 +13,12 @@ package tech.pegasys.teku.spec.datastructures.blocks.blockbody.versions.electra; +import static tech.pegasys.teku.spec.schemas.SchemaTypes.ATTESTATION_SCHEMA; +import static tech.pegasys.teku.spec.schemas.SchemaTypes.ATTESTER_SLASHING_SCHEMA; +import static tech.pegasys.teku.spec.schemas.SchemaTypes.BLOB_KZG_COMMITMENTS_SCHEMA; +import static tech.pegasys.teku.spec.schemas.SchemaTypes.EXECUTION_PAYLOAD_SCHEMA; +import static tech.pegasys.teku.spec.schemas.SchemaTypes.SIGNED_BLS_TO_EXECUTION_CHANGE_SCHEMA; + import it.unimi.dsi.fastutil.longs.LongList; import java.util.function.Function; import tech.pegasys.teku.infrastructure.async.SafeFuture; @@ -24,7 +30,6 @@ import tech.pegasys.teku.infrastructure.ssz.tree.GIndexUtil; import tech.pegasys.teku.infrastructure.ssz.tree.TreeNode; import tech.pegasys.teku.spec.config.SpecConfigElectra; -import tech.pegasys.teku.spec.datastructures.blobs.versions.deneb.BlobKzgCommitmentsSchema; 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.BeaconBlockBodyBuilder; @@ -36,16 +41,14 @@ import tech.pegasys.teku.spec.datastructures.execution.versions.electra.ExecutionPayloadSchemaElectra; import tech.pegasys.teku.spec.datastructures.operations.Attestation; import tech.pegasys.teku.spec.datastructures.operations.AttesterSlashing; -import tech.pegasys.teku.spec.datastructures.operations.AttesterSlashingSchema; import tech.pegasys.teku.spec.datastructures.operations.Deposit; import tech.pegasys.teku.spec.datastructures.operations.ProposerSlashing; import tech.pegasys.teku.spec.datastructures.operations.SignedBlsToExecutionChange; -import tech.pegasys.teku.spec.datastructures.operations.SignedBlsToExecutionChangeSchema; import tech.pegasys.teku.spec.datastructures.operations.SignedVoluntaryExit; -import tech.pegasys.teku.spec.datastructures.operations.versions.electra.AttestationElectraSchema; import tech.pegasys.teku.spec.datastructures.type.SszKZGCommitment; import tech.pegasys.teku.spec.datastructures.type.SszSignature; import tech.pegasys.teku.spec.datastructures.type.SszSignatureSchema; +import tech.pegasys.teku.spec.schemas.SchemaRegistry; public class BeaconBlockBodySchemaElectraImpl extends ContainerSchema12< @@ -96,10 +99,7 @@ protected BeaconBlockBodySchemaElectraImpl( public static BeaconBlockBodySchemaElectraImpl create( final SpecConfigElectra specConfig, - final AttesterSlashingSchema attesterSlashingSchema, - final SignedBlsToExecutionChangeSchema blsToExecutionChangeSchema, - final BlobKzgCommitmentsSchema blobKzgCommitmentsSchema, - final long maxValidatorsPerAttestation, + final SchemaRegistry schemaRegistry, final String containerName) { return new BeaconBlockBodySchemaElectraImpl( containerName, @@ -113,15 +113,12 @@ public static BeaconBlockBodySchemaElectraImpl create( namedSchema( BlockBodyFields.ATTESTER_SLASHINGS, SszListSchema.create( - attesterSlashingSchema.castTypeToAttesterSlashingSchema(), + schemaRegistry.get(ATTESTER_SLASHING_SCHEMA), specConfig.getMaxAttesterSlashingsElectra())), namedSchema( BlockBodyFields.ATTESTATIONS, SszListSchema.create( - new AttestationElectraSchema( - maxValidatorsPerAttestation, specConfig.getMaxCommitteesPerSlot()) - .castTypeToAttestationSchema(), - specConfig.getMaxAttestationsElectra())), + schemaRegistry.get(ATTESTATION_SCHEMA), specConfig.getMaxAttestationsElectra())), namedSchema( BlockBodyFields.DEPOSITS, SszListSchema.create(Deposit.SSZ_SCHEMA, specConfig.getMaxDeposits())), @@ -133,12 +130,15 @@ public static BeaconBlockBodySchemaElectraImpl create( BlockBodyFields.SYNC_AGGREGATE, SyncAggregateSchema.create(specConfig.getSyncCommitteeSize())), namedSchema( - BlockBodyFields.EXECUTION_PAYLOAD, new ExecutionPayloadSchemaElectra(specConfig)), + BlockBodyFields.EXECUTION_PAYLOAD, + (ExecutionPayloadSchemaElectra) schemaRegistry.get(EXECUTION_PAYLOAD_SCHEMA)), namedSchema( BlockBodyFields.BLS_TO_EXECUTION_CHANGES, SszListSchema.create( - blsToExecutionChangeSchema, specConfig.getMaxBlsToExecutionChanges())), - namedSchema(BlockBodyFields.BLOB_KZG_COMMITMENTS, blobKzgCommitmentsSchema)); + schemaRegistry.get(SIGNED_BLS_TO_EXECUTION_CHANGE_SCHEMA), + specConfig.getMaxBlsToExecutionChanges())), + namedSchema( + BlockBodyFields.BLOB_KZG_COMMITMENTS, schemaRegistry.get(BLOB_KZG_COMMITMENTS_SCHEMA))); } @Override diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/blocks/blockbody/versions/electra/BlindedBeaconBlockBodySchemaElectraImpl.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/blocks/blockbody/versions/electra/BlindedBeaconBlockBodySchemaElectraImpl.java index e971d364431..1c808fcd9de 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/blocks/blockbody/versions/electra/BlindedBeaconBlockBodySchemaElectraImpl.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/blocks/blockbody/versions/electra/BlindedBeaconBlockBodySchemaElectraImpl.java @@ -13,6 +13,12 @@ package tech.pegasys.teku.spec.datastructures.blocks.blockbody.versions.electra; +import static tech.pegasys.teku.spec.schemas.SchemaTypes.ATTESTATION_SCHEMA; +import static tech.pegasys.teku.spec.schemas.SchemaTypes.ATTESTER_SLASHING_SCHEMA; +import static tech.pegasys.teku.spec.schemas.SchemaTypes.BLOB_KZG_COMMITMENTS_SCHEMA; +import static tech.pegasys.teku.spec.schemas.SchemaTypes.EXECUTION_PAYLOAD_HEADER_SCHEMA; +import static tech.pegasys.teku.spec.schemas.SchemaTypes.SIGNED_BLS_TO_EXECUTION_CHANGE_SCHEMA; + import it.unimi.dsi.fastutil.longs.LongList; import java.util.function.Function; import tech.pegasys.teku.infrastructure.async.SafeFuture; @@ -24,7 +30,6 @@ import tech.pegasys.teku.infrastructure.ssz.tree.GIndexUtil; import tech.pegasys.teku.infrastructure.ssz.tree.TreeNode; import tech.pegasys.teku.spec.config.SpecConfigElectra; -import tech.pegasys.teku.spec.datastructures.blobs.versions.deneb.BlobKzgCommitmentsSchema; 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.BeaconBlockBodyBuilder; @@ -35,16 +40,14 @@ import tech.pegasys.teku.spec.datastructures.execution.versions.electra.ExecutionPayloadHeaderSchemaElectra; import tech.pegasys.teku.spec.datastructures.operations.Attestation; import tech.pegasys.teku.spec.datastructures.operations.AttesterSlashing; -import tech.pegasys.teku.spec.datastructures.operations.AttesterSlashingSchema; import tech.pegasys.teku.spec.datastructures.operations.Deposit; import tech.pegasys.teku.spec.datastructures.operations.ProposerSlashing; import tech.pegasys.teku.spec.datastructures.operations.SignedBlsToExecutionChange; -import tech.pegasys.teku.spec.datastructures.operations.SignedBlsToExecutionChangeSchema; import tech.pegasys.teku.spec.datastructures.operations.SignedVoluntaryExit; -import tech.pegasys.teku.spec.datastructures.operations.versions.electra.AttestationElectraSchema; import tech.pegasys.teku.spec.datastructures.type.SszKZGCommitment; import tech.pegasys.teku.spec.datastructures.type.SszSignature; import tech.pegasys.teku.spec.datastructures.type.SszSignatureSchema; +import tech.pegasys.teku.spec.schemas.SchemaRegistry; public class BlindedBeaconBlockBodySchemaElectraImpl extends ContainerSchema12< @@ -95,10 +98,7 @@ private BlindedBeaconBlockBodySchemaElectraImpl( public static BlindedBeaconBlockBodySchemaElectraImpl create( final SpecConfigElectra specConfig, - final AttesterSlashingSchema attesterSlashingSchema, - final SignedBlsToExecutionChangeSchema signedBlsToExecutionChangeSchema, - final BlobKzgCommitmentsSchema blobKzgCommitmentsSchema, - final long maxValidatorsPerAttestation, + final SchemaRegistry schemaRegistry, final String containerName) { return new BlindedBeaconBlockBodySchemaElectraImpl( containerName, @@ -112,15 +112,12 @@ public static BlindedBeaconBlockBodySchemaElectraImpl create( namedSchema( BlockBodyFields.ATTESTER_SLASHINGS, SszListSchema.create( - attesterSlashingSchema.castTypeToAttesterSlashingSchema(), + schemaRegistry.get(ATTESTER_SLASHING_SCHEMA), specConfig.getMaxAttesterSlashingsElectra())), namedSchema( BlockBodyFields.ATTESTATIONS, SszListSchema.create( - new AttestationElectraSchema( - maxValidatorsPerAttestation, specConfig.getMaxCommitteesPerSlot()) - .castTypeToAttestationSchema(), - specConfig.getMaxAttestationsElectra())), + schemaRegistry.get(ATTESTATION_SCHEMA), specConfig.getMaxAttestationsElectra())), namedSchema( BlockBodyFields.DEPOSITS, SszListSchema.create(Deposit.SSZ_SCHEMA, specConfig.getMaxDeposits())), @@ -133,12 +130,15 @@ public static BlindedBeaconBlockBodySchemaElectraImpl create( SyncAggregateSchema.create(specConfig.getSyncCommitteeSize())), namedSchema( BlockBodyFields.EXECUTION_PAYLOAD_HEADER, - new ExecutionPayloadHeaderSchemaElectra(specConfig)), + (ExecutionPayloadHeaderSchemaElectra) + schemaRegistry.get(EXECUTION_PAYLOAD_HEADER_SCHEMA)), namedSchema( BlockBodyFields.BLS_TO_EXECUTION_CHANGES, SszListSchema.create( - signedBlsToExecutionChangeSchema, specConfig.getMaxBlsToExecutionChanges())), - namedSchema(BlockBodyFields.BLOB_KZG_COMMITMENTS, blobKzgCommitmentsSchema)); + schemaRegistry.get(SIGNED_BLS_TO_EXECUTION_CHANGE_SCHEMA), + specConfig.getMaxBlsToExecutionChanges())), + namedSchema( + BlockBodyFields.BLOB_KZG_COMMITMENTS, schemaRegistry.get(BLOB_KZG_COMMITMENTS_SCHEMA))); } @Override diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/blocks/blockbody/versions/phase0/BeaconBlockBodySchemaPhase0.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/blocks/blockbody/versions/phase0/BeaconBlockBodySchemaPhase0.java index b65493d80c1..376a5d32d56 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/blocks/blockbody/versions/phase0/BeaconBlockBodySchemaPhase0.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/blocks/blockbody/versions/phase0/BeaconBlockBodySchemaPhase0.java @@ -13,6 +13,9 @@ package tech.pegasys.teku.spec.datastructures.blocks.blockbody.versions.phase0; +import static tech.pegasys.teku.spec.schemas.SchemaTypes.ATTESTATION_SCHEMA; +import static tech.pegasys.teku.spec.schemas.SchemaTypes.ATTESTER_SLASHING_SCHEMA; + import it.unimi.dsi.fastutil.longs.LongList; import java.util.function.Function; import tech.pegasys.teku.infrastructure.async.SafeFuture; @@ -30,13 +33,12 @@ import tech.pegasys.teku.spec.datastructures.blocks.blockbody.common.BlockBodyFields; import tech.pegasys.teku.spec.datastructures.operations.Attestation; import tech.pegasys.teku.spec.datastructures.operations.AttesterSlashing; -import tech.pegasys.teku.spec.datastructures.operations.AttesterSlashingSchema; import tech.pegasys.teku.spec.datastructures.operations.Deposit; import tech.pegasys.teku.spec.datastructures.operations.ProposerSlashing; import tech.pegasys.teku.spec.datastructures.operations.SignedVoluntaryExit; -import tech.pegasys.teku.spec.datastructures.operations.versions.phase0.AttestationPhase0Schema; import tech.pegasys.teku.spec.datastructures.type.SszSignature; import tech.pegasys.teku.spec.datastructures.type.SszSignatureSchema; +import tech.pegasys.teku.spec.schemas.SchemaRegistry; public class BeaconBlockBodySchemaPhase0 extends ContainerSchema8< @@ -75,8 +77,7 @@ private BeaconBlockBodySchemaPhase0( public static BeaconBlockBodySchemaPhase0 create( final SpecConfig specConfig, - final AttesterSlashingSchema attesterSlashingSchema, - final long maxValidatorsPerAttestation, + final SchemaRegistry schemaRegistry, final String containerName) { return new BeaconBlockBodySchemaPhase0( containerName, @@ -90,14 +91,12 @@ public static BeaconBlockBodySchemaPhase0 create( namedSchema( BlockBodyFields.ATTESTER_SLASHINGS, SszListSchema.create( - attesterSlashingSchema.castTypeToAttesterSlashingSchema(), + schemaRegistry.get(ATTESTER_SLASHING_SCHEMA), specConfig.getMaxAttesterSlashings())), namedSchema( BlockBodyFields.ATTESTATIONS, SszListSchema.create( - new AttestationPhase0Schema(maxValidatorsPerAttestation) - .castTypeToAttestationSchema(), - specConfig.getMaxAttestations())), + schemaRegistry.get(ATTESTATION_SCHEMA), specConfig.getMaxAttestations())), namedSchema( BlockBodyFields.DEPOSITS, SszListSchema.create(Deposit.SSZ_SCHEMA, specConfig.getMaxDeposits())), diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/operations/Attestation.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/operations/Attestation.java index 57f0ff3f234..8aa1be06b07 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/operations/Attestation.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/operations/Attestation.java @@ -13,6 +13,7 @@ package tech.pegasys.teku.spec.datastructures.operations; +import com.google.common.collect.Sets; import java.util.Collection; import java.util.List; import java.util.Optional; @@ -24,6 +25,7 @@ import tech.pegasys.teku.infrastructure.unsigned.UInt64; import tech.pegasys.teku.spec.Spec; import tech.pegasys.teku.spec.datastructures.operations.versions.phase0.AttestationPhase0; +import tech.pegasys.teku.spec.datastructures.type.SszSignature; /** * Interface used to represent different types of attestations ({@link AttestationPhase0} and {@link @@ -34,9 +36,13 @@ public interface Attestation extends SszContainer { @Override AttestationSchema getSchema(); - UInt64 getEarliestSlotForForkChoiceProcessing(final Spec spec); + default UInt64 getEarliestSlotForForkChoiceProcessing(final Spec spec) { + return getData().getEarliestSlotForForkChoice(spec); + } - Collection getDependentBlockRoots(); + default Collection getDependentBlockRoots() { + return Sets.newHashSet(getData().getTarget().getRoot(), getData().getBeaconBlockRoot()); + } AttestationData getData(); @@ -44,16 +50,19 @@ public interface Attestation extends SszContainer { UInt64 getFirstCommitteeIndex(); - default Optional getCommitteeBits() { - return Optional.empty(); + SszSignature getSignature(); + + default SszBitvector getCommitteeBits() { + throw new RuntimeException("not supported"); } - default SszBitvector getCommitteeBitsRequired() { - return getCommitteeBits() - .orElseThrow(() -> new IllegalArgumentException("Missing committee bits")); + default Optional getCommitteeBitsOptional() { + return Optional.empty(); } - BLSSignature getAggregateSignature(); + default BLSSignature getAggregateSignature() { + return getSignature().getSignature(); + } default Optional> getCommitteeIndices() { return Optional.empty(); diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/operations/AttestationSchema.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/operations/AttestationSchema.java index 3b0b0f880ec..59ac530d3ff 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/operations/AttestationSchema.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/operations/AttestationSchema.java @@ -42,7 +42,7 @@ default SszBitlist createEmptyAggregationBits() { } default Optional createEmptyCommitteeBits() { - return getCommitteeBitsSchema().map(SszBitvectorSchema::ofBits); + return getCommitteeBitsSchemaOptional().map(SszBitvectorSchema::ofBits); } @SuppressWarnings("unchecked") @@ -56,7 +56,14 @@ default Optional toVersionElectra() { SszBitlistSchema getAggregationBitsSchema(); - Optional> getCommitteeBitsSchema(); + SszBitvectorSchema getCommitteeBitsSchema(); + + default Optional> getCommitteeBitsSchemaOptional() { + if (requiresCommitteeBits()) { + return Optional.of(getCommitteeBitsSchema()); + } + return Optional.empty(); + } boolean requiresCommitteeBits(); } diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/operations/SignedBlsToExecutionChangeSchema.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/operations/SignedBlsToExecutionChangeSchema.java index 43c01f24754..51f302400f5 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/operations/SignedBlsToExecutionChangeSchema.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/operations/SignedBlsToExecutionChangeSchema.java @@ -13,19 +13,22 @@ package tech.pegasys.teku.spec.datastructures.operations; +import static tech.pegasys.teku.spec.schemas.SchemaTypes.BLS_TO_EXECUTION_CHANGE_SCHEMA; + import tech.pegasys.teku.bls.BLSSignature; import tech.pegasys.teku.infrastructure.ssz.containers.ContainerSchema2; import tech.pegasys.teku.infrastructure.ssz.tree.TreeNode; import tech.pegasys.teku.spec.datastructures.type.SszSignature; import tech.pegasys.teku.spec.datastructures.type.SszSignatureSchema; +import tech.pegasys.teku.spec.schemas.SchemaRegistry; public class SignedBlsToExecutionChangeSchema extends ContainerSchema2 { - public SignedBlsToExecutionChangeSchema() { + public SignedBlsToExecutionChangeSchema(final SchemaRegistry schemaRegistry) { super( "SignedBLSToExecutionChange", - namedSchema("message", new BlsToExecutionChangeSchema()), + namedSchema("message", schemaRegistry.get(BLS_TO_EXECUTION_CHANGE_SCHEMA)), namedSchema("signature", SszSignatureSchema.INSTANCE)); } diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/operations/versions/electra/AttestationElectra.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/operations/versions/electra/AttestationElectra.java index 1842c46e897..f3d4cf9813a 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/operations/versions/electra/AttestationElectra.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/operations/versions/electra/AttestationElectra.java @@ -13,87 +13,34 @@ package tech.pegasys.teku.spec.datastructures.operations.versions.electra; -import com.google.common.collect.Sets; -import java.util.Collection; import java.util.List; import java.util.Optional; -import org.apache.tuweni.bytes.Bytes32; -import tech.pegasys.teku.bls.BLSSignature; -import tech.pegasys.teku.infrastructure.ssz.collections.SszBitlist; import tech.pegasys.teku.infrastructure.ssz.collections.SszBitvector; -import tech.pegasys.teku.infrastructure.ssz.containers.Container4; -import tech.pegasys.teku.infrastructure.ssz.tree.TreeNode; import tech.pegasys.teku.infrastructure.unsigned.UInt64; -import tech.pegasys.teku.spec.Spec; import tech.pegasys.teku.spec.datastructures.operations.Attestation; -import tech.pegasys.teku.spec.datastructures.operations.AttestationData; -import tech.pegasys.teku.spec.datastructures.type.SszSignature; - -public class AttestationElectra - extends Container4 - implements Attestation { - - public AttestationElectra(final AttestationElectraSchema type, final TreeNode backingNode) { - super(type, backingNode); - } - - public AttestationElectra( - final AttestationElectraSchema schema, - final SszBitlist aggregationBits, - final AttestationData data, - final BLSSignature signature, - final SszBitvector committeeBits) { - super(schema, aggregationBits, data, new SszSignature(signature), committeeBits); - } - - @Override - public AttestationElectraSchema getSchema() { - return (AttestationElectraSchema) super.getSchema(); - } - - @Override - public UInt64 getEarliestSlotForForkChoiceProcessing(final Spec spec) { - return getData().getEarliestSlotForForkChoice(spec); - } +public interface AttestationElectra extends Attestation { @Override - public Collection getDependentBlockRoots() { - return Sets.newHashSet(getData().getTarget().getRoot(), getData().getBeaconBlockRoot()); - } - - @Override - public SszBitlist getAggregationBits() { - return getField0(); - } - - @Override - public AttestationData getData() { - return getField1(); - } - - @Override - public Optional getCommitteeBits() { - return Optional.of(getField3()); - } + SszBitvector getCommitteeBits(); @Override - public BLSSignature getAggregateSignature() { - return getField2().getSignature(); + default Optional getCommitteeBitsOptional() { + return Optional.of(getCommitteeBits()); } @Override - public Optional> getCommitteeIndices() { + default Optional> getCommitteeIndices() { return Optional.of( - getCommitteeBitsRequired().getAllSetBits().intStream().mapToObj(UInt64::valueOf).toList()); + getCommitteeBits().getAllSetBits().intStream().mapToObj(UInt64::valueOf).toList()); } @Override - public UInt64 getFirstCommitteeIndex() { - return UInt64.valueOf(getCommitteeBitsRequired().streamAllSetBits().findFirst().orElseThrow()); + default UInt64 getFirstCommitteeIndex() { + return UInt64.valueOf(getCommitteeBits().streamAllSetBits().findFirst().orElseThrow()); } @Override - public boolean requiresCommitteeBits() { + default boolean requiresCommitteeBits() { return true; } } diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/operations/versions/electra/AttestationElectraSchema.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/operations/versions/electra/AttestationElectraSchema.java index 1f6597738d1..2e07949f628 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/operations/versions/electra/AttestationElectraSchema.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/operations/versions/electra/AttestationElectraSchema.java @@ -20,72 +20,37 @@ import tech.pegasys.teku.bls.BLSSignature; import tech.pegasys.teku.infrastructure.ssz.collections.SszBitlist; import tech.pegasys.teku.infrastructure.ssz.collections.SszBitvector; -import tech.pegasys.teku.infrastructure.ssz.containers.ContainerSchema4; -import tech.pegasys.teku.infrastructure.ssz.schema.collections.SszBitlistSchema; -import tech.pegasys.teku.infrastructure.ssz.schema.collections.SszBitvectorSchema; -import tech.pegasys.teku.infrastructure.ssz.tree.TreeNode; import tech.pegasys.teku.spec.datastructures.operations.Attestation; import tech.pegasys.teku.spec.datastructures.operations.AttestationData; import tech.pegasys.teku.spec.datastructures.operations.AttestationSchema; import tech.pegasys.teku.spec.datastructures.type.SszSignature; -import tech.pegasys.teku.spec.datastructures.type.SszSignatureSchema; -public class AttestationElectraSchema - extends ContainerSchema4< - AttestationElectra, SszBitlist, AttestationData, SszSignature, SszBitvector> - implements AttestationSchema { - - public AttestationElectraSchema( - final long maxValidatorsPerAttestation, final long maxCommitteePerSlot) { - super( - "AttestationElectra", - namedSchema("aggregation_bits", SszBitlistSchema.create(maxValidatorsPerAttestation)), - namedSchema("data", AttestationData.SSZ_SCHEMA), - namedSchema("signature", SszSignatureSchema.INSTANCE), - namedSchema("committee_bits", SszBitvectorSchema.create(maxCommitteePerSlot))); - } +public interface AttestationElectraSchema extends AttestationSchema { @Override - public SszBitlistSchema getAggregationBitsSchema() { - return (SszBitlistSchema) getFieldSchema0(); - } - - @Override - public Optional> getCommitteeBitsSchema() { - return Optional.of((SszBitvectorSchema) getFieldSchema3()); - } - - @Override - public AttestationElectra createFromBackingNode(final TreeNode node) { - return new AttestationElectra(this, node); - } - - @Override - public Attestation create( + default Attestation create( final SszBitlist aggregationBits, final AttestationData data, final BLSSignature signature, final Supplier committeeBits) { final SszBitvector suppliedCommitteeBits = committeeBits.get(); checkNotNull(suppliedCommitteeBits, "committeeBits must be provided in Electra"); - return new AttestationElectra(this, aggregationBits, data, signature, suppliedCommitteeBits); + return create(aggregationBits, data, new SszSignature(signature), suppliedCommitteeBits); } - public AttestationElectra create( + AttestationElectra create( final SszBitlist aggregationBits, final AttestationData data, - final BLSSignature signature, - final SszBitvector committeeBits) { - return new AttestationElectra(this, aggregationBits, data, signature, committeeBits); - } + final SszSignature signature, + final SszBitvector committeeBits); @Override - public Optional toVersionElectra() { + default Optional toVersionElectra() { return Optional.of(this); } @Override - public boolean requiresCommitteeBits() { + default boolean requiresCommitteeBits() { return true; } } diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/operations/versions/phase0/AttestationPhase0.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/operations/versions/phase0/AttestationPhase0.java index dd343f37361..cf913658742 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/operations/versions/phase0/AttestationPhase0.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/operations/versions/phase0/AttestationPhase0.java @@ -13,72 +13,18 @@ package tech.pegasys.teku.spec.datastructures.operations.versions.phase0; -import com.google.common.collect.Sets; -import java.util.Collection; -import org.apache.tuweni.bytes.Bytes32; -import tech.pegasys.teku.bls.BLSSignature; -import tech.pegasys.teku.infrastructure.ssz.collections.SszBitlist; -import tech.pegasys.teku.infrastructure.ssz.containers.Container3; -import tech.pegasys.teku.infrastructure.ssz.tree.TreeNode; import tech.pegasys.teku.infrastructure.unsigned.UInt64; -import tech.pegasys.teku.spec.Spec; import tech.pegasys.teku.spec.datastructures.operations.Attestation; -import tech.pegasys.teku.spec.datastructures.operations.AttestationData; -import tech.pegasys.teku.spec.datastructures.type.SszSignature; -public class AttestationPhase0 - extends Container3 - implements Attestation { - - AttestationPhase0(final AttestationPhase0Schema type, final TreeNode backingNode) { - super(type, backingNode); - } - - AttestationPhase0( - final AttestationPhase0Schema schema, - final SszBitlist aggregationBits, - final AttestationData data, - final BLSSignature signature) { - super(schema, aggregationBits, data, new SszSignature(signature)); - } - - @Override - public AttestationPhase0Schema getSchema() { - return (AttestationPhase0Schema) super.getSchema(); - } - - @Override - public UInt64 getEarliestSlotForForkChoiceProcessing(final Spec spec) { - return getData().getEarliestSlotForForkChoice(spec); - } - - @Override - public Collection getDependentBlockRoots() { - return Sets.newHashSet(getData().getTarget().getRoot(), getData().getBeaconBlockRoot()); - } - - @Override - public SszBitlist getAggregationBits() { - return getField0(); - } - - @Override - public AttestationData getData() { - return getField1(); - } - - @Override - public UInt64 getFirstCommitteeIndex() { - return getField1().getIndex(); - } +public interface AttestationPhase0 extends Attestation { @Override - public BLSSignature getAggregateSignature() { - return getField2().getSignature(); + default UInt64 getFirstCommitteeIndex() { + return getData().getIndex(); } @Override - public boolean requiresCommitteeBits() { + default boolean requiresCommitteeBits() { return false; } } diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/operations/versions/phase0/AttestationPhase0Schema.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/operations/versions/phase0/AttestationPhase0Schema.java index 322e49abc00..1c235216f4b 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/operations/versions/phase0/AttestationPhase0Schema.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/operations/versions/phase0/AttestationPhase0Schema.java @@ -13,59 +13,31 @@ package tech.pegasys.teku.spec.datastructures.operations.versions.phase0; -import java.util.Optional; import java.util.function.Supplier; import tech.pegasys.teku.bls.BLSSignature; import tech.pegasys.teku.infrastructure.ssz.collections.SszBitlist; import tech.pegasys.teku.infrastructure.ssz.collections.SszBitvector; -import tech.pegasys.teku.infrastructure.ssz.containers.ContainerSchema3; -import tech.pegasys.teku.infrastructure.ssz.schema.collections.SszBitlistSchema; -import tech.pegasys.teku.infrastructure.ssz.schema.collections.SszBitvectorSchema; -import tech.pegasys.teku.infrastructure.ssz.tree.TreeNode; import tech.pegasys.teku.spec.datastructures.operations.Attestation; import tech.pegasys.teku.spec.datastructures.operations.AttestationData; import tech.pegasys.teku.spec.datastructures.operations.AttestationSchema; import tech.pegasys.teku.spec.datastructures.type.SszSignature; -import tech.pegasys.teku.spec.datastructures.type.SszSignatureSchema; -public class AttestationPhase0Schema - extends ContainerSchema3 - implements AttestationSchema { - - public AttestationPhase0Schema(final long maxValidatorPerAttestation) { - super( - "AttestationPhase0", - namedSchema("aggregation_bits", SszBitlistSchema.create(maxValidatorPerAttestation)), - namedSchema("data", AttestationData.SSZ_SCHEMA), - namedSchema("signature", SszSignatureSchema.INSTANCE)); - } - - @Override - public SszBitlistSchema getAggregationBitsSchema() { - return (SszBitlistSchema) getFieldSchema0(); - } - - @Override - public Optional> getCommitteeBitsSchema() { - return Optional.empty(); - } - - @Override - public AttestationPhase0 createFromBackingNode(final TreeNode node) { - return new AttestationPhase0(this, node); - } +public interface AttestationPhase0Schema extends AttestationSchema { @Override - public Attestation create( + default Attestation create( final SszBitlist aggregationBits, final AttestationData data, final BLSSignature signature, final Supplier committeeBits) { - return new AttestationPhase0(this, aggregationBits, data, signature); + return create(aggregationBits, data, new SszSignature(signature)); } + AttestationPhase0 create( + final SszBitlist aggregationBits, final AttestationData data, final SszSignature signature); + @Override - public boolean requiresCommitteeBits() { + default boolean requiresCommitteeBits() { return false; } } diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/altair/forktransition/AltairStateUpgrade.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/altair/forktransition/AltairStateUpgrade.java index 73fcfabfa44..194f58383a5 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/altair/forktransition/AltairStateUpgrade.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/altair/forktransition/AltairStateUpgrade.java @@ -27,6 +27,7 @@ import tech.pegasys.teku.spec.datastructures.state.beaconstate.BeaconState; import tech.pegasys.teku.spec.datastructures.state.beaconstate.common.BeaconStateFields; import tech.pegasys.teku.spec.datastructures.state.beaconstate.versions.altair.BeaconStateAltair; +import tech.pegasys.teku.spec.datastructures.state.beaconstate.versions.altair.BeaconStateSchemaAltair; import tech.pegasys.teku.spec.datastructures.state.beaconstate.versions.altair.MutableBeaconStateAltair; import tech.pegasys.teku.spec.datastructures.state.beaconstate.versions.phase0.BeaconStatePhase0; import tech.pegasys.teku.spec.logic.common.forktransition.StateUpgrade; @@ -60,8 +61,7 @@ public BeaconStateAltair upgrade(final BeaconState preState) { final UInt64 epoch = beaconStateAccessors.getCurrentEpoch(preState); final int validatorCount = preState.getValidators().size(); - return schemaDefinitions - .getBeaconStateSchema() + return BeaconStateSchemaAltair.required(schemaDefinitions.getBeaconStateSchema()) .createEmpty() .updatedAltair( state -> { diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/bellatrix/forktransition/BellatrixStateUpgrade.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/bellatrix/forktransition/BellatrixStateUpgrade.java index a79d89a82a6..bf261dd5bba 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/bellatrix/forktransition/BellatrixStateUpgrade.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/bellatrix/forktransition/BellatrixStateUpgrade.java @@ -20,6 +20,7 @@ import tech.pegasys.teku.spec.datastructures.state.beaconstate.common.BeaconStateFields; import tech.pegasys.teku.spec.datastructures.state.beaconstate.versions.altair.BeaconStateAltair; import tech.pegasys.teku.spec.datastructures.state.beaconstate.versions.bellatrix.BeaconStateBellatrix; +import tech.pegasys.teku.spec.datastructures.state.beaconstate.versions.bellatrix.BeaconStateSchemaBellatrix; import tech.pegasys.teku.spec.logic.common.forktransition.StateUpgrade; import tech.pegasys.teku.spec.logic.versions.altair.helpers.BeaconStateAccessorsAltair; import tech.pegasys.teku.spec.schemas.SchemaDefinitionsBellatrix; @@ -43,8 +44,7 @@ public BeaconStateBellatrix upgrade(final BeaconState preState) { final UInt64 epoch = beaconStateAccessors.getCurrentEpoch(preState); BeaconStateAltair preStateAltair = BeaconStateAltair.required(preState); - return schemaDefinitions - .getBeaconStateSchema() + return BeaconStateSchemaBellatrix.required(schemaDefinitions.getBeaconStateSchema()) .createEmpty() .updatedBellatrix( state -> { diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/capella/forktransition/CapellaStateUpgrade.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/capella/forktransition/CapellaStateUpgrade.java index 18377732c03..c5ef3e68f0e 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/capella/forktransition/CapellaStateUpgrade.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/capella/forktransition/CapellaStateUpgrade.java @@ -47,8 +47,7 @@ public CapellaStateUpgrade( public BeaconStateCapella upgrade(final BeaconState preState) { final UInt64 epoch = beaconStateAccessors.getCurrentEpoch(preState); BeaconStateBellatrix preStateBellatrix = BeaconStateBellatrix.required(preState); - return schemaDefinitions - .getBeaconStateSchema() + return BeaconStateSchemaCapella.required(schemaDefinitions.getBeaconStateSchema()) .createEmpty() .updatedCapella( state -> { diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/deneb/forktransition/DenebStateUpgrade.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/deneb/forktransition/DenebStateUpgrade.java index c124ff15876..36de21c2d0d 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/deneb/forktransition/DenebStateUpgrade.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/deneb/forktransition/DenebStateUpgrade.java @@ -22,6 +22,7 @@ import tech.pegasys.teku.spec.datastructures.state.beaconstate.common.BeaconStateFields; import tech.pegasys.teku.spec.datastructures.state.beaconstate.versions.capella.BeaconStateCapella; import tech.pegasys.teku.spec.datastructures.state.beaconstate.versions.deneb.BeaconStateDeneb; +import tech.pegasys.teku.spec.datastructures.state.beaconstate.versions.deneb.BeaconStateSchemaDeneb; import tech.pegasys.teku.spec.logic.common.forktransition.StateUpgrade; import tech.pegasys.teku.spec.logic.versions.altair.helpers.BeaconStateAccessorsAltair; import tech.pegasys.teku.spec.schemas.SchemaDefinitionsDeneb; @@ -45,8 +46,7 @@ public DenebStateUpgrade( public BeaconStateDeneb upgrade(final BeaconState preState) { final UInt64 epoch = beaconStateAccessors.getCurrentEpoch(preState); final BeaconStateCapella preStateCapella = BeaconStateCapella.required(preState); - return schemaDefinitions - .getBeaconStateSchema() + return BeaconStateSchemaDeneb.required(schemaDefinitions.getBeaconStateSchema()) .createEmpty() .updatedDeneb( state -> { diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/electra/forktransition/ElectraStateUpgrade.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/electra/forktransition/ElectraStateUpgrade.java index e1797446ce5..77167594b42 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/electra/forktransition/ElectraStateUpgrade.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/electra/forktransition/ElectraStateUpgrade.java @@ -29,6 +29,7 @@ import tech.pegasys.teku.spec.datastructures.state.beaconstate.common.BeaconStateFields; import tech.pegasys.teku.spec.datastructures.state.beaconstate.versions.deneb.BeaconStateDeneb; import tech.pegasys.teku.spec.datastructures.state.beaconstate.versions.electra.BeaconStateElectra; +import tech.pegasys.teku.spec.datastructures.state.beaconstate.versions.electra.BeaconStateSchemaElectra; import tech.pegasys.teku.spec.logic.common.forktransition.StateUpgrade; import tech.pegasys.teku.spec.logic.versions.electra.helpers.BeaconStateAccessorsElectra; import tech.pegasys.teku.spec.logic.versions.electra.helpers.BeaconStateMutatorsElectra; @@ -61,8 +62,7 @@ public BeaconStateElectra upgrade(final BeaconState preState) { final PredicatesElectra predicatesElectra = new PredicatesElectra(specConfig); final MiscHelpersElectra miscHelpersElectra = new MiscHelpersElectra(specConfig, predicatesElectra, schemaDefinitions); - return schemaDefinitions - .getBeaconStateSchema() + return BeaconStateSchemaElectra.required(schemaDefinitions.getBeaconStateSchema()) .createEmpty() .updatedElectra( state -> { 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 d2f9551a4d7..1c2821f0215 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 @@ -13,50 +13,47 @@ package tech.pegasys.teku.spec.schemas; +import static tech.pegasys.teku.spec.schemas.SchemaTypes.ATTNETS_ENR_FIELD_SCHEMA; +import static tech.pegasys.teku.spec.schemas.SchemaTypes.BEACON_BLOCKS_BY_ROOT_REQUEST_MESSAGE_SCHEMA; +import static tech.pegasys.teku.spec.schemas.SchemaTypes.HISTORICAL_BATCH_SCHEMA; +import static tech.pegasys.teku.spec.schemas.SchemaTypes.SYNCNETS_ENR_FIELD_SCHEMA; + import tech.pegasys.teku.infrastructure.ssz.collections.SszBitvector; import tech.pegasys.teku.infrastructure.ssz.schema.collections.SszBitvectorSchema; -import tech.pegasys.teku.spec.config.SpecConfig; -import tech.pegasys.teku.spec.constants.NetworkConstants; import tech.pegasys.teku.spec.datastructures.networking.libp2p.rpc.BeaconBlocksByRootRequestMessage; import tech.pegasys.teku.spec.datastructures.state.HistoricalBatch.HistoricalBatchSchema; public abstract class AbstractSchemaDefinitions implements SchemaDefinitions { - final SszBitvectorSchema attnetsENRFieldSchema; - final SszBitvectorSchema syncnetsENRFieldSchema = - SszBitvectorSchema.create(NetworkConstants.SYNC_COMMITTEE_SUBNET_COUNT); - private final HistoricalBatchSchema historicalBatchSchema; - private final BeaconBlocksByRootRequestMessage.BeaconBlocksByRootRequestMessageSchema - beaconBlocksByRootRequestMessageSchema; - - public AbstractSchemaDefinitions(final SpecConfig specConfig) { - this.historicalBatchSchema = new HistoricalBatchSchema(specConfig.getSlotsPerHistoricalRoot()); + protected SchemaRegistry schemaRegistry; - this.beaconBlocksByRootRequestMessageSchema = - new BeaconBlocksByRootRequestMessage.BeaconBlocksByRootRequestMessageSchema(specConfig); - this.attnetsENRFieldSchema = SszBitvectorSchema.create(specConfig.getAttestationSubnetCount()); + public AbstractSchemaDefinitions(final SchemaRegistry schemaRegistry) { + this.schemaRegistry = schemaRegistry; } - abstract long getMaxValidatorPerAttestation(SpecConfig specConfig); + @Override + public SchemaRegistry getSchemaRegistry() { + return schemaRegistry; + } @Override public SszBitvectorSchema getAttnetsENRFieldSchema() { - return attnetsENRFieldSchema; + return schemaRegistry.get(ATTNETS_ENR_FIELD_SCHEMA); } @Override public SszBitvectorSchema getSyncnetsENRFieldSchema() { - return syncnetsENRFieldSchema; + return schemaRegistry.get(SYNCNETS_ENR_FIELD_SCHEMA); } @Override public HistoricalBatchSchema getHistoricalBatchSchema() { - return historicalBatchSchema; + return schemaRegistry.get(HISTORICAL_BATCH_SCHEMA); } @Override public BeaconBlocksByRootRequestMessage.BeaconBlocksByRootRequestMessageSchema getBeaconBlocksByRootRequestMessageSchema() { - return beaconBlocksByRootRequestMessageSchema; + return schemaRegistry.get(BEACON_BLOCKS_BY_ROOT_REQUEST_MESSAGE_SCHEMA); } } diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/AbstractSchemaProvider.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/AbstractSchemaProvider.java new file mode 100644 index 00000000000..cc0517dee82 --- /dev/null +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/AbstractSchemaProvider.java @@ -0,0 +1,87 @@ +/* + * 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; + +import static com.google.common.base.Preconditions.checkArgument; + +import java.util.EnumMap; +import java.util.Locale; +import java.util.Map; +import tech.pegasys.teku.spec.SpecMilestone; +import tech.pegasys.teku.spec.config.SpecConfig; +import tech.pegasys.teku.spec.schemas.SchemaTypes.SchemaId; + +public abstract class AbstractSchemaProvider implements SchemaProvider { + private final Map milestoneToEffectiveMilestone = + new EnumMap<>(SpecMilestone.class); + private final SchemaId schemaId; + + protected AbstractSchemaProvider(final SchemaId schemaId) { + this.schemaId = schemaId; + } + + protected void addMilestoneMapping( + final SpecMilestone milestone, final SpecMilestone untilMilestone) { + checkArgument( + untilMilestone.isGreaterThan(milestone), + "%s must be earlier than %s", + milestone, + untilMilestone); + + SpecMilestone currentMilestone = untilMilestone; + while (!currentMilestone.equals(milestone)) { + + checkIfAlreadyMapped(currentMilestone); + + milestoneToEffectiveMilestone.put(currentMilestone, milestone); + + currentMilestone = currentMilestone.getPreviousMilestone(); + } + + checkIfAlreadyMapped(currentMilestone); + } + + private void checkIfAlreadyMapped(final SpecMilestone milestone) { + if (milestoneToEffectiveMilestone.containsKey(milestone)) { + throw new IllegalArgumentException( + String.format( + "Milestone %s is already mapped to %s", + milestone, milestoneToEffectiveMilestone.get(milestone))); + } + } + + protected String capitalizeMilestone(final SpecMilestone milestone) { + return milestone.name().charAt(0) + milestone.name().substring(1).toLowerCase(Locale.ROOT); + } + + @Override + public SpecMilestone getEffectiveMilestone(final SpecMilestone milestone) { + return milestoneToEffectiveMilestone.getOrDefault(milestone, milestone); + } + + @Override + public T getSchema(final SchemaRegistry registry) { + final SpecMilestone milestone = registry.getMilestone(); + final SpecMilestone effectiveMilestone = getEffectiveMilestone(milestone); + return createSchema(registry, effectiveMilestone, registry.getSpecConfig()); + } + + @Override + public SchemaId getSchemaId() { + return schemaId; + } + + protected abstract T createSchema( + SchemaRegistry registry, SpecMilestone baseVersion, SpecConfig specConfig); +} diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/SchemaCache.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/SchemaCache.java new file mode 100644 index 00000000000..99d8a5daf73 --- /dev/null +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/SchemaCache.java @@ -0,0 +1,45 @@ +/* + * 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; + +import java.util.EnumMap; +import java.util.HashMap; +import java.util.Map; +import tech.pegasys.teku.spec.SpecMilestone; +import tech.pegasys.teku.spec.schemas.SchemaTypes.SchemaId; + +public interface SchemaCache { + static SchemaCache createDefault() { + return new SchemaCache() { + private final Map, Object>> cache = + new EnumMap<>(SpecMilestone.class); + + @SuppressWarnings("unchecked") + @Override + public T get(final SpecMilestone milestone, final SchemaId schemaId) { + return (T) cache.computeIfAbsent(milestone, __ -> new HashMap<>()).get(schemaId); + } + + @Override + public void put( + final SpecMilestone milestone, final SchemaId schemaId, final T schema) { + cache.computeIfAbsent(milestone, __ -> new HashMap<>()).put(schemaId, schema); + } + }; + } + + T get(SpecMilestone milestone, SchemaId schemaId); + + void put(SpecMilestone milestone, SchemaId schemaId, T schema); +} diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/SchemaDefinitions.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/SchemaDefinitions.java index f9af34bf087..c2b1eb0a21f 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/SchemaDefinitions.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/SchemaDefinitions.java @@ -89,6 +89,9 @@ public interface SchemaDefinitions { @NonSchema BeaconBlockBodyBuilder createBeaconBlockBodyBuilder(); + @NonSchema + SchemaRegistry getSchemaRegistry(); + @NonSchema default Optional toVersionAltair() { return Optional.empty(); diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/SchemaDefinitionsAltair.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/SchemaDefinitionsAltair.java index 735fc4d1e2b..034829340f1 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/SchemaDefinitionsAltair.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/SchemaDefinitionsAltair.java @@ -13,9 +13,19 @@ package tech.pegasys.teku.spec.schemas; +import static tech.pegasys.teku.spec.schemas.SchemaTypes.AGGREGATE_AND_PROOF_SCHEMA; +import static tech.pegasys.teku.spec.schemas.SchemaTypes.ATTESTATION_SCHEMA; +import static tech.pegasys.teku.spec.schemas.SchemaTypes.ATTESTER_SLASHING_SCHEMA; +import static tech.pegasys.teku.spec.schemas.SchemaTypes.BEACON_BLOCK_BODY_SCHEMA; +import static tech.pegasys.teku.spec.schemas.SchemaTypes.BEACON_BLOCK_SCHEMA; +import static tech.pegasys.teku.spec.schemas.SchemaTypes.BEACON_STATE_SCHEMA; +import static tech.pegasys.teku.spec.schemas.SchemaTypes.INDEXED_ATTESTATION_SCHEMA; +import static tech.pegasys.teku.spec.schemas.SchemaTypes.METADATA_MESSAGE_SCHEMA; +import static tech.pegasys.teku.spec.schemas.SchemaTypes.SIGNED_AGGREGATE_AND_PROOF_SCHEMA; +import static tech.pegasys.teku.spec.schemas.SchemaTypes.SIGNED_BEACON_BLOCK_SCHEMA; + import com.google.common.base.Preconditions; import java.util.Optional; -import tech.pegasys.teku.spec.config.SpecConfig; import tech.pegasys.teku.spec.config.SpecConfigAltair; import tech.pegasys.teku.spec.datastructures.blocks.BeaconBlockSchema; import tech.pegasys.teku.spec.datastructures.blocks.BlockContainer; @@ -26,12 +36,11 @@ import tech.pegasys.teku.spec.datastructures.blocks.blockbody.BeaconBlockBodyBuilder; import tech.pegasys.teku.spec.datastructures.blocks.blockbody.BeaconBlockBodySchema; import tech.pegasys.teku.spec.datastructures.blocks.blockbody.versions.altair.BeaconBlockBodyBuilderAltair; -import tech.pegasys.teku.spec.datastructures.blocks.blockbody.versions.altair.BeaconBlockBodySchemaAltairImpl; import tech.pegasys.teku.spec.datastructures.lightclient.LightClientBootstrapSchema; import tech.pegasys.teku.spec.datastructures.lightclient.LightClientHeaderSchema; import tech.pegasys.teku.spec.datastructures.lightclient.LightClientUpdateResponseSchema; import tech.pegasys.teku.spec.datastructures.lightclient.LightClientUpdateSchema; -import tech.pegasys.teku.spec.datastructures.networking.libp2p.rpc.metadata.versions.altair.MetadataMessageSchemaAltair; +import tech.pegasys.teku.spec.datastructures.networking.libp2p.rpc.metadata.MetadataMessageSchema; import tech.pegasys.teku.spec.datastructures.operations.AggregateAndProof.AggregateAndProofSchema; import tech.pegasys.teku.spec.datastructures.operations.Attestation; import tech.pegasys.teku.spec.datastructures.operations.AttestationSchema; @@ -45,59 +54,28 @@ import tech.pegasys.teku.spec.datastructures.operations.versions.altair.SyncAggregatorSelectionDataSchema; import tech.pegasys.teku.spec.datastructures.operations.versions.altair.SyncCommitteeContributionSchema; import tech.pegasys.teku.spec.datastructures.operations.versions.altair.SyncCommitteeMessageSchema; -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.altair.BeaconStateAltair; -import tech.pegasys.teku.spec.datastructures.state.beaconstate.versions.altair.BeaconStateSchemaAltair; -import tech.pegasys.teku.spec.datastructures.state.beaconstate.versions.altair.MutableBeaconStateAltair; public class SchemaDefinitionsAltair extends AbstractSchemaDefinitions { - private final IndexedAttestationSchema indexedAttestationSchema; - private final AttesterSlashingSchema attesterSlashingSchema; - private final AttestationSchema attestationSchema; - private final SignedAggregateAndProofSchema signedAggregateAndProofSchema; - private final AggregateAndProofSchema aggregateAndProofSchema; - private final BeaconStateSchemaAltair beaconStateSchema; - private final BeaconBlockBodySchemaAltairImpl beaconBlockBodySchema; - private final BeaconBlockSchema beaconBlockSchema; - private final SignedBeaconBlockSchema signedBeaconBlockSchema; - private final SyncCommitteeContributionSchema syncCommitteeContributionSchema; - private final ContributionAndProofSchema contributionAndProofSchema; - private final SignedContributionAndProofSchema signedContributionAndProofSchema; - private final MetadataMessageSchemaAltair metadataMessageSchema; private final LightClientHeaderSchema lightClientHeaderSchema; private final LightClientBootstrapSchema lightClientBootstrapSchema; private final LightClientUpdateSchema lightClientUpdateSchema; private final LightClientUpdateResponseSchema lightClientUpdateResponseSchema; - public SchemaDefinitionsAltair(final SpecConfigAltair specConfig) { - super(specConfig); - this.indexedAttestationSchema = - new IndexedAttestationPhase0Schema(getMaxValidatorPerAttestation(specConfig)) - .castTypeToIndexedAttestationSchema(); - this.attesterSlashingSchema = - new AttesterSlashingPhase0Schema(indexedAttestationSchema) - .castTypeToAttesterSlashingSchema(); - this.attestationSchema = - new AttestationPhase0Schema(getMaxValidatorPerAttestation(specConfig)) - .castTypeToAttestationSchema(); - this.aggregateAndProofSchema = new AggregateAndProofSchema(attestationSchema); - this.signedAggregateAndProofSchema = new SignedAggregateAndProofSchema(aggregateAndProofSchema); - this.beaconStateSchema = BeaconStateSchemaAltair.create(specConfig); - this.beaconBlockBodySchema = - BeaconBlockBodySchemaAltairImpl.create( - specConfig, getMaxValidatorPerAttestation(specConfig), "BeaconBlockBodyAltair"); - this.beaconBlockSchema = new BeaconBlockSchema(beaconBlockBodySchema, "BeaconBlockAltair"); - this.signedBeaconBlockSchema = - new SignedBeaconBlockSchema(beaconBlockSchema, "SignedBeaconBlockAltair"); + private final SyncCommitteeContributionSchema syncCommitteeContributionSchema; + private final ContributionAndProofSchema contributionAndProofSchema; + private final SignedContributionAndProofSchema signedContributionAndProofSchema; + + public SchemaDefinitionsAltair(final SchemaRegistry schemaRegistry) { + super(schemaRegistry); + final SpecConfigAltair specConfig = SpecConfigAltair.required(schemaRegistry.getSpecConfig()); + this.syncCommitteeContributionSchema = SyncCommitteeContributionSchema.create(specConfig); this.contributionAndProofSchema = ContributionAndProofSchema.create(syncCommitteeContributionSchema); this.signedContributionAndProofSchema = SignedContributionAndProofSchema.create(contributionAndProofSchema); - this.metadataMessageSchema = new MetadataMessageSchemaAltair(specConfig.getNetworkingConfig()); + this.lightClientHeaderSchema = new LightClientHeaderSchema(); this.lightClientBootstrapSchema = new LightClientBootstrapSchema(specConfig); this.lightClientUpdateSchema = new LightClientUpdateSchema(specConfig); @@ -115,48 +93,47 @@ public static SchemaDefinitionsAltair required(final SchemaDefinitions schemaDef @Override public SignedAggregateAndProofSchema getSignedAggregateAndProofSchema() { - return signedAggregateAndProofSchema; + return schemaRegistry.get(SIGNED_AGGREGATE_AND_PROOF_SCHEMA); } @Override public AggregateAndProofSchema getAggregateAndProofSchema() { - return aggregateAndProofSchema; + return schemaRegistry.get(AGGREGATE_AND_PROOF_SCHEMA); } @Override public AttestationSchema getAttestationSchema() { - return attestationSchema; + return schemaRegistry.get(ATTESTATION_SCHEMA); } @Override public IndexedAttestationSchema getIndexedAttestationSchema() { - return indexedAttestationSchema; + return schemaRegistry.get(INDEXED_ATTESTATION_SCHEMA); } @Override public AttesterSlashingSchema getAttesterSlashingSchema() { - return attesterSlashingSchema; + return schemaRegistry.get(ATTESTER_SLASHING_SCHEMA); } @Override - public BeaconStateSchema - getBeaconStateSchema() { - return beaconStateSchema; + public BeaconStateSchema getBeaconStateSchema() { + return schemaRegistry.get(BEACON_STATE_SCHEMA); } @Override public SignedBeaconBlockSchema getSignedBeaconBlockSchema() { - return signedBeaconBlockSchema; + return schemaRegistry.get(SIGNED_BEACON_BLOCK_SCHEMA); } @Override public BeaconBlockSchema getBeaconBlockSchema() { - return beaconBlockSchema; + return schemaRegistry.get(BEACON_BLOCK_SCHEMA); } @Override public BeaconBlockBodySchema getBeaconBlockBodySchema() { - return beaconBlockBodySchema; + return schemaRegistry.get(BEACON_BLOCK_BODY_SCHEMA); } @Override @@ -196,12 +173,12 @@ public SignedBlockContainerSchema getSignedBlindedBlockCon @Override public BeaconBlockBodyBuilder createBeaconBlockBodyBuilder() { - return new BeaconBlockBodyBuilderAltair(beaconBlockBodySchema); + return new BeaconBlockBodyBuilderAltair(getBeaconBlockBodySchema()); } @Override - public MetadataMessageSchemaAltair getMetadataMessageSchema() { - return metadataMessageSchema; + public MetadataMessageSchema getMetadataMessageSchema() { + return schemaRegistry.get(METADATA_MESSAGE_SCHEMA); } @Override @@ -244,9 +221,4 @@ public LightClientUpdateSchema getLightClientUpdateSchema() { public LightClientUpdateResponseSchema getLightClientUpdateResponseSchema() { return lightClientUpdateResponseSchema; } - - @Override - long getMaxValidatorPerAttestation(final SpecConfig specConfig) { - return specConfig.getMaxValidatorsPerCommittee(); - } } diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/SchemaDefinitionsBellatrix.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/SchemaDefinitionsBellatrix.java index 29534d8b1f4..1c0e139f104 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/SchemaDefinitionsBellatrix.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/SchemaDefinitionsBellatrix.java @@ -14,67 +14,38 @@ package tech.pegasys.teku.spec.schemas; import static com.google.common.base.Preconditions.checkArgument; +import static tech.pegasys.teku.spec.schemas.SchemaTypes.BLINDED_BEACON_BLOCK_BODY_SCHEMA; +import static tech.pegasys.teku.spec.schemas.SchemaTypes.BLINDED_BEACON_BLOCK_SCHEMA; +import static tech.pegasys.teku.spec.schemas.SchemaTypes.EXECUTION_PAYLOAD_HEADER_SCHEMA; +import static tech.pegasys.teku.spec.schemas.SchemaTypes.EXECUTION_PAYLOAD_SCHEMA; +import static tech.pegasys.teku.spec.schemas.SchemaTypes.SIGNED_BLINDED_BEACON_BLOCK_SCHEMA; import java.util.Optional; -import tech.pegasys.teku.spec.config.SpecConfigBellatrix; import tech.pegasys.teku.spec.datastructures.blocks.BeaconBlockSchema; import tech.pegasys.teku.spec.datastructures.blocks.BlockContainer; import tech.pegasys.teku.spec.datastructures.blocks.BlockContainerSchema; import tech.pegasys.teku.spec.datastructures.blocks.SignedBeaconBlockSchema; -import tech.pegasys.teku.spec.datastructures.blocks.SignedBlockContainer; -import tech.pegasys.teku.spec.datastructures.blocks.SignedBlockContainerSchema; import tech.pegasys.teku.spec.datastructures.blocks.blockbody.BeaconBlockBodyBuilder; import tech.pegasys.teku.spec.datastructures.blocks.blockbody.BeaconBlockBodySchema; import tech.pegasys.teku.spec.datastructures.blocks.blockbody.versions.bellatrix.BeaconBlockBodyBuilderBellatrix; -import tech.pegasys.teku.spec.datastructures.blocks.blockbody.versions.bellatrix.BeaconBlockBodySchemaBellatrixImpl; -import tech.pegasys.teku.spec.datastructures.blocks.blockbody.versions.bellatrix.BlindedBeaconBlockBodySchemaBellatrixImpl; +import tech.pegasys.teku.spec.datastructures.blocks.blockbody.versions.bellatrix.BlindedBeaconBlockBodyBellatrix; import tech.pegasys.teku.spec.datastructures.builder.BuilderBidSchema; import tech.pegasys.teku.spec.datastructures.builder.BuilderPayloadSchema; import tech.pegasys.teku.spec.datastructures.builder.SignedBuilderBidSchema; import tech.pegasys.teku.spec.datastructures.builder.versions.bellatrix.BuilderBidSchemaBellatrix; import tech.pegasys.teku.spec.datastructures.execution.ExecutionPayloadHeaderSchema; import tech.pegasys.teku.spec.datastructures.execution.ExecutionPayloadSchema; -import tech.pegasys.teku.spec.datastructures.execution.versions.bellatrix.ExecutionPayloadHeaderSchemaBellatrix; -import tech.pegasys.teku.spec.datastructures.state.beaconstate.BeaconStateSchema; -import tech.pegasys.teku.spec.datastructures.state.beaconstate.versions.bellatrix.BeaconStateBellatrix; -import tech.pegasys.teku.spec.datastructures.state.beaconstate.versions.bellatrix.BeaconStateSchemaBellatrix; -import tech.pegasys.teku.spec.datastructures.state.beaconstate.versions.bellatrix.MutableBeaconStateBellatrix; public class SchemaDefinitionsBellatrix extends SchemaDefinitionsAltair { - private final BeaconStateSchemaBellatrix beaconStateSchema; - private final BeaconBlockBodySchemaBellatrixImpl beaconBlockBodySchema; - private final BlindedBeaconBlockBodySchemaBellatrixImpl blindedBeaconBlockBodySchema; - private final BeaconBlockSchema beaconBlockSchema; - private final BeaconBlockSchema blindedBeaconBlockSchema; - private final SignedBeaconBlockSchema signedBeaconBlockSchema; - private final SignedBeaconBlockSchema signedBlindedBeaconBlockSchema; - private final ExecutionPayloadHeaderSchemaBellatrix executionPayloadHeaderSchema; + private final BuilderBidSchema builderBidSchema; private final SignedBuilderBidSchema signedBuilderBidSchema; - public SchemaDefinitionsBellatrix(final SpecConfigBellatrix specConfig) { - super(specConfig); - final long maxValidatorsPerAttestation = getMaxValidatorPerAttestation(specConfig); - this.beaconStateSchema = BeaconStateSchemaBellatrix.create(specConfig); - this.executionPayloadHeaderSchema = beaconStateSchema.getLastExecutionPayloadHeaderSchema(); - this.beaconBlockBodySchema = - BeaconBlockBodySchemaBellatrixImpl.create( - specConfig, maxValidatorsPerAttestation, "BeaconBlockBodyBellatrix"); - this.blindedBeaconBlockBodySchema = - BlindedBeaconBlockBodySchemaBellatrixImpl.create( - specConfig, - maxValidatorsPerAttestation, - "BlindedBlockBodyBellatrix", - executionPayloadHeaderSchema); - this.beaconBlockSchema = new BeaconBlockSchema(beaconBlockBodySchema, "BeaconBlockBellatrix"); - this.blindedBeaconBlockSchema = - new BeaconBlockSchema(blindedBeaconBlockBodySchema, "BlindedBlockBellatrix"); - this.signedBeaconBlockSchema = - new SignedBeaconBlockSchema(beaconBlockSchema, "SignedBeaconBlockBellatrix"); - this.signedBlindedBeaconBlockSchema = - new SignedBeaconBlockSchema(blindedBeaconBlockSchema, "SignedBlindedBlockBellatrix"); + public SchemaDefinitionsBellatrix(final SchemaRegistry schemaRegistry) { + super(schemaRegistry); + this.builderBidSchema = - new BuilderBidSchemaBellatrix("BuilderBidBellatrix", executionPayloadHeaderSchema); + new BuilderBidSchemaBellatrix("BuilderBidBellatrix", getExecutionPayloadHeaderSchema()); this.signedBuilderBidSchema = new SignedBuilderBidSchema("SignedBuilderBidBellatrix", builderBidSchema); } @@ -88,45 +59,20 @@ public static SchemaDefinitionsBellatrix required(final SchemaDefinitions schema return (SchemaDefinitionsBellatrix) schemaDefinitions; } - @Override - public BeaconStateSchema - getBeaconStateSchema() { - return beaconStateSchema; - } - - @Override - public SignedBeaconBlockSchema getSignedBeaconBlockSchema() { - return signedBeaconBlockSchema; - } - - @Override - public BeaconBlockSchema getBeaconBlockSchema() { - return beaconBlockSchema; - } - @Override public BeaconBlockSchema getBlindedBeaconBlockSchema() { - return blindedBeaconBlockSchema; + return schemaRegistry.get(BLINDED_BEACON_BLOCK_SCHEMA); } @Override - public BeaconBlockBodySchema getBlindedBeaconBlockBodySchema() { - return blindedBeaconBlockBodySchema; - } - - @Override - public BeaconBlockBodySchema getBeaconBlockBodySchema() { - return beaconBlockBodySchema; + public BeaconBlockBodySchema + getBlindedBeaconBlockBodySchema() { + return schemaRegistry.get(BLINDED_BEACON_BLOCK_BODY_SCHEMA); } @Override public SignedBeaconBlockSchema getSignedBlindedBeaconBlockSchema() { - return signedBlindedBeaconBlockSchema; - } - - @Override - public BlockContainerSchema getBlockContainerSchema() { - return getBeaconBlockSchema().castTypeToBlockContainer(); + return schemaRegistry.get(SIGNED_BLINDED_BEACON_BLOCK_SCHEMA); } @Override @@ -134,27 +80,19 @@ public BlockContainerSchema getBlindedBlockContainerSchema() { return getBlindedBeaconBlockSchema().castTypeToBlockContainer(); } - @Override - public SignedBlockContainerSchema getSignedBlockContainerSchema() { - return getSignedBeaconBlockSchema().castTypeToSignedBlockContainer(); - } - - @Override - public SignedBlockContainerSchema getSignedBlindedBlockContainerSchema() { - return getSignedBlindedBeaconBlockSchema().castTypeToSignedBlockContainer(); - } - @Override public BeaconBlockBodyBuilder createBeaconBlockBodyBuilder() { - return new BeaconBlockBodyBuilderBellatrix(beaconBlockBodySchema, blindedBeaconBlockBodySchema); + return new BeaconBlockBodyBuilderBellatrix( + getBeaconBlockBodySchema().toVersionBellatrix().orElseThrow(), + getBlindedBeaconBlockBodySchema()); } public ExecutionPayloadSchema getExecutionPayloadSchema() { - return beaconBlockBodySchema.getExecutionPayloadSchema(); + return schemaRegistry.get(EXECUTION_PAYLOAD_SCHEMA); } public ExecutionPayloadHeaderSchema getExecutionPayloadHeaderSchema() { - return executionPayloadHeaderSchema; + return schemaRegistry.get(EXECUTION_PAYLOAD_HEADER_SCHEMA); } public BuilderBidSchema getBuilderBidSchema() { diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/SchemaDefinitionsCapella.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/SchemaDefinitionsCapella.java index ce3e9e02041..02e8c02b25d 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/SchemaDefinitionsCapella.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/SchemaDefinitionsCapella.java @@ -14,93 +14,40 @@ package tech.pegasys.teku.spec.schemas; import static com.google.common.base.Preconditions.checkArgument; +import static tech.pegasys.teku.spec.schemas.SchemaTypes.BLINDED_BEACON_BLOCK_BODY_SCHEMA; +import static tech.pegasys.teku.spec.schemas.SchemaTypes.BLS_TO_EXECUTION_CHANGE_SCHEMA; +import static tech.pegasys.teku.spec.schemas.SchemaTypes.SIGNED_BLS_TO_EXECUTION_CHANGE_SCHEMA; import java.util.Optional; -import tech.pegasys.teku.spec.config.SpecConfigCapella; -import tech.pegasys.teku.spec.datastructures.blocks.BeaconBlockSchema; -import tech.pegasys.teku.spec.datastructures.blocks.BlockContainer; -import tech.pegasys.teku.spec.datastructures.blocks.BlockContainerSchema; -import tech.pegasys.teku.spec.datastructures.blocks.SignedBeaconBlockSchema; import tech.pegasys.teku.spec.datastructures.blocks.SignedBlockContainer; import tech.pegasys.teku.spec.datastructures.blocks.SignedBlockContainerSchema; import tech.pegasys.teku.spec.datastructures.blocks.blockbody.BeaconBlockBodyBuilder; import tech.pegasys.teku.spec.datastructures.blocks.blockbody.BeaconBlockBodySchema; import tech.pegasys.teku.spec.datastructures.blocks.blockbody.versions.capella.BeaconBlockBodyBuilderCapella; -import tech.pegasys.teku.spec.datastructures.blocks.blockbody.versions.capella.BeaconBlockBodySchemaCapellaImpl; -import tech.pegasys.teku.spec.datastructures.blocks.blockbody.versions.capella.BlindedBeaconBlockBodySchemaCapellaImpl; +import tech.pegasys.teku.spec.datastructures.blocks.blockbody.versions.capella.BlindedBeaconBlockBodyCapella; import tech.pegasys.teku.spec.datastructures.builder.BuilderBidSchema; import tech.pegasys.teku.spec.datastructures.builder.SignedBuilderBidSchema; import tech.pegasys.teku.spec.datastructures.builder.versions.bellatrix.BuilderBidSchemaBellatrix; -import tech.pegasys.teku.spec.datastructures.execution.ExecutionPayloadHeaderSchema; -import tech.pegasys.teku.spec.datastructures.execution.ExecutionPayloadSchema; -import tech.pegasys.teku.spec.datastructures.execution.versions.capella.ExecutionPayloadHeaderSchemaCapella; -import tech.pegasys.teku.spec.datastructures.execution.versions.capella.ExecutionPayloadSchemaCapella; import tech.pegasys.teku.spec.datastructures.execution.versions.capella.Withdrawal; import tech.pegasys.teku.spec.datastructures.execution.versions.capella.WithdrawalSchema; import tech.pegasys.teku.spec.datastructures.operations.BlsToExecutionChangeSchema; import tech.pegasys.teku.spec.datastructures.operations.SignedBlsToExecutionChangeSchema; -import tech.pegasys.teku.spec.datastructures.state.beaconstate.BeaconStateSchema; -import tech.pegasys.teku.spec.datastructures.state.beaconstate.versions.capella.BeaconStateCapella; -import tech.pegasys.teku.spec.datastructures.state.beaconstate.versions.capella.BeaconStateSchemaCapella; -import tech.pegasys.teku.spec.datastructures.state.beaconstate.versions.capella.MutableBeaconStateCapella; import tech.pegasys.teku.spec.datastructures.state.versions.capella.HistoricalSummary; public class SchemaDefinitionsCapella extends SchemaDefinitionsBellatrix { - - private final BeaconStateSchemaCapella beaconStateSchema; - - private final ExecutionPayloadSchemaCapella executionPayloadSchemaCapella; - private final ExecutionPayloadHeaderSchemaCapella executionPayloadHeaderSchemaCapella; - - private final BeaconBlockBodySchemaCapellaImpl beaconBlockBodySchema; - private final BlindedBeaconBlockBodySchemaCapellaImpl blindedBeaconBlockBodySchema; - - private final BeaconBlockSchema beaconBlockSchema; - private final BeaconBlockSchema blindedBeaconBlockSchema; - private final SignedBeaconBlockSchema signedBeaconBlockSchema; - private final SignedBeaconBlockSchema signedBlindedBeaconBlockSchema; - private final WithdrawalSchema withdrawalSchema; - private final BlsToExecutionChangeSchema blsToExecutionChangeSchema; - - private final SignedBlsToExecutionChangeSchema signedBlsToExecutionChangeSchema; private final BuilderBidSchema builderBidSchemaCapella; private final SignedBuilderBidSchema signedBuilderBidSchemaCapella; private final HistoricalSummary.HistoricalSummarySchema historicalSummarySchema; - public SchemaDefinitionsCapella(final SpecConfigCapella specConfig) { - super(specConfig); - this.executionPayloadSchemaCapella = new ExecutionPayloadSchemaCapella(specConfig); - this.blsToExecutionChangeSchema = new BlsToExecutionChangeSchema(); - this.signedBlsToExecutionChangeSchema = new SignedBlsToExecutionChangeSchema(); + public SchemaDefinitionsCapella(final SchemaRegistry schemaRegistry) { + super(schemaRegistry); this.withdrawalSchema = Withdrawal.SSZ_SCHEMA; - this.beaconStateSchema = BeaconStateSchemaCapella.create(specConfig); - this.executionPayloadHeaderSchemaCapella = - beaconStateSchema.getLastExecutionPayloadHeaderSchema(); - this.beaconBlockBodySchema = - BeaconBlockBodySchemaCapellaImpl.create( - specConfig, - signedBlsToExecutionChangeSchema, - getMaxValidatorPerAttestation(specConfig), - "BeaconBlockBodyCapella"); - this.blindedBeaconBlockBodySchema = - BlindedBeaconBlockBodySchemaCapellaImpl.create( - specConfig, - signedBlsToExecutionChangeSchema, - getMaxValidatorPerAttestation(specConfig), - "BlindedBlockBodyCapella"); - this.beaconBlockSchema = new BeaconBlockSchema(beaconBlockBodySchema, "BeaconBlockCapella"); - this.blindedBeaconBlockSchema = - new BeaconBlockSchema(blindedBeaconBlockBodySchema, "BlindedBlockCapella"); - this.signedBeaconBlockSchema = - new SignedBeaconBlockSchema(beaconBlockSchema, "SignedBeaconBlockCapella"); - this.signedBlindedBeaconBlockSchema = - new SignedBeaconBlockSchema(blindedBeaconBlockSchema, "SignedBlindedBlockCapella"); this.builderBidSchemaCapella = - new BuilderBidSchemaBellatrix("BuilderBidCapella", executionPayloadHeaderSchemaCapella); + new BuilderBidSchemaBellatrix("BuilderBidCapella", getExecutionPayloadHeaderSchema()); this.signedBuilderBidSchemaCapella = new SignedBuilderBidSchema("SignedBuilderBidCapella", builderBidSchemaCapella); this.historicalSummarySchema = new HistoricalSummary.HistoricalSummarySchema(); @@ -116,54 +63,11 @@ public static SchemaDefinitionsCapella required(final SchemaDefinitions schemaDe } @Override - public BeaconStateSchema - getBeaconStateSchema() { - return beaconStateSchema; - } - - @Override - public BeaconBlockBodySchema getBeaconBlockBodySchema() { - return beaconBlockBodySchema; - } - - @Override - public BeaconBlockBodySchema getBlindedBeaconBlockBodySchema() { - return blindedBeaconBlockBodySchema; - } - - @Override - public BeaconBlockSchema getBeaconBlockSchema() { - return beaconBlockSchema; - } - - @Override - public BeaconBlockSchema getBlindedBeaconBlockSchema() { - return blindedBeaconBlockSchema; - } - - @Override - public SignedBeaconBlockSchema getSignedBeaconBlockSchema() { - return signedBeaconBlockSchema; - } - - @Override - public SignedBeaconBlockSchema getSignedBlindedBeaconBlockSchema() { - return signedBlindedBeaconBlockSchema; - } - - @Override - public BlockContainerSchema getBlockContainerSchema() { - return getBeaconBlockSchema().castTypeToBlockContainer(); - } - - @Override - public BlockContainerSchema getBlindedBlockContainerSchema() { - return getBlindedBeaconBlockSchema().castTypeToBlockContainer(); - } - - @Override - public SignedBlockContainerSchema getSignedBlockContainerSchema() { - return getSignedBeaconBlockSchema().castTypeToSignedBlockContainer(); + @SuppressWarnings("unchecked") + public BeaconBlockBodySchema + getBlindedBeaconBlockBodySchema() { + return (BeaconBlockBodySchema) + schemaRegistry.get(BLINDED_BEACON_BLOCK_BODY_SCHEMA); } @Override @@ -171,19 +75,11 @@ public SignedBlockContainerSchema getSignedBlindedBlockCon return getSignedBlindedBeaconBlockSchema().castTypeToSignedBlockContainer(); } - @Override - public ExecutionPayloadSchema getExecutionPayloadSchema() { - return executionPayloadSchemaCapella; - } - - @Override - public ExecutionPayloadHeaderSchema getExecutionPayloadHeaderSchema() { - return executionPayloadHeaderSchemaCapella; - } - @Override public BeaconBlockBodyBuilder createBeaconBlockBodyBuilder() { - return new BeaconBlockBodyBuilderCapella(beaconBlockBodySchema, blindedBeaconBlockBodySchema); + return new BeaconBlockBodyBuilderCapella( + getBeaconBlockBodySchema().toVersionCapella().orElseThrow(), + getBlindedBeaconBlockBodySchema()); } public WithdrawalSchema getWithdrawalSchema() { @@ -191,11 +87,11 @@ public WithdrawalSchema getWithdrawalSchema() { } public BlsToExecutionChangeSchema getBlsToExecutionChangeSchema() { - return blsToExecutionChangeSchema; + return schemaRegistry.get(BLS_TO_EXECUTION_CHANGE_SCHEMA); } public SignedBlsToExecutionChangeSchema getSignedBlsToExecutionChangeSchema() { - return signedBlsToExecutionChangeSchema; + return schemaRegistry.get(SIGNED_BLS_TO_EXECUTION_CHANGE_SCHEMA); } public HistoricalSummary.HistoricalSummarySchema getHistoricalSummarySchema() { diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/SchemaDefinitionsDeneb.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/SchemaDefinitionsDeneb.java index 05effc1ed3d..db5f9ed9386 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/SchemaDefinitionsDeneb.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/SchemaDefinitionsDeneb.java @@ -14,6 +14,8 @@ package tech.pegasys.teku.spec.schemas; import static com.google.common.base.Preconditions.checkArgument; +import static tech.pegasys.teku.spec.schemas.SchemaTypes.BLINDED_BEACON_BLOCK_BODY_SCHEMA; +import static tech.pegasys.teku.spec.schemas.SchemaTypes.BLOB_KZG_COMMITMENTS_SCHEMA; import java.util.Optional; import tech.pegasys.teku.infrastructure.ssz.SszList; @@ -23,18 +25,15 @@ import tech.pegasys.teku.spec.datastructures.blobs.versions.deneb.BlobKzgCommitmentsSchema; import tech.pegasys.teku.spec.datastructures.blobs.versions.deneb.BlobSchema; import tech.pegasys.teku.spec.datastructures.blobs.versions.deneb.BlobSidecarSchema; -import tech.pegasys.teku.spec.datastructures.blocks.BeaconBlockSchema; import tech.pegasys.teku.spec.datastructures.blocks.BlockContainer; import tech.pegasys.teku.spec.datastructures.blocks.BlockContainerSchema; import tech.pegasys.teku.spec.datastructures.blocks.SignedBeaconBlockHeader; -import tech.pegasys.teku.spec.datastructures.blocks.SignedBeaconBlockSchema; import tech.pegasys.teku.spec.datastructures.blocks.SignedBlockContainer; import tech.pegasys.teku.spec.datastructures.blocks.SignedBlockContainerSchema; import tech.pegasys.teku.spec.datastructures.blocks.blockbody.BeaconBlockBodyBuilder; import tech.pegasys.teku.spec.datastructures.blocks.blockbody.BeaconBlockBodySchema; import tech.pegasys.teku.spec.datastructures.blocks.blockbody.versions.deneb.BeaconBlockBodyBuilderDeneb; -import tech.pegasys.teku.spec.datastructures.blocks.blockbody.versions.deneb.BeaconBlockBodySchemaDenebImpl; -import tech.pegasys.teku.spec.datastructures.blocks.blockbody.versions.deneb.BlindedBeaconBlockBodySchemaDenebImpl; +import tech.pegasys.teku.spec.datastructures.blocks.blockbody.versions.deneb.BlindedBeaconBlockBodyDeneb; import tech.pegasys.teku.spec.datastructures.blocks.versions.deneb.BlockContentsSchema; import tech.pegasys.teku.spec.datastructures.blocks.versions.deneb.SignedBlockContentsSchema; import tech.pegasys.teku.spec.datastructures.builder.BlobsBundleSchema; @@ -43,33 +42,10 @@ import tech.pegasys.teku.spec.datastructures.builder.ExecutionPayloadAndBlobsBundleSchema; import tech.pegasys.teku.spec.datastructures.builder.SignedBuilderBidSchema; import tech.pegasys.teku.spec.datastructures.builder.versions.deneb.BuilderBidSchemaDeneb; -import tech.pegasys.teku.spec.datastructures.execution.ExecutionPayloadHeaderSchema; -import tech.pegasys.teku.spec.datastructures.execution.ExecutionPayloadSchema; -import tech.pegasys.teku.spec.datastructures.execution.versions.deneb.ExecutionPayloadHeaderSchemaDeneb; -import tech.pegasys.teku.spec.datastructures.execution.versions.deneb.ExecutionPayloadSchemaDeneb; import tech.pegasys.teku.spec.datastructures.networking.libp2p.rpc.BlobSidecarsByRootRequestMessageSchema; -import tech.pegasys.teku.spec.datastructures.state.beaconstate.BeaconStateSchema; -import tech.pegasys.teku.spec.datastructures.state.beaconstate.versions.deneb.BeaconStateDeneb; -import tech.pegasys.teku.spec.datastructures.state.beaconstate.versions.deneb.BeaconStateSchemaDeneb; -import tech.pegasys.teku.spec.datastructures.state.beaconstate.versions.deneb.MutableBeaconStateDeneb; public class SchemaDefinitionsDeneb extends SchemaDefinitionsCapella { - private final BeaconStateSchemaDeneb beaconStateSchema; - - private final ExecutionPayloadSchemaDeneb executionPayloadSchemaDeneb; - private final ExecutionPayloadHeaderSchemaDeneb executionPayloadHeaderSchemaDeneb; - - private final BlobKzgCommitmentsSchema blobKzgCommitmentsSchema; - - private final BeaconBlockBodySchemaDenebImpl beaconBlockBodySchema; - private final BlindedBeaconBlockBodySchemaDenebImpl blindedBeaconBlockBodySchema; - - private final BeaconBlockSchema beaconBlockSchema; - private final BeaconBlockSchema blindedBeaconBlockSchema; - private final SignedBeaconBlockSchema signedBeaconBlockSchema; - private final SignedBeaconBlockSchema signedBlindedBeaconBlockSchema; - private final BuilderBidSchema builderBidSchemaDeneb; private final SignedBuilderBidSchema signedBuilderBidSchemaDeneb; @@ -82,38 +58,13 @@ public class SchemaDefinitionsDeneb extends SchemaDefinitionsCapella { private final ExecutionPayloadAndBlobsBundleSchema executionPayloadAndBlobsBundleSchema; private final BlobSidecarsByRootRequestMessageSchema blobSidecarsByRootRequestMessageSchema; - public SchemaDefinitionsDeneb(final SpecConfigDeneb specConfig) { - super(specConfig); - this.executionPayloadSchemaDeneb = new ExecutionPayloadSchemaDeneb(specConfig); + public SchemaDefinitionsDeneb(final SchemaRegistry schemaRegistry) { + super(schemaRegistry); + final SpecConfigDeneb specConfig = SpecConfigDeneb.required(schemaRegistry.getSpecConfig()); - this.beaconStateSchema = BeaconStateSchemaDeneb.create(specConfig); - this.executionPayloadHeaderSchemaDeneb = - beaconStateSchema.getLastExecutionPayloadHeaderSchema(); - this.blobKzgCommitmentsSchema = new BlobKzgCommitmentsSchema(specConfig); - this.beaconBlockBodySchema = - BeaconBlockBodySchemaDenebImpl.create( - specConfig, - getSignedBlsToExecutionChangeSchema(), - blobKzgCommitmentsSchema, - getMaxValidatorPerAttestation(specConfig), - "BeaconBlockBodyDeneb"); - this.blindedBeaconBlockBodySchema = - BlindedBeaconBlockBodySchemaDenebImpl.create( - specConfig, - getSignedBlsToExecutionChangeSchema(), - blobKzgCommitmentsSchema, - getMaxValidatorPerAttestation(specConfig), - "BlindedBlockBodyDeneb"); - this.beaconBlockSchema = new BeaconBlockSchema(beaconBlockBodySchema, "BeaconBlockDeneb"); - this.blindedBeaconBlockSchema = - new BeaconBlockSchema(blindedBeaconBlockBodySchema, "BlindedBlockDeneb"); - this.signedBeaconBlockSchema = - new SignedBeaconBlockSchema(beaconBlockSchema, "SignedBeaconBlockDeneb"); - this.signedBlindedBeaconBlockSchema = - new SignedBeaconBlockSchema(blindedBeaconBlockSchema, "SignedBlindedBlockDeneb"); this.builderBidSchemaDeneb = new BuilderBidSchemaDeneb( - "BuilderBidDeneb", executionPayloadHeaderSchemaDeneb, blobKzgCommitmentsSchema); + "BuilderBidDeneb", getExecutionPayloadHeaderSchema(), getBlobKzgCommitmentsSchema()); this.signedBuilderBidSchemaDeneb = new SignedBuilderBidSchema("SignedBuilderBidDeneb", builderBidSchemaDeneb); @@ -125,14 +76,16 @@ public SchemaDefinitionsDeneb(final SpecConfigDeneb specConfig) { blobSchema, specConfig.getKzgCommitmentInclusionProofDepth()); this.blockContentsSchema = - BlockContentsSchema.create(specConfig, beaconBlockSchema, blobSchema, "BlockContentsDeneb"); + BlockContentsSchema.create( + specConfig, getBeaconBlockSchema(), blobSchema, "BlockContentsDeneb"); this.signedBlockContentsSchema = SignedBlockContentsSchema.create( - specConfig, signedBeaconBlockSchema, blobSchema, "SignedBlockContentsDeneb"); + specConfig, getSignedBeaconBlockSchema(), blobSchema, "SignedBlockContentsDeneb"); this.blobsBundleSchema = - new BlobsBundleSchema("BlobsBundleDeneb", blobSchema, blobKzgCommitmentsSchema, specConfig); + new BlobsBundleSchema( + "BlobsBundleDeneb", blobSchema, getBlobKzgCommitmentsSchema(), specConfig); this.executionPayloadAndBlobsBundleSchema = - new ExecutionPayloadAndBlobsBundleSchema(executionPayloadSchemaDeneb, blobsBundleSchema); + new ExecutionPayloadAndBlobsBundleSchema(getExecutionPayloadSchema(), blobsBundleSchema); this.blobSidecarsByRootRequestMessageSchema = new BlobSidecarsByRootRequestMessageSchema(specConfig); } @@ -147,39 +100,11 @@ public static SchemaDefinitionsDeneb required(final SchemaDefinitions schemaDefi } @Override - public BeaconStateSchema - getBeaconStateSchema() { - return beaconStateSchema; - } - - @Override - public BeaconBlockBodySchema getBeaconBlockBodySchema() { - return beaconBlockBodySchema; - } - - @Override - public BeaconBlockBodySchema getBlindedBeaconBlockBodySchema() { - return blindedBeaconBlockBodySchema; - } - - @Override - public BeaconBlockSchema getBeaconBlockSchema() { - return beaconBlockSchema; - } - - @Override - public BeaconBlockSchema getBlindedBeaconBlockSchema() { - return blindedBeaconBlockSchema; - } - - @Override - public SignedBeaconBlockSchema getSignedBeaconBlockSchema() { - return signedBeaconBlockSchema; - } - - @Override - public SignedBeaconBlockSchema getSignedBlindedBeaconBlockSchema() { - return signedBlindedBeaconBlockSchema; + @SuppressWarnings("unchecked") + public BeaconBlockBodySchema + getBlindedBeaconBlockBodySchema() { + return (BeaconBlockBodySchema) + schemaRegistry.get(BLINDED_BEACON_BLOCK_BODY_SCHEMA); } @Override @@ -187,31 +112,11 @@ public BlockContainerSchema getBlockContainerSchema() { return getBlockContentsSchema().castTypeToBlockContainer(); } - @Override - public BlockContainerSchema getBlindedBlockContainerSchema() { - return getBlindedBeaconBlockSchema().castTypeToBlockContainer(); - } - @Override public SignedBlockContainerSchema getSignedBlockContainerSchema() { return getSignedBlockContentsSchema().castTypeToSignedBlockContainer(); } - @Override - public SignedBlockContainerSchema getSignedBlindedBlockContainerSchema() { - return getSignedBlindedBeaconBlockSchema().castTypeToSignedBlockContainer(); - } - - @Override - public ExecutionPayloadSchema getExecutionPayloadSchema() { - return executionPayloadSchemaDeneb; - } - - @Override - public ExecutionPayloadHeaderSchema getExecutionPayloadHeaderSchema() { - return executionPayloadHeaderSchemaDeneb; - } - @Override public BuilderBidSchema getBuilderBidSchema() { return builderBidSchemaDeneb; @@ -229,7 +134,9 @@ public BuilderPayloadSchema getBuilderPayloadSchema() { @Override public BeaconBlockBodyBuilder createBeaconBlockBodyBuilder() { - return new BeaconBlockBodyBuilderDeneb(beaconBlockBodySchema, blindedBeaconBlockBodySchema); + return new BeaconBlockBodyBuilderDeneb( + getBeaconBlockBodySchema().toVersionDeneb().orElseThrow(), + getBlindedBeaconBlockBodySchema()); } public BlobSchema getBlobSchema() { @@ -237,7 +144,7 @@ public BlobSchema getBlobSchema() { } public BlobKzgCommitmentsSchema getBlobKzgCommitmentsSchema() { - return blobKzgCommitmentsSchema; + return schemaRegistry.get(BLOB_KZG_COMMITMENTS_SCHEMA); } public SszListSchema> getBlobsInBlockSchema() { 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 4d6ecfd09eb..d0ba41884b3 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 @@ -14,22 +14,20 @@ package tech.pegasys.teku.spec.schemas; import static com.google.common.base.Preconditions.checkArgument; +import static tech.pegasys.teku.spec.schemas.SchemaTypes.BEACON_STATE_SCHEMA; +import static tech.pegasys.teku.spec.schemas.SchemaTypes.BLINDED_BEACON_BLOCK_BODY_SCHEMA; import java.util.Optional; import tech.pegasys.teku.infrastructure.ssz.schema.SszListSchema; -import tech.pegasys.teku.spec.config.SpecConfig; import tech.pegasys.teku.spec.config.SpecConfigElectra; -import tech.pegasys.teku.spec.datastructures.blocks.BeaconBlockSchema; import tech.pegasys.teku.spec.datastructures.blocks.BlockContainer; import tech.pegasys.teku.spec.datastructures.blocks.BlockContainerSchema; -import tech.pegasys.teku.spec.datastructures.blocks.SignedBeaconBlockSchema; import tech.pegasys.teku.spec.datastructures.blocks.SignedBlockContainer; import tech.pegasys.teku.spec.datastructures.blocks.SignedBlockContainerSchema; import tech.pegasys.teku.spec.datastructures.blocks.blockbody.BeaconBlockBodyBuilder; import tech.pegasys.teku.spec.datastructures.blocks.blockbody.BeaconBlockBodySchema; import tech.pegasys.teku.spec.datastructures.blocks.blockbody.versions.electra.BeaconBlockBodyBuilderElectra; -import tech.pegasys.teku.spec.datastructures.blocks.blockbody.versions.electra.BeaconBlockBodySchemaElectraImpl; -import tech.pegasys.teku.spec.datastructures.blocks.blockbody.versions.electra.BlindedBeaconBlockBodySchemaElectraImpl; +import tech.pegasys.teku.spec.datastructures.blocks.blockbody.versions.electra.BlindedBeaconBlockBodyElectra; import tech.pegasys.teku.spec.datastructures.blocks.versions.deneb.BlockContentsSchema; import tech.pegasys.teku.spec.datastructures.blocks.versions.deneb.SignedBlockContentsSchema; import tech.pegasys.teku.spec.datastructures.builder.BlobsBundleSchema; @@ -38,56 +36,19 @@ import tech.pegasys.teku.spec.datastructures.builder.ExecutionPayloadAndBlobsBundleSchema; import tech.pegasys.teku.spec.datastructures.builder.SignedBuilderBidSchema; import tech.pegasys.teku.spec.datastructures.builder.versions.deneb.BuilderBidSchemaDeneb; -import tech.pegasys.teku.spec.datastructures.execution.ExecutionPayloadHeaderSchema; -import tech.pegasys.teku.spec.datastructures.execution.ExecutionPayloadSchema; import tech.pegasys.teku.spec.datastructures.execution.versions.electra.ConsolidationRequest; import tech.pegasys.teku.spec.datastructures.execution.versions.electra.ConsolidationRequestSchema; import tech.pegasys.teku.spec.datastructures.execution.versions.electra.DepositRequest; import tech.pegasys.teku.spec.datastructures.execution.versions.electra.DepositRequestSchema; -import tech.pegasys.teku.spec.datastructures.execution.versions.electra.ExecutionPayloadHeaderSchemaElectra; -import tech.pegasys.teku.spec.datastructures.execution.versions.electra.ExecutionPayloadSchemaElectra; 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.execution.versions.electra.WithdrawalRequestSchema; -import tech.pegasys.teku.spec.datastructures.operations.AggregateAndProof.AggregateAndProofSchema; -import tech.pegasys.teku.spec.datastructures.operations.Attestation; -import tech.pegasys.teku.spec.datastructures.operations.AttestationSchema; -import tech.pegasys.teku.spec.datastructures.operations.AttesterSlashing; -import tech.pegasys.teku.spec.datastructures.operations.AttesterSlashingSchema; -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; -import tech.pegasys.teku.spec.datastructures.state.beaconstate.versions.electra.BeaconStateElectra; import tech.pegasys.teku.spec.datastructures.state.beaconstate.versions.electra.BeaconStateSchemaElectra; -import tech.pegasys.teku.spec.datastructures.state.beaconstate.versions.electra.MutableBeaconStateElectra; import tech.pegasys.teku.spec.datastructures.state.versions.electra.PendingBalanceDeposit; import tech.pegasys.teku.spec.datastructures.state.versions.electra.PendingConsolidation; import tech.pegasys.teku.spec.datastructures.state.versions.electra.PendingPartialWithdrawal; public class SchemaDefinitionsElectra extends SchemaDefinitionsDeneb { - private final IndexedAttestationSchema indexedAttestationSchema; - private final AttesterSlashingSchema attesterSlashingSchema; - private final AttestationSchema attestationSchema; - private final SignedAggregateAndProofSchema signedAggregateAndProofSchema; - private final AggregateAndProofSchema aggregateAndProofSchema; - - private final BeaconStateSchemaElectra beaconStateSchema; - - private final ExecutionPayloadSchemaElectra executionPayloadSchemaElectra; - private final ExecutionPayloadHeaderSchemaElectra executionPayloadHeaderSchemaElectra; - - private final BeaconBlockBodySchemaElectraImpl beaconBlockBodySchema; - private final BlindedBeaconBlockBodySchemaElectraImpl blindedBeaconBlockBodySchema; - - private final BeaconBlockSchema beaconBlockSchema; - private final BeaconBlockSchema blindedBeaconBlockSchema; - private final SignedBeaconBlockSchema signedBeaconBlockSchema; - private final SignedBeaconBlockSchema signedBlindedBeaconBlockSchema; - private final BuilderBidSchema builderBidSchemaElectra; private final SignedBuilderBidSchema signedBuilderBidSchemaElectra; @@ -107,71 +68,31 @@ public class SchemaDefinitionsElectra extends SchemaDefinitionsDeneb { pendingPartialWithdrawalSchema; private final PendingConsolidation.PendingConsolidationSchema pendingConsolidationSchema; - public SchemaDefinitionsElectra(final SpecConfigElectra specConfig) { - super(specConfig); - - final long maxValidatorsPerAttestation = getMaxValidatorPerAttestation(specConfig); - this.indexedAttestationSchema = - new IndexedAttestationElectraSchema(maxValidatorsPerAttestation) - .castTypeToIndexedAttestationSchema(); - this.attesterSlashingSchema = - new AttesterSlashingElectraSchema(indexedAttestationSchema) - .castTypeToAttesterSlashingSchema(); - - this.attestationSchema = - new AttestationElectraSchema( - maxValidatorsPerAttestation, specConfig.getMaxCommitteesPerSlot()) - .castTypeToAttestationSchema(); - this.aggregateAndProofSchema = new AggregateAndProofSchema(attestationSchema); - this.signedAggregateAndProofSchema = new SignedAggregateAndProofSchema(aggregateAndProofSchema); - - this.executionPayloadSchemaElectra = new ExecutionPayloadSchemaElectra(specConfig); - - this.beaconStateSchema = BeaconStateSchemaElectra.create(specConfig); - this.executionPayloadHeaderSchemaElectra = - beaconStateSchema.getLastExecutionPayloadHeaderSchema(); - this.beaconBlockBodySchema = - BeaconBlockBodySchemaElectraImpl.create( - specConfig, - getAttesterSlashingSchema(), - getSignedBlsToExecutionChangeSchema(), - getBlobKzgCommitmentsSchema(), - maxValidatorsPerAttestation, - "BeaconBlockBodyElectra"); - this.blindedBeaconBlockBodySchema = - BlindedBeaconBlockBodySchemaElectraImpl.create( - specConfig, - getAttesterSlashingSchema(), - getSignedBlsToExecutionChangeSchema(), - getBlobKzgCommitmentsSchema(), - maxValidatorsPerAttestation, - "BlindedBlockBodyElectra"); - this.beaconBlockSchema = new BeaconBlockSchema(beaconBlockBodySchema, "BeaconBlockElectra"); - this.blindedBeaconBlockSchema = - new BeaconBlockSchema(blindedBeaconBlockBodySchema, "BlindedBlockElectra"); - this.signedBeaconBlockSchema = - new SignedBeaconBlockSchema(beaconBlockSchema, "SignedBeaconBlockElectra"); - this.signedBlindedBeaconBlockSchema = - new SignedBeaconBlockSchema(blindedBeaconBlockSchema, "SignedBlindedBlockElectra"); + public SchemaDefinitionsElectra(final SchemaRegistry schemaRegistry) { + super(schemaRegistry); + + final SpecConfigElectra specConfig = SpecConfigElectra.required(schemaRegistry.getSpecConfig()); + this.builderBidSchemaElectra = new BuilderBidSchemaDeneb( - "BuilderBidElectra", - executionPayloadHeaderSchemaElectra, - getBlobKzgCommitmentsSchema()); + "BuilderBidElectra", getExecutionPayloadHeaderSchema(), getBlobKzgCommitmentsSchema()); this.signedBuilderBidSchemaElectra = new SignedBuilderBidSchema("SignedBuilderBidElectra", builderBidSchemaElectra); this.blockContentsSchema = BlockContentsSchema.create( - specConfig, beaconBlockSchema, getBlobSchema(), "BlockContentsElectra"); + specConfig, getBeaconBlockSchema(), getBlobSchema(), "BlockContentsElectra"); this.signedBlockContentsSchema = SignedBlockContentsSchema.create( - specConfig, signedBeaconBlockSchema, getBlobSchema(), "SignedBlockContentsElectra"); + specConfig, + getSignedBeaconBlockSchema(), + getBlobSchema(), + "SignedBlockContentsElectra"); this.blobsBundleSchema = new BlobsBundleSchema( "BlobsBundleElectra", getBlobSchema(), getBlobKzgCommitmentsSchema(), specConfig); this.executionPayloadAndBlobsBundleSchema = - new ExecutionPayloadAndBlobsBundleSchema(executionPayloadSchemaElectra, blobsBundleSchema); + new ExecutionPayloadAndBlobsBundleSchema(getExecutionPayloadSchema(), blobsBundleSchema); this.executionRequestsSchema = new ExecutionRequestsSchema(specConfig); this.depositRequestSchema = DepositRequest.SSZ_SCHEMA; @@ -193,64 +114,11 @@ public static SchemaDefinitionsElectra required(final SchemaDefinitions schemaDe } @Override - public SignedAggregateAndProofSchema getSignedAggregateAndProofSchema() { - return signedAggregateAndProofSchema; - } - - @Override - public AggregateAndProofSchema getAggregateAndProofSchema() { - return aggregateAndProofSchema; - } - - @Override - public AttestationSchema getAttestationSchema() { - return attestationSchema; - } - - @Override - public IndexedAttestationSchema getIndexedAttestationSchema() { - return indexedAttestationSchema; - } - - @Override - public AttesterSlashingSchema getAttesterSlashingSchema() { - return attesterSlashingSchema; - } - - @Override - public BeaconStateSchema - getBeaconStateSchema() { - return beaconStateSchema; - } - - @Override - public BeaconBlockBodySchema getBeaconBlockBodySchema() { - return beaconBlockBodySchema; - } - - @Override - public BeaconBlockBodySchema getBlindedBeaconBlockBodySchema() { - return blindedBeaconBlockBodySchema; - } - - @Override - public BeaconBlockSchema getBeaconBlockSchema() { - return beaconBlockSchema; - } - - @Override - public BeaconBlockSchema getBlindedBeaconBlockSchema() { - return blindedBeaconBlockSchema; - } - - @Override - public SignedBeaconBlockSchema getSignedBeaconBlockSchema() { - return signedBeaconBlockSchema; - } - - @Override - public SignedBeaconBlockSchema getSignedBlindedBeaconBlockSchema() { - return signedBlindedBeaconBlockSchema; + @SuppressWarnings("unchecked") + public BeaconBlockBodySchema + getBlindedBeaconBlockBodySchema() { + return (BeaconBlockBodySchema) + schemaRegistry.get(BLINDED_BEACON_BLOCK_BODY_SCHEMA); } @Override @@ -258,31 +126,11 @@ public BlockContainerSchema getBlockContainerSchema() { return getBlockContentsSchema().castTypeToBlockContainer(); } - @Override - public BlockContainerSchema getBlindedBlockContainerSchema() { - return getBlindedBeaconBlockSchema().castTypeToBlockContainer(); - } - @Override public SignedBlockContainerSchema getSignedBlockContainerSchema() { return getSignedBlockContentsSchema().castTypeToSignedBlockContainer(); } - @Override - public SignedBlockContainerSchema getSignedBlindedBlockContainerSchema() { - return getSignedBlindedBeaconBlockSchema().castTypeToSignedBlockContainer(); - } - - @Override - public ExecutionPayloadSchema getExecutionPayloadSchema() { - return executionPayloadSchemaElectra; - } - - @Override - public ExecutionPayloadHeaderSchema getExecutionPayloadHeaderSchema() { - return executionPayloadHeaderSchemaElectra; - } - @Override public BuilderBidSchema getBuilderBidSchema() { return builderBidSchemaElectra; @@ -300,7 +148,9 @@ public BuilderPayloadSchema getBuilderPayloadSchema() { @Override public BeaconBlockBodyBuilder createBeaconBlockBodyBuilder() { - return new BeaconBlockBodyBuilderElectra(beaconBlockBodySchema, blindedBeaconBlockBodySchema); + return new BeaconBlockBodyBuilderElectra( + getBeaconBlockBodySchema().toVersionElectra().orElseThrow(), + getBlindedBeaconBlockBodySchema()); } @Override @@ -340,15 +190,18 @@ public PendingBalanceDeposit.PendingBalanceDepositSchema getPendingBalanceDeposi } public SszListSchema getPendingBalanceDepositsSchema() { - return beaconStateSchema.getPendingBalanceDepositsSchema(); + return BeaconStateSchemaElectra.required(schemaRegistry.get(BEACON_STATE_SCHEMA)) + .getPendingBalanceDepositsSchema(); } public SszListSchema getPendingConsolidationsSchema() { - return beaconStateSchema.getPendingConsolidationsSchema(); + return BeaconStateSchemaElectra.required(schemaRegistry.get(BEACON_STATE_SCHEMA)) + .getPendingConsolidationsSchema(); } public SszListSchema getPendingPartialWithdrawalsSchema() { - return beaconStateSchema.getPendingPartialWithdrawalsSchema(); + return BeaconStateSchemaElectra.required(schemaRegistry.get(BEACON_STATE_SCHEMA)) + .getPendingPartialWithdrawalsSchema(); } public PendingPartialWithdrawal.PendingPartialWithdrawalSchema @@ -368,9 +221,4 @@ public PendingConsolidation.PendingConsolidationSchema getPendingConsolidationSc public ConsolidationRequestSchema getConsolidationRequestSchema() { return consolidationRequestSchema; } - - @Override - long getMaxValidatorPerAttestation(final SpecConfig specConfig) { - return (long) specConfig.getMaxValidatorsPerCommittee() * specConfig.getMaxCommitteesPerSlot(); - } } 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 83cb6ceb615..25b766d8a25 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 @@ -13,8 +13,18 @@ package tech.pegasys.teku.spec.schemas; +import static tech.pegasys.teku.spec.schemas.SchemaTypes.AGGREGATE_AND_PROOF_SCHEMA; +import static tech.pegasys.teku.spec.schemas.SchemaTypes.ATTESTATION_SCHEMA; +import static tech.pegasys.teku.spec.schemas.SchemaTypes.ATTESTER_SLASHING_SCHEMA; +import static tech.pegasys.teku.spec.schemas.SchemaTypes.BEACON_BLOCK_BODY_SCHEMA; +import static tech.pegasys.teku.spec.schemas.SchemaTypes.BEACON_BLOCK_SCHEMA; +import static tech.pegasys.teku.spec.schemas.SchemaTypes.BEACON_STATE_SCHEMA; +import static tech.pegasys.teku.spec.schemas.SchemaTypes.INDEXED_ATTESTATION_SCHEMA; +import static tech.pegasys.teku.spec.schemas.SchemaTypes.METADATA_MESSAGE_SCHEMA; +import static tech.pegasys.teku.spec.schemas.SchemaTypes.SIGNED_AGGREGATE_AND_PROOF_SCHEMA; +import static tech.pegasys.teku.spec.schemas.SchemaTypes.SIGNED_BEACON_BLOCK_SCHEMA; + import java.util.Optional; -import tech.pegasys.teku.spec.config.SpecConfig; import tech.pegasys.teku.spec.datastructures.blocks.BeaconBlockSchema; import tech.pegasys.teku.spec.datastructures.blocks.BlockContainer; import tech.pegasys.teku.spec.datastructures.blocks.BlockContainerSchema; @@ -24,8 +34,7 @@ import tech.pegasys.teku.spec.datastructures.blocks.blockbody.BeaconBlockBodyBuilder; import tech.pegasys.teku.spec.datastructures.blocks.blockbody.BeaconBlockBodySchema; import tech.pegasys.teku.spec.datastructures.blocks.blockbody.versions.phase0.BeaconBlockBodyBuilderPhase0; -import tech.pegasys.teku.spec.datastructures.blocks.blockbody.versions.phase0.BeaconBlockBodySchemaPhase0; -import tech.pegasys.teku.spec.datastructures.networking.libp2p.rpc.metadata.versions.phase0.MetadataMessageSchemaPhase0; +import tech.pegasys.teku.spec.datastructures.networking.libp2p.rpc.metadata.MetadataMessageSchema; import tech.pegasys.teku.spec.datastructures.operations.AggregateAndProof.AggregateAndProofSchema; import tech.pegasys.teku.spec.datastructures.operations.Attestation; import tech.pegasys.teku.spec.datastructures.operations.AttestationSchema; @@ -34,99 +43,57 @@ 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; public class SchemaDefinitionsPhase0 extends AbstractSchemaDefinitions { - private final IndexedAttestationSchema indexedAttestationSchema; - private final AttesterSlashingSchema attesterSlashingSchema; - private final AttestationSchema attestationSchema; - private final SignedAggregateAndProofSchema signedAggregateAndProofSchema; - private final AggregateAndProofSchema aggregateAndProofSchema; - private final BeaconStateSchemaPhase0 beaconStateSchema; - private final BeaconBlockBodySchemaPhase0 beaconBlockBodySchema; - private final MetadataMessageSchemaPhase0 metadataMessageSchema; - private final BeaconBlockSchema beaconBlockSchema; - private final SignedBeaconBlockSchema signedBeaconBlockSchema; - - public SchemaDefinitionsPhase0(final SpecConfig specConfig) { - super(specConfig); - this.indexedAttestationSchema = - new IndexedAttestationPhase0Schema(getMaxValidatorPerAttestation(specConfig)) - .castTypeToIndexedAttestationSchema(); - this.attesterSlashingSchema = - new AttesterSlashingPhase0Schema(indexedAttestationSchema) - .castTypeToAttesterSlashingSchema(); - - this.aggregateAndProofSchema = - new AggregateAndProofSchema( - new AttestationPhase0Schema(getMaxValidatorPerAttestation(specConfig))); - this.attestationSchema = this.aggregateAndProofSchema.getAttestationSchema(); - this.signedAggregateAndProofSchema = new SignedAggregateAndProofSchema(aggregateAndProofSchema); - this.beaconStateSchema = BeaconStateSchemaPhase0.create(specConfig); - this.beaconBlockBodySchema = - BeaconBlockBodySchemaPhase0.create( - specConfig, - getAttesterSlashingSchema(), - getMaxValidatorPerAttestation(specConfig), - "BeaconBlockBodyPhase0"); - this.metadataMessageSchema = new MetadataMessageSchemaPhase0(specConfig.getNetworkingConfig()); - beaconBlockSchema = new BeaconBlockSchema(beaconBlockBodySchema, "BeaconBlockPhase0"); - signedBeaconBlockSchema = - new SignedBeaconBlockSchema(beaconBlockSchema, "SignedBeaconBlockPhase0"); - } - - @Override - long getMaxValidatorPerAttestation(final SpecConfig specConfig) { - return specConfig.getMaxValidatorsPerCommittee(); + + public SchemaDefinitionsPhase0(final SchemaRegistry schemaRegistry) { + super(schemaRegistry); } @Override public SignedAggregateAndProofSchema getSignedAggregateAndProofSchema() { - return signedAggregateAndProofSchema; + return schemaRegistry.get(SIGNED_AGGREGATE_AND_PROOF_SCHEMA); } @Override public AggregateAndProofSchema getAggregateAndProofSchema() { - return aggregateAndProofSchema; + return schemaRegistry.get(AGGREGATE_AND_PROOF_SCHEMA); } @Override public AttestationSchema getAttestationSchema() { - return attestationSchema; + return schemaRegistry.get(ATTESTATION_SCHEMA); } @Override public IndexedAttestationSchema getIndexedAttestationSchema() { - return indexedAttestationSchema; + return schemaRegistry.get(INDEXED_ATTESTATION_SCHEMA); } @Override public AttesterSlashingSchema getAttesterSlashingSchema() { - return attesterSlashingSchema; + return schemaRegistry.get(ATTESTER_SLASHING_SCHEMA); } @Override public BeaconStateSchema getBeaconStateSchema() { - return beaconStateSchema; + return schemaRegistry.get(BEACON_STATE_SCHEMA); } @Override public SignedBeaconBlockSchema getSignedBeaconBlockSchema() { - return signedBeaconBlockSchema; + return schemaRegistry.get(SIGNED_BEACON_BLOCK_SCHEMA); } @Override public BeaconBlockSchema getBeaconBlockSchema() { - return beaconBlockSchema; + return schemaRegistry.get(BEACON_BLOCK_SCHEMA); } @Override public BeaconBlockBodySchema getBeaconBlockBodySchema() { - return beaconBlockBodySchema; + return schemaRegistry.get(BEACON_BLOCK_BODY_SCHEMA); } @Override @@ -166,12 +133,12 @@ public SignedBlockContainerSchema getSignedBlindedBlockCon @Override public BeaconBlockBodyBuilder createBeaconBlockBodyBuilder() { - return new BeaconBlockBodyBuilderPhase0(beaconBlockBodySchema); + return new BeaconBlockBodyBuilderPhase0(getBeaconBlockBodySchema()); } @Override - public MetadataMessageSchemaPhase0 getMetadataMessageSchema() { - return metadataMessageSchema; + public MetadataMessageSchema getMetadataMessageSchema() { + return schemaRegistry.get(METADATA_MESSAGE_SCHEMA); } @Override diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/SchemaProvider.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/SchemaProvider.java new file mode 100644 index 00000000000..a49ceccb2fb --- /dev/null +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/SchemaProvider.java @@ -0,0 +1,52 @@ +/* + * 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; + +import static tech.pegasys.teku.spec.SpecMilestone.BELLATRIX; +import static tech.pegasys.teku.spec.SpecMilestone.CAPELLA; +import static tech.pegasys.teku.spec.SpecMilestone.DENEB; +import static tech.pegasys.teku.spec.SpecMilestone.ELECTRA; + +import java.util.EnumSet; +import java.util.Set; +import tech.pegasys.teku.spec.SpecMilestone; +import tech.pegasys.teku.spec.schemas.SchemaTypes.SchemaId; + +public interface SchemaProvider { + Set ALL_MILESTONES = EnumSet.allOf(SpecMilestone.class); + Set FROM_BELLATRIX = from(BELLATRIX); + Set FROM_CAPELLA = from(CAPELLA); + Set FROM_DENEB = from(DENEB); + Set FROM_ELECTRA = from(ELECTRA); + + static Set from(final SpecMilestone milestone) { + return EnumSet.copyOf(SpecMilestone.getAllMilestonesFrom(milestone)); + } + + static Set fromTo( + final SpecMilestone fromMilestone, final SpecMilestone toMilestone) { + return EnumSet.copyOf( + SpecMilestone.getAllMilestonesFrom(fromMilestone).stream() + .filter(toMilestone::isLessThanOrEqualTo) + .toList()); + } + + T getSchema(SchemaRegistry registry); + + Set getSupportedMilestones(); + + SpecMilestone getEffectiveMilestone(SpecMilestone version); + + SchemaId getSchemaId(); +} diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/SchemaRegistry.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/SchemaRegistry.java new file mode 100644 index 00000000000..871415f5292 --- /dev/null +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/SchemaRegistry.java @@ -0,0 +1,88 @@ +/* + * 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; + +import com.google.common.annotations.VisibleForTesting; +import java.util.HashMap; +import java.util.Map; +import tech.pegasys.teku.spec.SpecMilestone; +import tech.pegasys.teku.spec.config.SpecConfig; +import tech.pegasys.teku.spec.schemas.SchemaTypes.SchemaId; + +public class SchemaRegistry { + private final Map, SchemaProvider> providers = new HashMap<>(); + private final SpecMilestone milestone; + private final SchemaCache cache; + private final SpecConfig specConfig; + + public SchemaRegistry( + final SpecMilestone milestone, final SpecConfig specConfig, final SchemaCache cache) { + this.milestone = milestone; + this.specConfig = specConfig; + this.cache = cache; + } + + public void registerProvider(final SchemaProvider provider) { + providers.put(provider.getSchemaId(), provider); + } + + @VisibleForTesting + boolean isProviderRegistered(final SchemaProvider provider) { + return provider.equals(providers.get(provider.getSchemaId())); + } + + @SuppressWarnings("unchecked") + public T get(final SchemaId schemaClass) { + SchemaProvider provider = (SchemaProvider) providers.get(schemaClass); + if (provider == null) { + throw new IllegalArgumentException( + "No provider registered for schema " + + schemaClass + + " or it does not support milestone " + + milestone); + } + T schema = cache.get(milestone, schemaClass); + if (schema != null) { + return schema; + } + final SpecMilestone effectiveMilestone = provider.getEffectiveMilestone(milestone); + if (effectiveMilestone != milestone) { + schema = cache.get(effectiveMilestone, schemaClass); + if (schema != null) { + cache.put(milestone, schemaClass, schema); + return schema; + } + } + schema = provider.getSchema(this); + cache.put(effectiveMilestone, schemaClass, schema); + if (effectiveMilestone != milestone) { + cache.put(milestone, schemaClass, schema); + } + return schema; + } + + public SpecMilestone getMilestone() { + return milestone; + } + + public SpecConfig getSpecConfig() { + return specConfig; + } + + public void primeRegistry() { + for (final SchemaId schemaClass : providers.keySet()) { + get(schemaClass); + } + } +} diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/SchemaRegistryBuilder.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/SchemaRegistryBuilder.java new file mode 100644 index 00000000000..37579fd2e08 --- /dev/null +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/SchemaRegistryBuilder.java @@ -0,0 +1,101 @@ +/* + * 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; + +import com.google.common.annotations.VisibleForTesting; +import java.util.ArrayList; +import java.util.List; +import tech.pegasys.teku.spec.SpecMilestone; +import tech.pegasys.teku.spec.config.SpecConfig; +import tech.pegasys.teku.spec.schemas.providers.AggregateAndProofSchemaProvider; +import tech.pegasys.teku.spec.schemas.providers.AttestationSchemaProvider; +import tech.pegasys.teku.spec.schemas.providers.AttesterShlashingSchemaProvider; +import tech.pegasys.teku.spec.schemas.providers.AttnetsENRFieldSchemaProvider; +import tech.pegasys.teku.spec.schemas.providers.BeaconBlockBodySchemaProvider; +import tech.pegasys.teku.spec.schemas.providers.BeaconBlockSchemaProvider; +import tech.pegasys.teku.spec.schemas.providers.BeaconBlocksByRootRequestMessageSchemaProvider; +import tech.pegasys.teku.spec.schemas.providers.BeaconStateSchemaProvider; +import tech.pegasys.teku.spec.schemas.providers.BlindedBeaconBlockBodySchemaProvider; +import tech.pegasys.teku.spec.schemas.providers.BlindedBeaconBlockSchemaProvider; +import tech.pegasys.teku.spec.schemas.providers.BlobKzgCommitmentsSchemaProvider; +import tech.pegasys.teku.spec.schemas.providers.BlsToExecutionChangeSchemaProvider; +import tech.pegasys.teku.spec.schemas.providers.ExecutionPayloadHeaderSchemaProvider; +import tech.pegasys.teku.spec.schemas.providers.ExecutionPayloadSchemaProvider; +import tech.pegasys.teku.spec.schemas.providers.HistoricalBatchSchemaProvider; +import tech.pegasys.teku.spec.schemas.providers.IndexedAttestationSchemaProvider; +import tech.pegasys.teku.spec.schemas.providers.MetadataMessageSchemaProvider; +import tech.pegasys.teku.spec.schemas.providers.SignedAggregateAndProofSchemaProvider; +import tech.pegasys.teku.spec.schemas.providers.SignedBeaconBlockSchemaProvider; +import tech.pegasys.teku.spec.schemas.providers.SignedBlindedBeaconBlockSchemaProvider; +import tech.pegasys.teku.spec.schemas.providers.SignedBlsToExecutionChangeSchemaProvider; +import tech.pegasys.teku.spec.schemas.providers.SyncnetsENRFieldSchemaProvider; + +public class SchemaRegistryBuilder { + private final List> providers = new ArrayList<>(); + private final SchemaCache cache; + + public static SchemaRegistryBuilder create() { + return new SchemaRegistryBuilder() + .addProvider(new AggregateAndProofSchemaProvider()) + .addProvider(new SignedAggregateAndProofSchemaProvider()) + .addProvider(new AttestationSchemaProvider()) + .addProvider(new AttesterShlashingSchemaProvider()) + .addProvider(new AttnetsENRFieldSchemaProvider()) + .addProvider(new BeaconBlockBodySchemaProvider()) + .addProvider(new BeaconBlockSchemaProvider()) + .addProvider(new SignedBeaconBlockSchemaProvider()) + .addProvider(new BeaconBlocksByRootRequestMessageSchemaProvider()) + .addProvider(new BeaconStateSchemaProvider()) + .addProvider(new HistoricalBatchSchemaProvider()) + .addProvider(new IndexedAttestationSchemaProvider()) + .addProvider(new MetadataMessageSchemaProvider()) + .addProvider(new SyncnetsENRFieldSchemaProvider()) + .addProvider(new ExecutionPayloadSchemaProvider()) + .addProvider(new ExecutionPayloadHeaderSchemaProvider()) + .addProvider(new BlindedBeaconBlockBodySchemaProvider()) + .addProvider(new BlindedBeaconBlockSchemaProvider()) + .addProvider(new SignedBlindedBeaconBlockSchemaProvider()) + .addProvider(new SignedBlsToExecutionChangeSchemaProvider()) + .addProvider(new BlsToExecutionChangeSchemaProvider()) + .addProvider(new BlobKzgCommitmentsSchemaProvider()); + } + + public SchemaRegistryBuilder() { + this.cache = SchemaCache.createDefault(); + } + + @VisibleForTesting + SchemaRegistryBuilder(final SchemaCache cache) { + this.cache = cache; + } + + public SchemaRegistryBuilder addProvider(final SchemaProvider provider) { + providers.add(provider); + return this; + } + + public SchemaRegistry build(final SpecMilestone milestone, final SpecConfig specConfig) { + final SchemaRegistry registry = new SchemaRegistry(milestone, specConfig, cache); + + for (final SchemaProvider provider : providers) { + if (provider.getSupportedMilestones().contains(milestone)) { + registry.registerProvider(provider); + } + } + + registry.primeRegistry(); + + return registry; + } +} diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/SchemaTypes.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/SchemaTypes.java new file mode 100644 index 00000000000..70f759b27e4 --- /dev/null +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/SchemaTypes.java @@ -0,0 +1,144 @@ +/* + * 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; + +import com.google.common.annotations.VisibleForTesting; +import com.google.common.base.MoreObjects; +import tech.pegasys.teku.infrastructure.ssz.collections.SszBitvector; +import tech.pegasys.teku.infrastructure.ssz.schema.collections.SszBitvectorSchema; +import tech.pegasys.teku.spec.datastructures.blobs.versions.deneb.BlobKzgCommitmentsSchema; +import tech.pegasys.teku.spec.datastructures.blocks.BeaconBlockSchema; +import tech.pegasys.teku.spec.datastructures.blocks.SignedBeaconBlockSchema; +import tech.pegasys.teku.spec.datastructures.blocks.blockbody.BeaconBlockBody; +import tech.pegasys.teku.spec.datastructures.blocks.blockbody.BeaconBlockBodySchema; +import tech.pegasys.teku.spec.datastructures.blocks.blockbody.versions.bellatrix.BlindedBeaconBlockBodySchemaBellatrix; +import tech.pegasys.teku.spec.datastructures.execution.ExecutionPayload; +import tech.pegasys.teku.spec.datastructures.execution.ExecutionPayloadHeader; +import tech.pegasys.teku.spec.datastructures.execution.ExecutionPayloadHeaderSchema; +import tech.pegasys.teku.spec.datastructures.execution.ExecutionPayloadSchema; +import tech.pegasys.teku.spec.datastructures.networking.libp2p.rpc.BeaconBlocksByRootRequestMessage.BeaconBlocksByRootRequestMessageSchema; +import tech.pegasys.teku.spec.datastructures.networking.libp2p.rpc.metadata.MetadataMessage; +import tech.pegasys.teku.spec.datastructures.networking.libp2p.rpc.metadata.MetadataMessageSchema; +import tech.pegasys.teku.spec.datastructures.operations.AggregateAndProof.AggregateAndProofSchema; +import tech.pegasys.teku.spec.datastructures.operations.Attestation; +import tech.pegasys.teku.spec.datastructures.operations.AttestationSchema; +import tech.pegasys.teku.spec.datastructures.operations.AttesterSlashing; +import tech.pegasys.teku.spec.datastructures.operations.AttesterSlashingSchema; +import tech.pegasys.teku.spec.datastructures.operations.BlsToExecutionChangeSchema; +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.SignedBlsToExecutionChangeSchema; +import tech.pegasys.teku.spec.datastructures.state.HistoricalBatch.HistoricalBatchSchema; +import tech.pegasys.teku.spec.datastructures.state.beaconstate.BeaconState; +import tech.pegasys.teku.spec.datastructures.state.beaconstate.BeaconStateSchema; +import tech.pegasys.teku.spec.datastructures.state.beaconstate.MutableBeaconState; + +public class SchemaTypes { + public static final SchemaId> ATTNETS_ENR_FIELD_SCHEMA = + create("ATTNETS_ENR_FIELD_SCHEMA"); + public static final SchemaId> SYNCNETS_ENR_FIELD_SCHEMA = + create("SYNCNETS_ENR_FIELD_SCHEMA"); + public static final SchemaId HISTORICAL_BATCH_SCHEMA = + create("HISTORICAL_BATCH_SCHEMA"); + public static final SchemaId + BEACON_BLOCKS_BY_ROOT_REQUEST_MESSAGE_SCHEMA = + create("BEACON_BLOCKS_BY_ROOT_REQUEST_MESSAGE_SCHEMA"); + + public static final SchemaId> + BEACON_BLOCK_BODY_SCHEMA = create("BEACON_BLOCK_BODY_SCHEMA"); + public static final SchemaId BEACON_BLOCK_SCHEMA = + create("BEACON_BLOCK_SCHEMA"); + public static final SchemaId SIGNED_BEACON_BLOCK_SCHEMA = + create("SIGNED_BEACON_BLOCK_SCHEMA"); + public static final SchemaId< + BeaconStateSchema> + BEACON_STATE_SCHEMA = create("BEACON_STATE_SCHEMA"); + public static final SchemaId> ATTESTATION_SCHEMA = + create("ATTESTATION_SCHEMA"); + public static final SchemaId SIGNED_AGGREGATE_AND_PROOF_SCHEMA = + create("SIGNED_AGGREGATE_AND_PROOF_SCHEMA"); + public static final SchemaId AGGREGATE_AND_PROOF_SCHEMA = + create("AGGREGATE_AND_PROOF_SCHEMA"); + public static final SchemaId> + METADATA_MESSAGE_SCHEMA = create("METADATA_MESSAGE_SCHEMA"); + public static final SchemaId> ATTESTER_SLASHING_SCHEMA = + create("ATTESTER_SLASHING_SCHEMA"); + public static final SchemaId> + INDEXED_ATTESTATION_SCHEMA = create("INDEXED_ATTESTATION_SCHEMA"); + + // Bellatrix + public static final SchemaId> + EXECUTION_PAYLOAD_SCHEMA = create("EXECUTION_PAYLOAD_SCHEMA"); + public static final SchemaId> + EXECUTION_PAYLOAD_HEADER_SCHEMA = create("EXECUTION_PAYLOAD_HEADER_SCHEMA"); + public static final SchemaId> + BLINDED_BEACON_BLOCK_BODY_SCHEMA = create("BLINDED_BEACON_BLOCK_BODY_SCHEMA"); + public static final SchemaId BLINDED_BEACON_BLOCK_SCHEMA = + create("BLINDED_BEACON_BLOCK_SCHEMA"); + public static final SchemaId SIGNED_BLINDED_BEACON_BLOCK_SCHEMA = + create("SIGNED_BLINDED_BEACON_BLOCK_SCHEMA"); + + // Capella + public static final SchemaId + SIGNED_BLS_TO_EXECUTION_CHANGE_SCHEMA = create("SIGNED_BLS_TO_EXECUTION_CHANGE_SCHEMA"); + public static final SchemaId BLS_TO_EXECUTION_CHANGE_SCHEMA = + create("BLS_TO_EXECUTION_CHANGE_SCHEMA"); + + // Deneb + public static final SchemaId BLOB_KZG_COMMITMENTS_SCHEMA = + create("BLOB_KZG_COMMITMENTS_SCHEMA"); + + private SchemaTypes() { + // Prevent instantiation + } + + @VisibleForTesting + static SchemaId create(final String name) { + return new SchemaId<>(name); + } + + public static class SchemaId { + private final String name; + + private SchemaId(final String name) { + this.name = name; + } + + public String getName() { + return name; + } + + @Override + public int hashCode() { + return name.hashCode(); + } + + @Override + public boolean equals(final Object o) { + if (this == o) { + return true; + } + if (o instanceof SchemaId other) { + return name.equals(other.name); + } + return false; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this).add("name", name).toString(); + } + } +} diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/providers/AggregateAndProofSchemaProvider.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/providers/AggregateAndProofSchemaProvider.java new file mode 100644 index 00000000000..e12b6d6d3ce --- /dev/null +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/providers/AggregateAndProofSchemaProvider.java @@ -0,0 +1,45 @@ +/* + * 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.providers; + +import static tech.pegasys.teku.spec.schemas.SchemaTypes.AGGREGATE_AND_PROOF_SCHEMA; +import static tech.pegasys.teku.spec.schemas.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.AggregateAndProof.AggregateAndProofSchema; +import tech.pegasys.teku.spec.schemas.AbstractSchemaProvider; +import tech.pegasys.teku.spec.schemas.SchemaRegistry; + +public class AggregateAndProofSchemaProvider + extends AbstractSchemaProvider { + + public AggregateAndProofSchemaProvider() { + super(AGGREGATE_AND_PROOF_SCHEMA); + } + + @Override + protected AggregateAndProofSchema createSchema( + final SchemaRegistry registry, + final SpecMilestone effectiveMilestone, + final SpecConfig specConfig) { + return new AggregateAndProofSchema(registry.get(ATTESTATION_SCHEMA)); + } + + @Override + public Set getSupportedMilestones() { + return ALL_MILESTONES; + } +} diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/providers/AttestationSchemaProvider.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/providers/AttestationSchemaProvider.java new file mode 100644 index 00000000000..07ac4edc979 --- /dev/null +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/providers/AttestationSchemaProvider.java @@ -0,0 +1,112 @@ +/* + * 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.providers; + +import static tech.pegasys.teku.spec.SpecMilestone.DENEB; +import static tech.pegasys.teku.spec.SpecMilestone.PHASE0; +import static tech.pegasys.teku.spec.schemas.SchemaTypes.ATTESTATION_SCHEMA; + +import java.util.Set; +import tech.pegasys.teku.infrastructure.ssz.SszTypeGenerator; +import tech.pegasys.teku.infrastructure.ssz.collections.SszBitlist; +import tech.pegasys.teku.infrastructure.ssz.collections.SszBitvector; +import tech.pegasys.teku.infrastructure.ssz.schema.collections.SszBitlistSchema; +import tech.pegasys.teku.infrastructure.ssz.schema.collections.SszBitvectorSchema; +import tech.pegasys.teku.infrastructure.ssz.schema.impl.AbstractSszContainerSchema.NamedSchema; +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.AttestationData; +import tech.pegasys.teku.spec.datastructures.operations.AttestationSchema; +import tech.pegasys.teku.spec.datastructures.operations.versions.electra.AttestationElectra; +import tech.pegasys.teku.spec.datastructures.operations.versions.electra.AttestationElectraSchema; +import tech.pegasys.teku.spec.datastructures.operations.versions.phase0.AttestationPhase0; +import tech.pegasys.teku.spec.datastructures.operations.versions.phase0.AttestationPhase0Schema; +import tech.pegasys.teku.spec.datastructures.type.SszSignature; +import tech.pegasys.teku.spec.datastructures.type.SszSignatureSchema; +import tech.pegasys.teku.spec.schemas.AbstractSchemaProvider; +import tech.pegasys.teku.spec.schemas.SchemaRegistry; + +public class AttestationSchemaProvider + extends AbstractSchemaProvider> { + + public AttestationSchemaProvider() { + super(ATTESTATION_SCHEMA); + addMilestoneMapping(PHASE0, DENEB); + } + + @Override + protected AttestationSchema createSchema( + final SchemaRegistry registry, + final SpecMilestone effectiveMilestone, + final SpecConfig specConfig) { + return switch (effectiveMilestone) { + case PHASE0 -> { + final SszTypeGenerator sszTypeGenerator = + new SszTypeGenerator<>( + AttestationPhase0.class, + AttestationPhase0Schema.class, + NamedSchema.of( + "aggregation_bits", + SszBitlistSchema.create(specConfig.getMaxValidatorsPerCommittee()), + SszBitlist.class), + NamedSchema.of("data", AttestationData.SSZ_SCHEMA, AttestationData.class), + NamedSchema.of("signature", SszSignatureSchema.INSTANCE, SszSignature.class)); + try { + yield sszTypeGenerator.defineType().castTypeToAttestationSchema(); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + // new AttestationPhase0Schema(specConfig.getMaxValidatorsPerCommittee()) + // .castTypeToAttestationSchema(); + case ELECTRA -> { + final SszTypeGenerator sszTypeGenerator = + new SszTypeGenerator<>( + AttestationElectra.class, + AttestationElectraSchema.class, + NamedSchema.of( + "aggregation_bits", + SszBitlistSchema.create( + (long) specConfig.getMaxValidatorsPerCommittee() + * specConfig.getMaxCommitteesPerSlot()), + SszBitlist.class), + NamedSchema.of("data", AttestationData.SSZ_SCHEMA, AttestationData.class), + NamedSchema.of("signature", SszSignatureSchema.INSTANCE, SszSignature.class), + NamedSchema.of( + "committee_bits", + SszBitvectorSchema.create(specConfig.getMaxCommitteesPerSlot()), + SszBitvector.class)); + try { + yield sszTypeGenerator.defineType().castTypeToAttestationSchema(); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + // 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/providers/AttesterShlashingSchemaProvider.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/providers/AttesterShlashingSchemaProvider.java new file mode 100644 index 00000000000..7f208052bb5 --- /dev/null +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/providers/AttesterShlashingSchemaProvider.java @@ -0,0 +1,61 @@ +/* + * 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.providers; + +import static tech.pegasys.teku.spec.SpecMilestone.DENEB; +import static tech.pegasys.teku.spec.SpecMilestone.PHASE0; +import static tech.pegasys.teku.spec.schemas.SchemaTypes.INDEXED_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.AttesterSlashing; +import tech.pegasys.teku.spec.datastructures.operations.AttesterSlashingSchema; +import tech.pegasys.teku.spec.datastructures.operations.versions.electra.AttesterSlashingElectraSchema; +import tech.pegasys.teku.spec.datastructures.operations.versions.phase0.AttesterSlashingPhase0Schema; +import tech.pegasys.teku.spec.schemas.AbstractSchemaProvider; +import tech.pegasys.teku.spec.schemas.SchemaRegistry; +import tech.pegasys.teku.spec.schemas.SchemaTypes; + +public class AttesterShlashingSchemaProvider + extends AbstractSchemaProvider> { + + public AttesterShlashingSchemaProvider() { + super(SchemaTypes.ATTESTER_SLASHING_SCHEMA); + addMilestoneMapping(PHASE0, DENEB); + } + + @Override + protected AttesterSlashingSchema createSchema( + final SchemaRegistry registry, + final SpecMilestone effectiveMilestone, + final SpecConfig specConfig) { + return switch (effectiveMilestone) { + case PHASE0 -> + new AttesterSlashingPhase0Schema(registry.get(INDEXED_ATTESTATION_SCHEMA)) + .castTypeToAttesterSlashingSchema(); + case ELECTRA -> + new AttesterSlashingElectraSchema(registry.get(INDEXED_ATTESTATION_SCHEMA)) + .castTypeToAttesterSlashingSchema(); + 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/providers/AttnetsENRFieldSchemaProvider.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/providers/AttnetsENRFieldSchemaProvider.java new file mode 100644 index 00000000000..9b93e36f655 --- /dev/null +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/providers/AttnetsENRFieldSchemaProvider.java @@ -0,0 +1,46 @@ +/* + * 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.providers; + +import static tech.pegasys.teku.spec.SpecMilestone.PHASE0; +import static tech.pegasys.teku.spec.schemas.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; +import tech.pegasys.teku.spec.schemas.AbstractSchemaProvider; +import tech.pegasys.teku.spec.schemas.SchemaRegistry; + +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/providers/BeaconBlockBodySchemaProvider.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/providers/BeaconBlockBodySchemaProvider.java new file mode 100644 index 00000000000..4de11228284 --- /dev/null +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/providers/BeaconBlockBodySchemaProvider.java @@ -0,0 +1,72 @@ +/* + * 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.providers; + +import static tech.pegasys.teku.spec.schemas.SchemaTypes.BEACON_BLOCK_BODY_SCHEMA; + +import java.util.Set; +import tech.pegasys.teku.spec.SpecMilestone; +import tech.pegasys.teku.spec.config.SpecConfig; +import tech.pegasys.teku.spec.config.SpecConfigBellatrix; +import tech.pegasys.teku.spec.config.SpecConfigCapella; +import tech.pegasys.teku.spec.config.SpecConfigDeneb; +import tech.pegasys.teku.spec.config.SpecConfigElectra; +import tech.pegasys.teku.spec.datastructures.blocks.blockbody.BeaconBlockBody; +import tech.pegasys.teku.spec.datastructures.blocks.blockbody.BeaconBlockBodySchema; +import tech.pegasys.teku.spec.datastructures.blocks.blockbody.versions.altair.BeaconBlockBodySchemaAltairImpl; +import tech.pegasys.teku.spec.datastructures.blocks.blockbody.versions.bellatrix.BeaconBlockBodySchemaBellatrixImpl; +import tech.pegasys.teku.spec.datastructures.blocks.blockbody.versions.capella.BeaconBlockBodySchemaCapellaImpl; +import tech.pegasys.teku.spec.datastructures.blocks.blockbody.versions.deneb.BeaconBlockBodySchemaDenebImpl; +import tech.pegasys.teku.spec.datastructures.blocks.blockbody.versions.electra.BeaconBlockBodySchemaElectraImpl; +import tech.pegasys.teku.spec.datastructures.blocks.blockbody.versions.phase0.BeaconBlockBodySchemaPhase0; +import tech.pegasys.teku.spec.schemas.AbstractSchemaProvider; +import tech.pegasys.teku.spec.schemas.SchemaRegistry; + +public class BeaconBlockBodySchemaProvider + extends AbstractSchemaProvider> { + + public BeaconBlockBodySchemaProvider() { + super(BEACON_BLOCK_BODY_SCHEMA); + } + + @Override + protected BeaconBlockBodySchema createSchema( + final SchemaRegistry registry, + final SpecMilestone effectiveMilestone, + final SpecConfig specConfig) { + return switch (effectiveMilestone) { + case PHASE0 -> + BeaconBlockBodySchemaPhase0.create(specConfig, registry, "BeaconBlockBodyPhase0"); + case ALTAIR -> + BeaconBlockBodySchemaAltairImpl.create(specConfig, registry, "BeaconBlockBodyAltair"); + case BELLATRIX -> + BeaconBlockBodySchemaBellatrixImpl.create( + SpecConfigBellatrix.required(specConfig), registry, "BeaconBlockBodyBellatrix"); + case CAPELLA -> + BeaconBlockBodySchemaCapellaImpl.create( + SpecConfigCapella.required(specConfig), registry, "BeaconBlockBodyCapella"); + case DENEB -> + BeaconBlockBodySchemaDenebImpl.create( + SpecConfigDeneb.required(specConfig), registry, "BeaconBlockBodyDeneb"); + case ELECTRA -> + BeaconBlockBodySchemaElectraImpl.create( + SpecConfigElectra.required(specConfig), registry, "BeaconBlockBodyElectra"); + }; + } + + @Override + public Set getSupportedMilestones() { + return ALL_MILESTONES; + } +} diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/providers/BeaconBlockSchemaProvider.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/providers/BeaconBlockSchemaProvider.java new file mode 100644 index 00000000000..6ee8d9f5f24 --- /dev/null +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/providers/BeaconBlockSchemaProvider.java @@ -0,0 +1,46 @@ +/* + * 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.providers; + +import static tech.pegasys.teku.spec.schemas.SchemaTypes.BEACON_BLOCK_BODY_SCHEMA; + +import java.util.Set; +import tech.pegasys.teku.spec.SpecMilestone; +import tech.pegasys.teku.spec.config.SpecConfig; +import tech.pegasys.teku.spec.datastructures.blocks.BeaconBlockSchema; +import tech.pegasys.teku.spec.schemas.AbstractSchemaProvider; +import tech.pegasys.teku.spec.schemas.SchemaRegistry; +import tech.pegasys.teku.spec.schemas.SchemaTypes; + +public class BeaconBlockSchemaProvider extends AbstractSchemaProvider { + + public BeaconBlockSchemaProvider() { + super(SchemaTypes.BEACON_BLOCK_SCHEMA); + } + + @Override + protected BeaconBlockSchema createSchema( + final SchemaRegistry registry, + final SpecMilestone effectiveMilestone, + final SpecConfig specConfig) { + return new BeaconBlockSchema( + registry.get(BEACON_BLOCK_BODY_SCHEMA), + "BeaconBlock" + capitalizeMilestone(effectiveMilestone)); + } + + @Override + public Set getSupportedMilestones() { + return ALL_MILESTONES; + } +} diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/providers/BeaconBlocksByRootRequestMessageSchemaProvider.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/providers/BeaconBlocksByRootRequestMessageSchemaProvider.java new file mode 100644 index 00000000000..f8f0b08768c --- /dev/null +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/providers/BeaconBlocksByRootRequestMessageSchemaProvider.java @@ -0,0 +1,45 @@ +/* + * 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.providers; + +import static tech.pegasys.teku.spec.SpecMilestone.PHASE0; +import static tech.pegasys.teku.spec.schemas.SchemaTypes.BEACON_BLOCKS_BY_ROOT_REQUEST_MESSAGE_SCHEMA; + +import java.util.Set; +import tech.pegasys.teku.spec.SpecMilestone; +import tech.pegasys.teku.spec.config.SpecConfig; +import tech.pegasys.teku.spec.datastructures.networking.libp2p.rpc.BeaconBlocksByRootRequestMessage.BeaconBlocksByRootRequestMessageSchema; +import tech.pegasys.teku.spec.schemas.AbstractSchemaProvider; +import tech.pegasys.teku.spec.schemas.SchemaRegistry; + +public class BeaconBlocksByRootRequestMessageSchemaProvider + extends AbstractSchemaProvider { + public BeaconBlocksByRootRequestMessageSchemaProvider() { + super(BEACON_BLOCKS_BY_ROOT_REQUEST_MESSAGE_SCHEMA); + addMilestoneMapping(PHASE0, SpecMilestone.getHighestMilestone()); + } + + @Override + protected BeaconBlocksByRootRequestMessageSchema createSchema( + final SchemaRegistry registry, + final SpecMilestone effectiveMilestone, + final SpecConfig specConfig) { + return new BeaconBlocksByRootRequestMessageSchema(specConfig); + } + + @Override + public Set getSupportedMilestones() { + return ALL_MILESTONES; + } +} diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/providers/BeaconStateSchemaProvider.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/providers/BeaconStateSchemaProvider.java new file mode 100644 index 00000000000..091400c3a0e --- /dev/null +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/providers/BeaconStateSchemaProvider.java @@ -0,0 +1,59 @@ +/* + * 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.providers; + +import java.util.Set; +import tech.pegasys.teku.spec.SpecMilestone; +import tech.pegasys.teku.spec.config.SpecConfig; +import tech.pegasys.teku.spec.datastructures.state.beaconstate.BeaconState; +import tech.pegasys.teku.spec.datastructures.state.beaconstate.BeaconStateSchema; +import tech.pegasys.teku.spec.datastructures.state.beaconstate.MutableBeaconState; +import tech.pegasys.teku.spec.datastructures.state.beaconstate.versions.altair.BeaconStateSchemaAltair; +import tech.pegasys.teku.spec.datastructures.state.beaconstate.versions.bellatrix.BeaconStateSchemaBellatrix; +import tech.pegasys.teku.spec.datastructures.state.beaconstate.versions.capella.BeaconStateSchemaCapella; +import tech.pegasys.teku.spec.datastructures.state.beaconstate.versions.deneb.BeaconStateSchemaDeneb; +import tech.pegasys.teku.spec.datastructures.state.beaconstate.versions.electra.BeaconStateSchemaElectra; +import tech.pegasys.teku.spec.datastructures.state.beaconstate.versions.phase0.BeaconStateSchemaPhase0; +import tech.pegasys.teku.spec.schemas.AbstractSchemaProvider; +import tech.pegasys.teku.spec.schemas.SchemaRegistry; +import tech.pegasys.teku.spec.schemas.SchemaTypes; + +public class BeaconStateSchemaProvider + extends AbstractSchemaProvider< + BeaconStateSchema> { + + public BeaconStateSchemaProvider() { + super(SchemaTypes.BEACON_STATE_SCHEMA); + } + + @Override + protected BeaconStateSchema createSchema( + final SchemaRegistry registry, + final SpecMilestone effectiveMilestone, + final SpecConfig specConfig) { + return switch (effectiveMilestone) { + case PHASE0 -> BeaconStateSchemaPhase0.create(specConfig); + case ALTAIR -> BeaconStateSchemaAltair.create(specConfig); + case BELLATRIX -> BeaconStateSchemaBellatrix.create(specConfig); + case CAPELLA -> BeaconStateSchemaCapella.create(specConfig); + case DENEB -> BeaconStateSchemaDeneb.create(specConfig); + case ELECTRA -> BeaconStateSchemaElectra.create(specConfig); + }; + } + + @Override + public Set getSupportedMilestones() { + return ALL_MILESTONES; + } +} diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/providers/BlindedBeaconBlockBodySchemaProvider.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/providers/BlindedBeaconBlockBodySchemaProvider.java new file mode 100644 index 00000000000..cb52f45b06c --- /dev/null +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/providers/BlindedBeaconBlockBodySchemaProvider.java @@ -0,0 +1,70 @@ +/* + * 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.providers; + +import static tech.pegasys.teku.spec.schemas.SchemaTypes.BLINDED_BEACON_BLOCK_BODY_SCHEMA; + +import java.util.Set; +import tech.pegasys.teku.spec.SpecMilestone; +import tech.pegasys.teku.spec.config.SpecConfig; +import tech.pegasys.teku.spec.config.SpecConfigBellatrix; +import tech.pegasys.teku.spec.config.SpecConfigCapella; +import tech.pegasys.teku.spec.config.SpecConfigDeneb; +import tech.pegasys.teku.spec.config.SpecConfigElectra; +import tech.pegasys.teku.spec.datastructures.blocks.blockbody.versions.bellatrix.BlindedBeaconBlockBodySchemaBellatrix; +import tech.pegasys.teku.spec.datastructures.blocks.blockbody.versions.bellatrix.BlindedBeaconBlockBodySchemaBellatrixImpl; +import tech.pegasys.teku.spec.datastructures.blocks.blockbody.versions.capella.BlindedBeaconBlockBodySchemaCapellaImpl; +import tech.pegasys.teku.spec.datastructures.blocks.blockbody.versions.deneb.BlindedBeaconBlockBodySchemaDenebImpl; +import tech.pegasys.teku.spec.datastructures.blocks.blockbody.versions.electra.BlindedBeaconBlockBodySchemaElectraImpl; +import tech.pegasys.teku.spec.schemas.AbstractSchemaProvider; +import tech.pegasys.teku.spec.schemas.SchemaRegistry; + +public class BlindedBeaconBlockBodySchemaProvider + extends AbstractSchemaProvider> { + + public BlindedBeaconBlockBodySchemaProvider() { + super(BLINDED_BEACON_BLOCK_BODY_SCHEMA); + } + + @Override + protected BlindedBeaconBlockBodySchemaBellatrix createSchema( + final SchemaRegistry registry, + final SpecMilestone effectiveMilestone, + final SpecConfig specConfig) { + return switch (effectiveMilestone) { + case BELLATRIX -> + BlindedBeaconBlockBodySchemaBellatrixImpl.create( + SpecConfigBellatrix.required(registry.getSpecConfig()), + registry, + "BlindedBlockBodyBellatrix"); + + case CAPELLA -> + BlindedBeaconBlockBodySchemaCapellaImpl.create( + SpecConfigCapella.required(specConfig), registry, "BlindedBlockBodyCapella"); + case DENEB -> + BlindedBeaconBlockBodySchemaDenebImpl.create( + SpecConfigDeneb.required(specConfig), registry, "BlindedBlockBodyDeneb"); + + case ELECTRA -> + BlindedBeaconBlockBodySchemaElectraImpl.create( + SpecConfigElectra.required(specConfig), registry, "BlindedBlockBodyElectra"); + default -> throw new IllegalStateException(""); + }; + } + + @Override + public Set getSupportedMilestones() { + return FROM_BELLATRIX; + } +} diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/providers/BlindedBeaconBlockSchemaProvider.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/providers/BlindedBeaconBlockSchemaProvider.java new file mode 100644 index 00000000000..018b2cfb95d --- /dev/null +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/providers/BlindedBeaconBlockSchemaProvider.java @@ -0,0 +1,46 @@ +/* + * 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.providers; + +import static tech.pegasys.teku.spec.schemas.SchemaTypes.BLINDED_BEACON_BLOCK_BODY_SCHEMA; +import static tech.pegasys.teku.spec.schemas.SchemaTypes.BLINDED_BEACON_BLOCK_SCHEMA; + +import java.util.Set; +import tech.pegasys.teku.spec.SpecMilestone; +import tech.pegasys.teku.spec.config.SpecConfig; +import tech.pegasys.teku.spec.datastructures.blocks.BeaconBlockSchema; +import tech.pegasys.teku.spec.schemas.AbstractSchemaProvider; +import tech.pegasys.teku.spec.schemas.SchemaRegistry; + +public class BlindedBeaconBlockSchemaProvider extends AbstractSchemaProvider { + + public BlindedBeaconBlockSchemaProvider() { + super(BLINDED_BEACON_BLOCK_SCHEMA); + } + + @Override + protected BeaconBlockSchema createSchema( + final SchemaRegistry registry, + final SpecMilestone effectiveMilestone, + final SpecConfig specConfig) { + return new BeaconBlockSchema( + registry.get(BLINDED_BEACON_BLOCK_BODY_SCHEMA), + "BlindedBlock" + capitalizeMilestone(effectiveMilestone)); + } + + @Override + public Set getSupportedMilestones() { + return FROM_BELLATRIX; + } +} diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/providers/BlobKzgCommitmentsSchemaProvider.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/providers/BlobKzgCommitmentsSchemaProvider.java new file mode 100644 index 00000000000..b182d628c18 --- /dev/null +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/providers/BlobKzgCommitmentsSchemaProvider.java @@ -0,0 +1,45 @@ +/* + * 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.providers; + +import static tech.pegasys.teku.spec.schemas.SchemaTypes.BLOB_KZG_COMMITMENTS_SCHEMA; + +import java.util.Set; +import tech.pegasys.teku.spec.SpecMilestone; +import tech.pegasys.teku.spec.config.SpecConfig; +import tech.pegasys.teku.spec.config.SpecConfigDeneb; +import tech.pegasys.teku.spec.datastructures.blobs.versions.deneb.BlobKzgCommitmentsSchema; +import tech.pegasys.teku.spec.schemas.AbstractSchemaProvider; +import tech.pegasys.teku.spec.schemas.SchemaRegistry; + +public class BlobKzgCommitmentsSchemaProvider + extends AbstractSchemaProvider { + + public BlobKzgCommitmentsSchemaProvider() { + super(BLOB_KZG_COMMITMENTS_SCHEMA); + } + + @Override + protected BlobKzgCommitmentsSchema createSchema( + final SchemaRegistry registry, + final SpecMilestone effectiveMilestone, + final SpecConfig specConfig) { + return new BlobKzgCommitmentsSchema(SpecConfigDeneb.required(specConfig)); + } + + @Override + public Set getSupportedMilestones() { + return FROM_DENEB; + } +} diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/providers/BlsToExecutionChangeSchemaProvider.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/providers/BlsToExecutionChangeSchemaProvider.java new file mode 100644 index 00000000000..924eb4e1143 --- /dev/null +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/providers/BlsToExecutionChangeSchemaProvider.java @@ -0,0 +1,46 @@ +/* + * 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.providers; + +import static tech.pegasys.teku.spec.SpecMilestone.CAPELLA; +import static tech.pegasys.teku.spec.schemas.SchemaTypes.BLS_TO_EXECUTION_CHANGE_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.BlsToExecutionChangeSchema; +import tech.pegasys.teku.spec.schemas.AbstractSchemaProvider; +import tech.pegasys.teku.spec.schemas.SchemaRegistry; + +public class BlsToExecutionChangeSchemaProvider + extends AbstractSchemaProvider { + + public BlsToExecutionChangeSchemaProvider() { + super(BLS_TO_EXECUTION_CHANGE_SCHEMA); + addMilestoneMapping(CAPELLA, SpecMilestone.getHighestMilestone()); + } + + @Override + protected BlsToExecutionChangeSchema createSchema( + final SchemaRegistry registry, + final SpecMilestone effectiveMilestone, + final SpecConfig specConfig) { + return new BlsToExecutionChangeSchema(); + } + + @Override + public Set getSupportedMilestones() { + return FROM_CAPELLA; + } +} diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/providers/ExecutionPayloadHeaderSchemaProvider.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/providers/ExecutionPayloadHeaderSchemaProvider.java new file mode 100644 index 00000000000..a8eda59bb0c --- /dev/null +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/providers/ExecutionPayloadHeaderSchemaProvider.java @@ -0,0 +1,64 @@ +/* + * 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.providers; + +import static tech.pegasys.teku.spec.schemas.SchemaTypes.BEACON_STATE_SCHEMA; +import static tech.pegasys.teku.spec.schemas.SchemaTypes.EXECUTION_PAYLOAD_HEADER_SCHEMA; + +import java.util.Set; +import tech.pegasys.teku.spec.SpecMilestone; +import tech.pegasys.teku.spec.config.SpecConfig; +import tech.pegasys.teku.spec.datastructures.execution.ExecutionPayloadHeader; +import tech.pegasys.teku.spec.datastructures.execution.ExecutionPayloadHeaderSchema; +import tech.pegasys.teku.spec.datastructures.state.beaconstate.versions.bellatrix.BeaconStateSchemaBellatrix; +import tech.pegasys.teku.spec.datastructures.state.beaconstate.versions.capella.BeaconStateSchemaCapella; +import tech.pegasys.teku.spec.datastructures.state.beaconstate.versions.deneb.BeaconStateSchemaDeneb; +import tech.pegasys.teku.spec.datastructures.state.beaconstate.versions.electra.BeaconStateSchemaElectra; +import tech.pegasys.teku.spec.schemas.AbstractSchemaProvider; +import tech.pegasys.teku.spec.schemas.SchemaRegistry; + +public class ExecutionPayloadHeaderSchemaProvider + extends AbstractSchemaProvider> { + + public ExecutionPayloadHeaderSchemaProvider() { + super(EXECUTION_PAYLOAD_HEADER_SCHEMA); + } + + @Override + protected ExecutionPayloadHeaderSchema createSchema( + final SchemaRegistry registry, + final SpecMilestone effectiveMilestone, + final SpecConfig specConfig) { + return switch (effectiveMilestone) { + case BELLATRIX -> + BeaconStateSchemaBellatrix.required(registry.get(BEACON_STATE_SCHEMA)) + .getLastExecutionPayloadHeaderSchema(); + case CAPELLA -> + BeaconStateSchemaCapella.required(registry.get(BEACON_STATE_SCHEMA)) + .getLastExecutionPayloadHeaderSchema(); + case DENEB -> + BeaconStateSchemaDeneb.required(registry.get(BEACON_STATE_SCHEMA)) + .getLastExecutionPayloadHeaderSchema(); + case ELECTRA -> + BeaconStateSchemaElectra.required(registry.get(BEACON_STATE_SCHEMA)) + .getLastExecutionPayloadHeaderSchema(); + default -> throw new IllegalStateException("Unsupported milestone: " + effectiveMilestone); + }; + } + + @Override + public Set getSupportedMilestones() { + return FROM_BELLATRIX; + } +} diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/providers/ExecutionPayloadSchemaProvider.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/providers/ExecutionPayloadSchemaProvider.java new file mode 100644 index 00000000000..ed616c1b21f --- /dev/null +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/providers/ExecutionPayloadSchemaProvider.java @@ -0,0 +1,64 @@ +/* + * 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.providers; + +import static tech.pegasys.teku.spec.SpecMilestone.BELLATRIX; +import static tech.pegasys.teku.spec.SpecMilestone.CAPELLA; +import static tech.pegasys.teku.spec.SpecMilestone.DENEB; +import static tech.pegasys.teku.spec.SpecMilestone.ELECTRA; +import static tech.pegasys.teku.spec.schemas.SchemaTypes.EXECUTION_PAYLOAD_SCHEMA; + +import java.util.Set; +import tech.pegasys.teku.spec.SpecMilestone; +import tech.pegasys.teku.spec.config.SpecConfig; +import tech.pegasys.teku.spec.config.SpecConfigBellatrix; +import tech.pegasys.teku.spec.config.SpecConfigCapella; +import tech.pegasys.teku.spec.config.SpecConfigDeneb; +import tech.pegasys.teku.spec.config.SpecConfigElectra; +import tech.pegasys.teku.spec.datastructures.execution.ExecutionPayload; +import tech.pegasys.teku.spec.datastructures.execution.ExecutionPayloadSchema; +import tech.pegasys.teku.spec.datastructures.execution.versions.bellatrix.ExecutionPayloadSchemaBellatrix; +import tech.pegasys.teku.spec.datastructures.execution.versions.capella.ExecutionPayloadSchemaCapella; +import tech.pegasys.teku.spec.datastructures.execution.versions.deneb.ExecutionPayloadSchemaDeneb; +import tech.pegasys.teku.spec.datastructures.execution.versions.electra.ExecutionPayloadSchemaElectra; +import tech.pegasys.teku.spec.schemas.AbstractSchemaProvider; +import tech.pegasys.teku.spec.schemas.SchemaRegistry; + +public class ExecutionPayloadSchemaProvider + extends AbstractSchemaProvider> { + + public ExecutionPayloadSchemaProvider() { + super(EXECUTION_PAYLOAD_SCHEMA); + } + + @Override + protected ExecutionPayloadSchema createSchema( + final SchemaRegistry registry, + final SpecMilestone effectiveMilestone, + final SpecConfig specConfig) { + return switch (effectiveMilestone) { + case BELLATRIX -> + new ExecutionPayloadSchemaBellatrix(SpecConfigBellatrix.required(specConfig)); + case CAPELLA -> new ExecutionPayloadSchemaCapella(SpecConfigCapella.required(specConfig)); + case DENEB -> new ExecutionPayloadSchemaDeneb(SpecConfigDeneb.required(specConfig)); + case ELECTRA -> new ExecutionPayloadSchemaElectra(SpecConfigElectra.required(specConfig)); + default -> throw new IllegalStateException(""); + }; + } + + @Override + public Set getSupportedMilestones() { + return FROM_BELLATRIX; + } +} diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/providers/HistoricalBatchSchemaProvider.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/providers/HistoricalBatchSchemaProvider.java new file mode 100644 index 00000000000..7e840152af0 --- /dev/null +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/providers/HistoricalBatchSchemaProvider.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.providers; + +import static tech.pegasys.teku.spec.SpecMilestone.PHASE0; +import static tech.pegasys.teku.spec.schemas.SchemaTypes.HISTORICAL_BATCH_SCHEMA; + +import java.util.Set; +import tech.pegasys.teku.spec.SpecMilestone; +import tech.pegasys.teku.spec.config.SpecConfig; +import tech.pegasys.teku.spec.datastructures.state.HistoricalBatch.HistoricalBatchSchema; +import tech.pegasys.teku.spec.schemas.AbstractSchemaProvider; +import tech.pegasys.teku.spec.schemas.SchemaRegistry; + +public class HistoricalBatchSchemaProvider extends AbstractSchemaProvider { + public HistoricalBatchSchemaProvider() { + super(HISTORICAL_BATCH_SCHEMA); + addMilestoneMapping(PHASE0, SpecMilestone.getHighestMilestone()); + } + + @Override + protected HistoricalBatchSchema createSchema( + final SchemaRegistry registry, + final SpecMilestone effectiveMilestone, + final SpecConfig specConfig) { + return new HistoricalBatchSchema(specConfig.getSlotsPerHistoricalRoot()); + } + + @Override + public Set getSupportedMilestones() { + return ALL_MILESTONES; + } +} diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/providers/IndexedAttestationSchemaProvider.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/providers/IndexedAttestationSchemaProvider.java new file mode 100644 index 00000000000..4201cd9fda4 --- /dev/null +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/providers/IndexedAttestationSchemaProvider.java @@ -0,0 +1,62 @@ +/* + * 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.providers; + +import static tech.pegasys.teku.spec.SpecMilestone.DENEB; +import static tech.pegasys.teku.spec.SpecMilestone.PHASE0; + +import java.util.Set; +import tech.pegasys.teku.spec.SpecMilestone; +import tech.pegasys.teku.spec.config.SpecConfig; +import tech.pegasys.teku.spec.datastructures.operations.IndexedAttestation; +import tech.pegasys.teku.spec.datastructures.operations.IndexedAttestationSchema; +import tech.pegasys.teku.spec.datastructures.operations.versions.electra.IndexedAttestationElectraSchema; +import tech.pegasys.teku.spec.datastructures.operations.versions.phase0.IndexedAttestationPhase0Schema; +import tech.pegasys.teku.spec.schemas.AbstractSchemaProvider; +import tech.pegasys.teku.spec.schemas.SchemaRegistry; +import tech.pegasys.teku.spec.schemas.SchemaTypes; + +public class IndexedAttestationSchemaProvider + extends AbstractSchemaProvider> { + + public IndexedAttestationSchemaProvider() { + super(SchemaTypes.INDEXED_ATTESTATION_SCHEMA); + addMilestoneMapping(PHASE0, DENEB); + } + + @Override + protected IndexedAttestationSchema createSchema( + final SchemaRegistry registry, + final SpecMilestone effectiveMilestone, + final SpecConfig specConfig) { + return switch (effectiveMilestone) { + case PHASE0 -> + new IndexedAttestationPhase0Schema(specConfig.getMaxValidatorsPerCommittee()) + .castTypeToIndexedAttestationSchema(); + case ELECTRA -> + new IndexedAttestationElectraSchema( + (long) specConfig.getMaxValidatorsPerCommittee() + * specConfig.getMaxCommitteesPerSlot()) + .castTypeToIndexedAttestationSchema(); + 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/providers/MetadataMessageSchemaProvider.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/providers/MetadataMessageSchemaProvider.java new file mode 100644 index 00000000000..1e0ffb68333 --- /dev/null +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/providers/MetadataMessageSchemaProvider.java @@ -0,0 +1,55 @@ +/* + * 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.providers; + +import static tech.pegasys.teku.spec.SpecMilestone.ALTAIR; + +import java.util.Set; +import tech.pegasys.teku.spec.SpecMilestone; +import tech.pegasys.teku.spec.config.SpecConfig; +import tech.pegasys.teku.spec.datastructures.networking.libp2p.rpc.metadata.MetadataMessage; +import tech.pegasys.teku.spec.datastructures.networking.libp2p.rpc.metadata.MetadataMessageSchema; +import tech.pegasys.teku.spec.datastructures.networking.libp2p.rpc.metadata.versions.altair.MetadataMessageSchemaAltair; +import tech.pegasys.teku.spec.datastructures.networking.libp2p.rpc.metadata.versions.phase0.MetadataMessageSchemaPhase0; +import tech.pegasys.teku.spec.schemas.AbstractSchemaProvider; +import tech.pegasys.teku.spec.schemas.SchemaRegistry; +import tech.pegasys.teku.spec.schemas.SchemaTypes; + +public class MetadataMessageSchemaProvider + extends AbstractSchemaProvider> { + + public MetadataMessageSchemaProvider() { + super(SchemaTypes.METADATA_MESSAGE_SCHEMA); + addMilestoneMapping(ALTAIR, SpecMilestone.getHighestMilestone()); + } + + @Override + protected MetadataMessageSchema createSchema( + final SchemaRegistry registry, + final SpecMilestone effectiveMilestone, + final SpecConfig specConfig) { + return switch (effectiveMilestone) { + case PHASE0 -> new MetadataMessageSchemaPhase0(specConfig.getNetworkingConfig()); + case ALTAIR -> new MetadataMessageSchemaAltair(specConfig.getNetworkingConfig()); + 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/providers/SignedAggregateAndProofSchemaProvider.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/providers/SignedAggregateAndProofSchemaProvider.java new file mode 100644 index 00000000000..7000230a67a --- /dev/null +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/providers/SignedAggregateAndProofSchemaProvider.java @@ -0,0 +1,45 @@ +/* + * 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.providers; + +import static tech.pegasys.teku.spec.schemas.SchemaTypes.AGGREGATE_AND_PROOF_SCHEMA; +import static tech.pegasys.teku.spec.schemas.SchemaTypes.SIGNED_AGGREGATE_AND_PROOF_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.SignedAggregateAndProof.SignedAggregateAndProofSchema; +import tech.pegasys.teku.spec.schemas.AbstractSchemaProvider; +import tech.pegasys.teku.spec.schemas.SchemaRegistry; + +public class SignedAggregateAndProofSchemaProvider + extends AbstractSchemaProvider { + + public SignedAggregateAndProofSchemaProvider() { + super(SIGNED_AGGREGATE_AND_PROOF_SCHEMA); + } + + @Override + protected SignedAggregateAndProofSchema createSchema( + final SchemaRegistry registry, + final SpecMilestone effectiveMilestone, + final SpecConfig specConfig) { + return new SignedAggregateAndProofSchema(registry.get(AGGREGATE_AND_PROOF_SCHEMA)); + } + + @Override + public Set getSupportedMilestones() { + return ALL_MILESTONES; + } +} diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/providers/SignedBeaconBlockSchemaProvider.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/providers/SignedBeaconBlockSchemaProvider.java new file mode 100644 index 00000000000..a3a79e74340 --- /dev/null +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/providers/SignedBeaconBlockSchemaProvider.java @@ -0,0 +1,47 @@ +/* + * 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.providers; + +import static tech.pegasys.teku.spec.schemas.SchemaTypes.BEACON_BLOCK_SCHEMA; +import static tech.pegasys.teku.spec.schemas.SchemaTypes.SIGNED_BEACON_BLOCK_SCHEMA; + +import java.util.Set; +import tech.pegasys.teku.spec.SpecMilestone; +import tech.pegasys.teku.spec.config.SpecConfig; +import tech.pegasys.teku.spec.datastructures.blocks.SignedBeaconBlockSchema; +import tech.pegasys.teku.spec.schemas.AbstractSchemaProvider; +import tech.pegasys.teku.spec.schemas.SchemaRegistry; + +public class SignedBeaconBlockSchemaProvider + extends AbstractSchemaProvider { + + public SignedBeaconBlockSchemaProvider() { + super(SIGNED_BEACON_BLOCK_SCHEMA); + } + + @Override + protected SignedBeaconBlockSchema createSchema( + final SchemaRegistry registry, + final SpecMilestone effectiveMilestone, + final SpecConfig specConfig) { + return new SignedBeaconBlockSchema( + registry.get(BEACON_BLOCK_SCHEMA), + "SignedBeaconBlock" + capitalizeMilestone(effectiveMilestone)); + } + + @Override + public Set getSupportedMilestones() { + return ALL_MILESTONES; + } +} diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/providers/SignedBlindedBeaconBlockSchemaProvider.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/providers/SignedBlindedBeaconBlockSchemaProvider.java new file mode 100644 index 00000000000..75a577fd3c1 --- /dev/null +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/providers/SignedBlindedBeaconBlockSchemaProvider.java @@ -0,0 +1,47 @@ +/* + * 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.providers; + +import static tech.pegasys.teku.spec.schemas.SchemaTypes.BLINDED_BEACON_BLOCK_SCHEMA; +import static tech.pegasys.teku.spec.schemas.SchemaTypes.SIGNED_BLINDED_BEACON_BLOCK_SCHEMA; + +import java.util.Set; +import tech.pegasys.teku.spec.SpecMilestone; +import tech.pegasys.teku.spec.config.SpecConfig; +import tech.pegasys.teku.spec.datastructures.blocks.SignedBeaconBlockSchema; +import tech.pegasys.teku.spec.schemas.AbstractSchemaProvider; +import tech.pegasys.teku.spec.schemas.SchemaRegistry; + +public class SignedBlindedBeaconBlockSchemaProvider + extends AbstractSchemaProvider { + + public SignedBlindedBeaconBlockSchemaProvider() { + super(SIGNED_BLINDED_BEACON_BLOCK_SCHEMA); + } + + @Override + protected SignedBeaconBlockSchema createSchema( + final SchemaRegistry registry, + final SpecMilestone effectiveMilestone, + final SpecConfig specConfig) { + return new SignedBeaconBlockSchema( + registry.get(BLINDED_BEACON_BLOCK_SCHEMA), + "SignedBlindedBlock" + capitalizeMilestone(effectiveMilestone)); + } + + @Override + public Set getSupportedMilestones() { + return FROM_BELLATRIX; + } +} diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/providers/SignedBlsToExecutionChangeSchemaProvider.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/providers/SignedBlsToExecutionChangeSchemaProvider.java new file mode 100644 index 00000000000..e7a00fa72df --- /dev/null +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/providers/SignedBlsToExecutionChangeSchemaProvider.java @@ -0,0 +1,46 @@ +/* + * 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.providers; + +import static tech.pegasys.teku.spec.SpecMilestone.CAPELLA; +import static tech.pegasys.teku.spec.schemas.SchemaTypes.SIGNED_BLS_TO_EXECUTION_CHANGE_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.SignedBlsToExecutionChangeSchema; +import tech.pegasys.teku.spec.schemas.AbstractSchemaProvider; +import tech.pegasys.teku.spec.schemas.SchemaRegistry; + +public class SignedBlsToExecutionChangeSchemaProvider + extends AbstractSchemaProvider { + + public SignedBlsToExecutionChangeSchemaProvider() { + super(SIGNED_BLS_TO_EXECUTION_CHANGE_SCHEMA); + addMilestoneMapping(CAPELLA, SpecMilestone.getHighestMilestone()); + } + + @Override + protected SignedBlsToExecutionChangeSchema createSchema( + final SchemaRegistry registry, + final SpecMilestone effectiveMilestone, + final SpecConfig specConfig) { + return new SignedBlsToExecutionChangeSchema(registry); + } + + @Override + public Set getSupportedMilestones() { + return FROM_CAPELLA; + } +} diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/providers/SimpleConstantSchemaProvider.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/providers/SimpleConstantSchemaProvider.java new file mode 100644 index 00000000000..1c1348c9b8d --- /dev/null +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/providers/SimpleConstantSchemaProvider.java @@ -0,0 +1,59 @@ +/* + * 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.providers; + +import static tech.pegasys.teku.spec.SpecMilestone.PHASE0; + +import java.util.HashSet; +import java.util.Set; +import java.util.function.Supplier; +import tech.pegasys.teku.spec.SpecMilestone; +import tech.pegasys.teku.spec.config.SpecConfig; +import tech.pegasys.teku.spec.schemas.AbstractSchemaProvider; +import tech.pegasys.teku.spec.schemas.SchemaRegistry; +import tech.pegasys.teku.spec.schemas.SchemaTypes.SchemaId; + +public class SimpleConstantSchemaProvider extends AbstractSchemaProvider { + private final Supplier schemaSupplier; + private final Set supportedMilestones; + + private SimpleConstantSchemaProvider( + final SchemaId schemaId, final SpecMilestone from, final Supplier schemaSupplier) { + super(schemaId); + this.schemaSupplier = schemaSupplier; + this.supportedMilestones = new HashSet<>(SpecMilestone.getAllMilestonesFrom(from)); + addMilestoneMapping(PHASE0, SpecMilestone.getHighestMilestone()); + } + + static SimpleConstantSchemaProvider create( + final SchemaId schemaId, final Supplier schemaSupplier) { + return new SimpleConstantSchemaProvider<>(schemaId, PHASE0, schemaSupplier); + } + + static SimpleConstantSchemaProvider createFrom( + final SchemaId schemaId, final SpecMilestone from, final Supplier schemaSupplier) { + return new SimpleConstantSchemaProvider<>(schemaId, from, schemaSupplier); + } + + @Override + protected T createSchema( + final SchemaRegistry registry, final SpecMilestone baseVersion, final SpecConfig specConfig) { + return schemaSupplier.get(); + } + + @Override + public Set getSupportedMilestones() { + return supportedMilestones; + } +} diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/providers/SyncnetsENRFieldSchemaProvider.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/providers/SyncnetsENRFieldSchemaProvider.java new file mode 100644 index 00000000000..d1b7223dc5b --- /dev/null +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/providers/SyncnetsENRFieldSchemaProvider.java @@ -0,0 +1,47 @@ +/* + * 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.providers; + +import static tech.pegasys.teku.spec.SpecMilestone.PHASE0; +import static tech.pegasys.teku.spec.schemas.SchemaTypes.SYNCNETS_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; +import tech.pegasys.teku.spec.constants.NetworkConstants; +import tech.pegasys.teku.spec.schemas.AbstractSchemaProvider; +import tech.pegasys.teku.spec.schemas.SchemaRegistry; + +public class SyncnetsENRFieldSchemaProvider + extends AbstractSchemaProvider> { + public SyncnetsENRFieldSchemaProvider() { + super(SYNCNETS_ENR_FIELD_SCHEMA); + addMilestoneMapping(PHASE0, SpecMilestone.getHighestMilestone()); + } + + @Override + protected SszBitvectorSchema createSchema( + final SchemaRegistry registry, + final SpecMilestone effectiveMilestone, + final SpecConfig specConfig) { + return SszBitvectorSchema.create(NetworkConstants.SYNC_COMMITTEE_SUBNET_COUNT); + } + + @Override + public Set getSupportedMilestones() { + return ALL_MILESTONES; + } +} diff --git a/ethereum/spec/src/test/java/tech/pegasys/teku/spec/ForkScheduleTest.java b/ethereum/spec/src/test/java/tech/pegasys/teku/spec/ForkScheduleTest.java index 76203ec6c0e..b0fd8a64430 100644 --- a/ethereum/spec/src/test/java/tech/pegasys/teku/spec/ForkScheduleTest.java +++ b/ethereum/spec/src/test/java/tech/pegasys/teku/spec/ForkScheduleTest.java @@ -25,6 +25,7 @@ import tech.pegasys.teku.spec.datastructures.state.Fork; import tech.pegasys.teku.spec.datastructures.util.ForkAndSpecMilestone; import tech.pegasys.teku.spec.networks.Eth2Network; +import tech.pegasys.teku.spec.schemas.SchemaRegistryBuilder; public class ForkScheduleTest { private static final SpecConfig MINIMAL_CONFIG = @@ -57,10 +58,12 @@ public class ForkScheduleTest { TRANSITION_CONFIG.toVersionAltair().orElseThrow().getAltairForkVersion(); static final Bytes4 UNKNOWN_FORK_VERSION = Bytes4.fromHexStringLenient("0xFFFFFFFF"); + static final SchemaRegistryBuilder SCHEMA_REGISTRY_BUILDER = SchemaRegistryBuilder.create(); + @Test public void build_validScheduleWithAltairTransition() { - final SpecVersion phase0 = SpecVersion.createPhase0(TRANSITION_CONFIG); - final SpecVersion altair = SpecVersion.createAltair(TRANSITION_CONFIG); + final SpecVersion phase0 = SpecVersion.createPhase0(TRANSITION_CONFIG, SCHEMA_REGISTRY_BUILDER); + final SpecVersion altair = SpecVersion.createAltair(TRANSITION_CONFIG, SCHEMA_REGISTRY_BUILDER); final ForkSchedule forkSchedule = ForkSchedule.builder().addNextMilestone(phase0).addNextMilestone(altair).build(); @@ -70,8 +73,8 @@ public void build_validScheduleWithAltairTransition() { @Test public void build_validScheduleWithAltairAtGenesis_phase0AndAltairSupplied() { - final SpecVersion phase0 = SpecVersion.createPhase0(ALTAIR_CONFIG); - final SpecVersion altair = SpecVersion.createAltair(ALTAIR_CONFIG); + final SpecVersion phase0 = SpecVersion.createPhase0(ALTAIR_CONFIG, SCHEMA_REGISTRY_BUILDER); + final SpecVersion altair = SpecVersion.createAltair(ALTAIR_CONFIG, SCHEMA_REGISTRY_BUILDER); final ForkSchedule forkSchedule = ForkSchedule.builder().addNextMilestone(phase0).addNextMilestone(altair).build(); @@ -82,7 +85,7 @@ public void build_validScheduleWithAltairAtGenesis_phase0AndAltairSupplied() { @Test public void build_validScheduleWithAltairAtGenesis_onlyAltairSupplied() { - final SpecVersion altair = SpecVersion.createAltair(ALTAIR_CONFIG); + final SpecVersion altair = SpecVersion.createAltair(ALTAIR_CONFIG, SCHEMA_REGISTRY_BUILDER); final ForkSchedule forkSchedule = ForkSchedule.builder().addNextMilestone(altair).build(); @@ -92,7 +95,7 @@ public void build_validScheduleWithAltairAtGenesis_onlyAltairSupplied() { @Test public void build_validPhase0Schedule() { - final SpecVersion phase0 = SpecVersion.createPhase0(PHASE0_CONFIG); + final SpecVersion phase0 = SpecVersion.createPhase0(PHASE0_CONFIG, SCHEMA_REGISTRY_BUILDER); final ForkSchedule forkSchedule = ForkSchedule.builder().addNextMilestone(phase0).build(); @@ -102,7 +105,7 @@ public void build_validPhase0Schedule() { @Test public void builder_milestonesSuppliedOutOfOrder_altairProcessedAtNonZeroSlot() { - final SpecVersion altair = SpecVersion.createAltair(TRANSITION_CONFIG); + final SpecVersion altair = SpecVersion.createAltair(TRANSITION_CONFIG, SCHEMA_REGISTRY_BUILDER); final ForkSchedule.Builder builder = ForkSchedule.builder(); assertThatThrownBy(() -> builder.addNextMilestone(altair)) @@ -112,8 +115,8 @@ public void builder_milestonesSuppliedOutOfOrder_altairProcessedAtNonZeroSlot() @Test public void builder_milestonesSuppliedOutOfOrder_processAltairBeforePhase0() { - final SpecVersion altair = SpecVersion.createAltair(ALTAIR_CONFIG); - final SpecVersion phase0 = SpecVersion.createPhase0(ALTAIR_CONFIG); + final SpecVersion altair = SpecVersion.createAltair(ALTAIR_CONFIG, SCHEMA_REGISTRY_BUILDER); + final SpecVersion phase0 = SpecVersion.createPhase0(ALTAIR_CONFIG, SCHEMA_REGISTRY_BUILDER); final ForkSchedule.Builder builder = ForkSchedule.builder(); builder.addNextMilestone(altair); @@ -132,7 +135,7 @@ public void getSupportedMilestones_withTransition() { @Test public void getSupportedMilestones_onlyAltairConfigured() { - final SpecVersion altair = SpecVersion.createAltair(ALTAIR_CONFIG); + final SpecVersion altair = SpecVersion.createAltair(ALTAIR_CONFIG, SCHEMA_REGISTRY_BUILDER); final ForkSchedule forkSchedule = ForkSchedule.builder().addNextMilestone(altair).build(); @@ -142,7 +145,7 @@ public void getSupportedMilestones_onlyAltairConfigured() { @Test public void getSupportedMilestones_onlyPhase0Configured() { - final SpecVersion phase0 = SpecVersion.createPhase0(PHASE0_CONFIG); + final SpecVersion phase0 = SpecVersion.createPhase0(PHASE0_CONFIG, SCHEMA_REGISTRY_BUILDER); final ForkSchedule forkSchedule = ForkSchedule.builder().addNextMilestone(phase0).build(); @@ -398,10 +401,11 @@ public void getGenesisFork_withTransition() { private ForkSchedule buildForkSchedule(final SpecConfig specConfig) { final ForkSchedule.Builder builder = ForkSchedule.builder(); - builder.addNextMilestone(SpecVersion.createPhase0(specConfig)); + builder.addNextMilestone(SpecVersion.createPhase0(specConfig, SCHEMA_REGISTRY_BUILDER)); specConfig .toVersionAltair() - .ifPresent(a -> builder.addNextMilestone(SpecVersion.createAltair(a))); + .ifPresent( + a -> builder.addNextMilestone(SpecVersion.createAltair(a, SCHEMA_REGISTRY_BUILDER))); return builder.build(); } diff --git a/ethereum/spec/src/test/java/tech/pegasys/teku/spec/SpecVersionTest.java b/ethereum/spec/src/test/java/tech/pegasys/teku/spec/SpecVersionTest.java index 1794982f102..9c13369a4d8 100644 --- a/ethereum/spec/src/test/java/tech/pegasys/teku/spec/SpecVersionTest.java +++ b/ethereum/spec/src/test/java/tech/pegasys/teku/spec/SpecVersionTest.java @@ -24,14 +24,17 @@ import tech.pegasys.teku.spec.config.SpecConfigElectra; import tech.pegasys.teku.spec.config.SpecConfigLoader; import tech.pegasys.teku.spec.networks.Eth2Network; +import tech.pegasys.teku.spec.schemas.SchemaRegistryBuilder; class SpecVersionTest { + private final SchemaRegistryBuilder schemaRegistryBuilder = SchemaRegistryBuilder.create(); private final SpecConfigAltair minimalConfig = SpecConfigAltair.required(SpecConfigLoader.loadConfig(Eth2Network.MINIMAL.configName())); @Test void shouldCreatePhase0Spec() { - final SpecVersion expectedVersion = SpecVersion.createPhase0(minimalConfig); + final SpecVersion expectedVersion = + SpecVersion.createPhase0(minimalConfig, schemaRegistryBuilder); final Optional actualVersion = SpecVersion.create(SpecMilestone.PHASE0, minimalConfig); assertThat(actualVersion).isPresent(); @@ -43,7 +46,8 @@ void shouldCreatePhase0Spec() { @Test void shouldCreateAltairSpec() { final SpecConfigAltair altairSpecConfig = SpecConfigAltair.required(minimalConfig); - final SpecVersion expectedVersion = SpecVersion.createAltair(altairSpecConfig); + final SpecVersion expectedVersion = + SpecVersion.createAltair(altairSpecConfig, schemaRegistryBuilder); final Optional actualVersion = SpecVersion.create(SpecMilestone.ALTAIR, minimalConfig); assertThat(actualVersion).isPresent(); @@ -55,7 +59,8 @@ void shouldCreateAltairSpec() { @Test void shouldCreateBellatrixSpec() { final SpecConfigBellatrix bellatrixSpecConfig = SpecConfigBellatrix.required(minimalConfig); - final SpecVersion expectedVersion = SpecVersion.createBellatrix(bellatrixSpecConfig); + final SpecVersion expectedVersion = + SpecVersion.createBellatrix(bellatrixSpecConfig, schemaRegistryBuilder); final Optional actualVersion = SpecVersion.create(SpecMilestone.BELLATRIX, minimalConfig); assertThat(actualVersion).isPresent(); @@ -67,7 +72,8 @@ void shouldCreateBellatrixSpec() { @Test void shouldCreateCapellaSpec() { final SpecConfigCapella capellaSpecConfig = SpecConfigCapella.required(minimalConfig); - final SpecVersion expectedVersion = SpecVersion.createCapella(capellaSpecConfig); + final SpecVersion expectedVersion = + SpecVersion.createCapella(capellaSpecConfig, schemaRegistryBuilder); final Optional actualVersion = SpecVersion.create(SpecMilestone.CAPELLA, minimalConfig); assertThat(actualVersion).isPresent(); @@ -79,7 +85,8 @@ void shouldCreateCapellaSpec() { @Test void shouldCreateDenebSpec() { final SpecConfigDeneb denebSpecConfig = SpecConfigDeneb.required(minimalConfig); - final SpecVersion expectedVersion = SpecVersion.createDeneb(denebSpecConfig); + final SpecVersion expectedVersion = + SpecVersion.createDeneb(denebSpecConfig, schemaRegistryBuilder); final Optional actualVersion = SpecVersion.create(SpecMilestone.DENEB, minimalConfig); assertThat(actualVersion).isPresent(); @@ -91,7 +98,8 @@ void shouldCreateDenebSpec() { @Test void shouldCreateElectraSpec() { final SpecConfigElectra electraSpecConfig = SpecConfigElectra.required(minimalConfig); - final SpecVersion expectedVersion = SpecVersion.createElectra(electraSpecConfig); + final SpecVersion expectedVersion = + SpecVersion.createElectra(electraSpecConfig, schemaRegistryBuilder); final Optional actualVersion = SpecVersion.create(SpecMilestone.ELECTRA, minimalConfig); assertThat(actualVersion).isPresent(); diff --git a/ethereum/spec/src/test/java/tech/pegasys/teku/spec/datastructures/blocks/blockbody/versions/phase0/BeaconBlockBodySchemaPhase0Test.java b/ethereum/spec/src/test/java/tech/pegasys/teku/spec/datastructures/blocks/blockbody/versions/phase0/BeaconBlockBodySchemaPhase0Test.java index fa23725f3a2..3b7256b1e8c 100644 --- a/ethereum/spec/src/test/java/tech/pegasys/teku/spec/datastructures/blocks/blockbody/versions/phase0/BeaconBlockBodySchemaPhase0Test.java +++ b/ethereum/spec/src/test/java/tech/pegasys/teku/spec/datastructures/blocks/blockbody/versions/phase0/BeaconBlockBodySchemaPhase0Test.java @@ -19,8 +19,6 @@ import tech.pegasys.teku.spec.Spec; import tech.pegasys.teku.spec.TestSpecFactory; import tech.pegasys.teku.spec.config.SpecConfig; -import tech.pegasys.teku.spec.datastructures.operations.IndexedAttestationSchema; -import tech.pegasys.teku.spec.datastructures.operations.versions.phase0.AttesterSlashingPhase0Schema; public class BeaconBlockBodySchemaPhase0Test { @@ -28,23 +26,15 @@ public class BeaconBlockBodySchemaPhase0Test { public void create_minimal() { final Spec spec = TestSpecFactory.createMinimalPhase0(); final SpecConfig specConfig = spec.getGenesisSpecConfig(); - final IndexedAttestationSchema indexAttestationSchemaA = - spec.getGenesisSchemaDefinitions().getIndexedAttestationSchema(); - final IndexedAttestationSchema indexAttestationSchemaB = - spec.getGenesisSchemaDefinitions().getIndexedAttestationSchema(); final BeaconBlockBodySchemaPhase0 specA = BeaconBlockBodySchemaPhase0.create( specConfig, - new AttesterSlashingPhase0Schema( - indexAttestationSchemaA.castTypeToIndexedAttestationSchema()), - specConfig.getMaxValidatorsPerCommittee(), + spec.getGenesisSchemaDefinitions().getSchemaRegistry(), "BeaconBlockBodyPhase0"); final BeaconBlockBodySchemaPhase0 specB = BeaconBlockBodySchemaPhase0.create( specConfig, - new AttesterSlashingPhase0Schema( - indexAttestationSchemaB.castTypeToIndexedAttestationSchema()), - specConfig.getMaxValidatorsPerCommittee(), + spec.getGenesisSchemaDefinitions().getSchemaRegistry(), "BeaconBlockBodyPhase0"); assertThat(specA).isEqualTo(specB); @@ -54,23 +44,15 @@ public void create_minimal() { public void create_mainnet() { final Spec spec = TestSpecFactory.createMainnetPhase0(); final SpecConfig specConfig = spec.getGenesisSpecConfig(); - final IndexedAttestationSchema indexAttestationSchemaA = - spec.getGenesisSchemaDefinitions().getIndexedAttestationSchema(); - final IndexedAttestationSchema indexAttestationSchemaB = - spec.getGenesisSchemaDefinitions().getIndexedAttestationSchema(); final BeaconBlockBodySchemaPhase0 specA = BeaconBlockBodySchemaPhase0.create( specConfig, - new AttesterSlashingPhase0Schema( - indexAttestationSchemaA.castTypeToIndexedAttestationSchema()), - specConfig.getMaxValidatorsPerCommittee(), + spec.getGenesisSchemaDefinitions().getSchemaRegistry(), "BeaconBlockBodyPhase0"); final BeaconBlockBodySchemaPhase0 specB = BeaconBlockBodySchemaPhase0.create( specConfig, - new AttesterSlashingPhase0Schema( - indexAttestationSchemaB.castTypeToIndexedAttestationSchema()), - specConfig.getMaxValidatorsPerCommittee(), + spec.getGenesisSchemaDefinitions().getSchemaRegistry(), "BeaconBlockBodyPhase0"); assertThat(specA).isEqualTo(specB); diff --git a/ethereum/spec/src/test/java/tech/pegasys/teku/spec/datastructures/operations/SignedBlsToExecutionChangeTest.java b/ethereum/spec/src/test/java/tech/pegasys/teku/spec/datastructures/operations/SignedBlsToExecutionChangeTest.java index cb79569fee2..fbff04d66fe 100644 --- a/ethereum/spec/src/test/java/tech/pegasys/teku/spec/datastructures/operations/SignedBlsToExecutionChangeTest.java +++ b/ethereum/spec/src/test/java/tech/pegasys/teku/spec/datastructures/operations/SignedBlsToExecutionChangeTest.java @@ -18,17 +18,22 @@ import org.apache.tuweni.bytes.Bytes; import org.junit.jupiter.api.Test; import tech.pegasys.teku.bls.BLSSignature; +import tech.pegasys.teku.spec.Spec; import tech.pegasys.teku.spec.SpecMilestone; import tech.pegasys.teku.spec.TestSpecFactory; import tech.pegasys.teku.spec.util.DataStructureUtil; class SignedBlsToExecutionChangeTest { - private final DataStructureUtil dataStructureUtil = - new DataStructureUtil(TestSpecFactory.createMinimal(SpecMilestone.CAPELLA)); + private final Spec spec = TestSpecFactory.createMinimal(SpecMilestone.CAPELLA); + + private final DataStructureUtil dataStructureUtil = new DataStructureUtil(spec); private final SignedBlsToExecutionChangeSchema signedBlsToExecutionChangeSchema = - new SignedBlsToExecutionChangeSchema(); + spec.getGenesisSchemaDefinitions() + .toVersionCapella() + .orElseThrow() + .getSignedBlsToExecutionChangeSchema(); private final BlsToExecutionChange message = dataStructureUtil.randomBlsToExecutionChange(); diff --git a/ethereum/spec/src/test/java/tech/pegasys/teku/spec/logic/versions/electra/helpers/BeaconStateAccessorsElectraTest.java b/ethereum/spec/src/test/java/tech/pegasys/teku/spec/logic/versions/electra/helpers/BeaconStateAccessorsElectraTest.java index 3a6eb21c073..2a00a816b9d 100644 --- a/ethereum/spec/src/test/java/tech/pegasys/teku/spec/logic/versions/electra/helpers/BeaconStateAccessorsElectraTest.java +++ b/ethereum/spec/src/test/java/tech/pegasys/teku/spec/logic/versions/electra/helpers/BeaconStateAccessorsElectraTest.java @@ -35,7 +35,7 @@ class BeaconStateAccessorsElectraTest { spy(SpecConfigElectra.required(spec.atSlot(UInt64.ZERO).getConfig())); private final PredicatesElectra predicatesElectra = new PredicatesElectra(specConfig); private final SchemaDefinitionsElectra schemaDefinitionsElectra = - new SchemaDefinitionsElectra(SpecConfigElectra.required(specConfig)); + spec.getGenesisSchemaDefinitions().toVersionElectra().orElseThrow(); private final MiscHelpersElectra miscHelpersElectra = new MiscHelpersElectra( SpecConfigElectra.required(specConfig), predicatesElectra, schemaDefinitionsElectra); diff --git a/ethereum/spec/src/test/java/tech/pegasys/teku/spec/schemas/BaseSchemaProviderTest.java b/ethereum/spec/src/test/java/tech/pegasys/teku/spec/schemas/BaseSchemaProviderTest.java new file mode 100644 index 00000000000..e77748827de --- /dev/null +++ b/ethereum/spec/src/test/java/tech/pegasys/teku/spec/schemas/BaseSchemaProviderTest.java @@ -0,0 +1,96 @@ +/* + * 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; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import static tech.pegasys.teku.spec.SpecMilestone.ALTAIR; +import static tech.pegasys.teku.spec.SpecMilestone.BELLATRIX; +import static tech.pegasys.teku.spec.SpecMilestone.CAPELLA; +import static tech.pegasys.teku.spec.SpecMilestone.PHASE0; + +import java.util.EnumSet; +import java.util.Set; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import tech.pegasys.teku.spec.SpecMilestone; +import tech.pegasys.teku.spec.config.SpecConfig; + +class BaseSchemaProviderTest { + + private TestSchemaProvider provider; + private SchemaRegistry mockRegistry; + + @BeforeEach + void setUp() { + provider = new TestSchemaProvider(); + mockRegistry = mock(SchemaRegistry.class); + } + + @Test + void shouldGetEffectiveMilestone() { + provider.addMilestoneMapping(PHASE0, ALTAIR); + assertEquals(PHASE0, provider.getEffectiveMilestone(PHASE0)); + assertEquals(PHASE0, provider.getEffectiveMilestone(ALTAIR)); + assertEquals(BELLATRIX, provider.getEffectiveMilestone(BELLATRIX)); + } + + @Test + void shouldGetSchema() { + when(mockRegistry.getMilestone()).thenReturn(PHASE0); + String result = provider.getSchema(mockRegistry); + assertEquals("TestSchema", result); + } + + @Test + void shouldGetNonOverlappingVersionMappings() { + provider.addMilestoneMapping(PHASE0, ALTAIR); + provider.addMilestoneMapping(BELLATRIX, CAPELLA); + + assertEquals(PHASE0, provider.getEffectiveMilestone(PHASE0)); + assertEquals(PHASE0, provider.getEffectiveMilestone(ALTAIR)); + assertEquals(BELLATRIX, provider.getEffectiveMilestone(BELLATRIX)); + assertEquals(BELLATRIX, provider.getEffectiveMilestone(CAPELLA)); + } + + @Test + void testOverlappingVersionMappingsThrowsException() { + provider.addMilestoneMapping(PHASE0, ALTAIR); + + assertThatThrownBy(() -> provider.addMilestoneMapping(ALTAIR, BELLATRIX)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("Milestone ALTAIR is already mapped to PHASE0"); + } + + private static class TestSchemaProvider extends AbstractSchemaProvider { + TestSchemaProvider() { + super(SchemaTypes.create("TestSchema")); + } + + @Override + protected String createSchema( + final SchemaRegistry registry, + final SpecMilestone baseVersion, + final SpecConfig specConfig) { + return "TestSchema"; + } + + @Override + public Set getSupportedMilestones() { + return EnumSet.allOf(SpecMilestone.class); + } + } +} diff --git a/ethereum/spec/src/test/java/tech/pegasys/teku/spec/schemas/SchemaDefinitionBuilderTest.java b/ethereum/spec/src/test/java/tech/pegasys/teku/spec/schemas/SchemaDefinitionBuilderTest.java new file mode 100644 index 00000000000..e05deb5a94f --- /dev/null +++ b/ethereum/spec/src/test/java/tech/pegasys/teku/spec/schemas/SchemaDefinitionBuilderTest.java @@ -0,0 +1,78 @@ +/* + * 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; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static tech.pegasys.teku.spec.SpecMilestone.ALTAIR; +import static tech.pegasys.teku.spec.SpecMilestone.PHASE0; + +import java.util.EnumSet; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import tech.pegasys.teku.spec.SpecMilestone; +import tech.pegasys.teku.spec.config.SpecConfig; +import tech.pegasys.teku.spec.schemas.SchemaTypes.SchemaId; + +public class SchemaDefinitionBuilderTest { + private final SpecConfig specConfig = mock(SpecConfig.class); + private final SchemaCache cache = spy(SchemaCache.createDefault()); + private final SchemaRegistryBuilder builder = new SchemaRegistryBuilder(cache); + private final SchemaId stringId = SchemaTypes.create("stringType"); + private final String stringSchema = "stringSchema"; + + @SuppressWarnings("unchecked") + private final SchemaProvider mockProvider = mock(SchemaProvider.class); + + private final EnumSet supportedMilestones = EnumSet.of(PHASE0, ALTAIR); + + @BeforeEach + void setUp() { + when(mockProvider.getSchemaId()).thenReturn(stringId); + when(mockProvider.getSchema(any())).thenReturn(stringSchema); + when(mockProvider.getSupportedMilestones()).thenReturn(supportedMilestones); + when(mockProvider.getEffectiveMilestone(any())).thenReturn(PHASE0); + } + + @Test + void shouldAddProviderForSupportedMilestone() { + + builder.addProvider(mockProvider); + + for (final SpecMilestone milestone : SpecMilestone.values()) { + final SchemaRegistry registry = builder.build(milestone, specConfig); + if (supportedMilestones.contains(milestone)) { + assertThat(registry.isProviderRegistered(mockProvider)).isTrue(); + } else { + assertThat(registry.isProviderRegistered(mockProvider)).isFalse(); + } + } + + verify(mockProvider, times(SpecMilestone.values().length)).getSupportedMilestones(); + } + + @Test + void shouldPrimeRegistry() { + builder.addProvider(mockProvider); + builder.build(ALTAIR, specConfig); + + // we should have it in cache immediately + verify(cache).put(ALTAIR, stringId, stringSchema); + } +} diff --git a/ethereum/spec/src/test/java/tech/pegasys/teku/spec/schemas/SchemaRegistryTest.java b/ethereum/spec/src/test/java/tech/pegasys/teku/spec/schemas/SchemaRegistryTest.java new file mode 100644 index 00000000000..325e1db2d39 --- /dev/null +++ b/ethereum/spec/src/test/java/tech/pegasys/teku/spec/schemas/SchemaRegistryTest.java @@ -0,0 +1,140 @@ +/* + * 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; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import org.junit.jupiter.api.Test; +import tech.pegasys.teku.spec.SpecMilestone; +import tech.pegasys.teku.spec.config.SpecConfig; +import tech.pegasys.teku.spec.schemas.SchemaTypes.SchemaId; + +public class SchemaRegistryTest { + + private final SpecConfig specConfig = mock(SpecConfig.class); + private final SchemaCache schemaCache = mock(SchemaCache.class); + + @SuppressWarnings("unchecked") + private final SchemaProvider schemaProvider = mock(SchemaProvider.class); + + @SuppressWarnings("unchecked") + private final SchemaId schemaId = mock(SchemaId.class); + + private final SchemaRegistry schemaRegistry = + new SchemaRegistry(SpecMilestone.ALTAIR, specConfig, schemaCache); + + @Test + void shouldGetSchemaFromCache() { + final String cachedSchema = "schema"; + when(schemaProvider.getSchemaId()).thenReturn(schemaId); + when(schemaCache.get(SpecMilestone.ALTAIR, schemaId)).thenReturn(cachedSchema); + + schemaRegistry.registerProvider(schemaProvider); + final String result = schemaRegistry.get(schemaId); + + assertEquals(cachedSchema, result); + verify(schemaCache).get(SpecMilestone.ALTAIR, schemaId); + verify(schemaProvider, never()).getSchema(any()); + } + + @Test + void shouldGetSchemaFromProvider() { + final String newSchema = "schema"; + when(schemaProvider.getSchemaId()).thenReturn(schemaId); + when(schemaCache.get(SpecMilestone.ALTAIR, schemaId)).thenReturn(null); + when(schemaProvider.getEffectiveMilestone(SpecMilestone.ALTAIR)) + .thenReturn(SpecMilestone.ALTAIR); + when(schemaProvider.getSchema(schemaRegistry)).thenReturn(newSchema); + + schemaRegistry.registerProvider(schemaProvider); + final String result = schemaRegistry.get(schemaId); + + assertEquals(newSchema, result); + verify(schemaCache).get(SpecMilestone.ALTAIR, schemaId); + verify(schemaProvider).getSchema(schemaRegistry); + verify(schemaCache).put(SpecMilestone.ALTAIR, schemaId, newSchema); + } + + @Test + void shouldCacheMilestoneAndEffectiveMilestoneFromProvider() { + final String newSchema = "schema"; + when(schemaProvider.getSchemaId()).thenReturn(schemaId); + when(schemaCache.get(SpecMilestone.PHASE0, schemaId)).thenReturn(null); + when(schemaCache.get(SpecMilestone.ALTAIR, schemaId)).thenReturn(null); + when(schemaProvider.getEffectiveMilestone(SpecMilestone.ALTAIR)) + .thenReturn(SpecMilestone.PHASE0); + when(schemaProvider.getSchema(schemaRegistry)).thenReturn(newSchema); + + schemaRegistry.registerProvider(schemaProvider); + final String result = schemaRegistry.get(schemaId); + + assertEquals(newSchema, result); + verify(schemaCache).get(SpecMilestone.PHASE0, schemaId); + verify(schemaCache).get(SpecMilestone.ALTAIR, schemaId); + verify(schemaProvider).getSchema(schemaRegistry); + verify(schemaCache).put(SpecMilestone.PHASE0, schemaId, newSchema); + verify(schemaCache).put(SpecMilestone.ALTAIR, schemaId, newSchema); + } + + @Test + void shouldGetFromCachedOfEffectiveMilestone() { + final String newSchema = "schema"; + when(schemaProvider.getSchemaId()).thenReturn(schemaId); + when(schemaCache.get(SpecMilestone.ALTAIR, schemaId)).thenReturn(null); + when(schemaCache.get(SpecMilestone.PHASE0, schemaId)).thenReturn(newSchema); + when(schemaProvider.getEffectiveMilestone(SpecMilestone.ALTAIR)) + .thenReturn(SpecMilestone.PHASE0); + when(schemaProvider.getSchema(schemaRegistry)).thenReturn(newSchema); + + schemaRegistry.registerProvider(schemaProvider); + final String result = schemaRegistry.get(schemaId); + + assertEquals(newSchema, result); + verify(schemaCache).put(SpecMilestone.ALTAIR, schemaId, newSchema); + verify(schemaProvider).getEffectiveMilestone(SpecMilestone.ALTAIR); + + verify(schemaProvider, never()).getSchema(schemaRegistry); + } + + @Test + void shouldThrowExceptionWhenGettingSchemaForUnregisteredProvider() { + assertThrows(IllegalArgumentException.class, () -> schemaRegistry.get(schemaId)); + } + + @Test + @SuppressWarnings("unchecked") + void shouldPrimeRegistry() { + final SchemaProvider provider1 = mock(SchemaProvider.class); + final SchemaProvider provider2 = mock(SchemaProvider.class); + final SchemaId id1 = mock(SchemaId.class); + final SchemaId id2 = mock(SchemaId.class); + + when(provider1.getSchemaId()).thenReturn(id1); + when(provider2.getSchemaId()).thenReturn(id2); + + schemaRegistry.registerProvider(provider1); + schemaRegistry.registerProvider(provider2); + + schemaRegistry.primeRegistry(); + + verify(provider1).getSchema(schemaRegistry); + verify(provider2).getSchema(schemaRegistry); + } +} diff --git a/ethereum/spec/src/test/java/tech/pegasys/teku/spec/schemas/SchemaTypesTest.java b/ethereum/spec/src/test/java/tech/pegasys/teku/spec/schemas/SchemaTypesTest.java new file mode 100644 index 00000000000..097c11be6c8 --- /dev/null +++ b/ethereum/spec/src/test/java/tech/pegasys/teku/spec/schemas/SchemaTypesTest.java @@ -0,0 +1,49 @@ +/* + * 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; + +import static java.lang.reflect.Modifier.isFinal; +import static java.lang.reflect.Modifier.isStatic; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.lang.reflect.Field; +import org.junit.jupiter.api.Test; +import tech.pegasys.teku.spec.schemas.SchemaTypes.SchemaId; + +public class SchemaTypesTest { + + @Test + public void testStaticFieldNamesMatchCreateArguments() throws IllegalAccessException { + // Get all declared fields in the SchemaTypes class + final Field[] fields = SchemaTypes.class.getDeclaredFields(); + + for (final Field field : fields) { + // Ensure the field is static and final + if (isStatic(field.getModifiers()) && isFinal(field.getModifiers())) { + + // Get the field name + final String fieldName = field.getName(); + + // Get the value of the field + field.setAccessible(true); + if (field.get(null) instanceof SchemaId schemaId) { + assertEquals( + fieldName, + schemaId.getName(), + "Field name does not match the create argument for field: " + fieldName); + } + } + } + } +} diff --git a/ethereum/spec/src/test/java/tech/pegasys/teku/spec/schemas/SimpleType.java b/ethereum/spec/src/test/java/tech/pegasys/teku/spec/schemas/SimpleType.java new file mode 100644 index 00000000000..6b3f29511c0 --- /dev/null +++ b/ethereum/spec/src/test/java/tech/pegasys/teku/spec/schemas/SimpleType.java @@ -0,0 +1,24 @@ +/* + * 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.spec.schemas; + +import tech.pegasys.teku.infrastructure.ssz.SszContainer; +import tech.pegasys.teku.infrastructure.ssz.primitive.SszUInt64; + +public interface SimpleType extends SszContainer { + + SszUInt64 getField1(); + + // Attestation getAttestation(); +} diff --git a/ethereum/spec/src/test/java/tech/pegasys/teku/spec/schemas/SimpleTypeSchema.java b/ethereum/spec/src/test/java/tech/pegasys/teku/spec/schemas/SimpleTypeSchema.java new file mode 100644 index 00000000000..ee9c4bc9e32 --- /dev/null +++ b/ethereum/spec/src/test/java/tech/pegasys/teku/spec/schemas/SimpleTypeSchema.java @@ -0,0 +1,27 @@ +/* + * 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.spec.schemas; + +import tech.pegasys.teku.infrastructure.ssz.primitive.SszUInt64; +import tech.pegasys.teku.infrastructure.ssz.schema.SszPrimitiveSchema; +import tech.pegasys.teku.infrastructure.ssz.schema.SszSchema; +import tech.pegasys.teku.infrastructure.unsigned.UInt64; + +public interface SimpleTypeSchema extends SszSchema { + SimpleType create(SszUInt64 field1 /*, Attestation attestation*/); + + SszPrimitiveSchema getField1Schema(); + + // AttestationSchema getAttestationSchema(); +} diff --git a/ethereum/spec/src/test/java/tech/pegasys/teku/spec/schemas/SszTypeGeneratorTest.java b/ethereum/spec/src/test/java/tech/pegasys/teku/spec/schemas/SszTypeGeneratorTest.java new file mode 100644 index 00000000000..62854e0a2f9 --- /dev/null +++ b/ethereum/spec/src/test/java/tech/pegasys/teku/spec/schemas/SszTypeGeneratorTest.java @@ -0,0 +1,52 @@ +/* + * 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.spec.schemas; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.jupiter.api.Test; +import tech.pegasys.teku.infrastructure.ssz.SszTypeGenerator; +import tech.pegasys.teku.infrastructure.ssz.primitive.SszUInt64; +import tech.pegasys.teku.infrastructure.ssz.schema.SszPrimitiveSchemas; +import tech.pegasys.teku.infrastructure.ssz.schema.impl.AbstractSszContainerSchema.NamedSchema; + +class SszTypeGeneratorTest { + + @Test + void shouldDefineASimpleType() throws Exception { + + // var spec = TestSpecFactory.createMinimalPhase0(); + // var dataStructureUtil = new DataStructureUtil(spec); + + // var attSchema = spec.getGenesisSchemaDefinitions().getAttestationSchema(); + + final SszTypeGenerator sszTypeGenerator = + new SszTypeGenerator<>( + SimpleType.class, + SimpleTypeSchema.class, + NamedSchema.of("field1", SszPrimitiveSchemas.UINT64_SCHEMA, SszUInt64.class) + // NamedSchema.of("attestation", attSchema, Attestation.class) + ); + final SimpleTypeSchema schema = sszTypeGenerator.defineType(); + assertThat(schema.getField1Schema()).isSameAs(SszPrimitiveSchemas.UINT64_SCHEMA); + // assertThat(schema.getAttestationSchema()).isSameAs(attSchema); + + // var attestation = dataStructureUtil.randomAttestation(); + final SimpleType simpleType = schema.create(SszUInt64.ZERO /*, attestation*/); + schema.createFromBackingNode(null); + assertThat(simpleType).isInstanceOf(SimpleType.class); + assertThat(simpleType.getField1()).isEqualTo(SszUInt64.ZERO); + // assertThat(simpleType.getAttestation()).isEqualTo(attestation); + } +} diff --git a/ethereum/spec/src/testFixtures/java/tech/pegasys/teku/spec/generator/AttestationGenerator.java b/ethereum/spec/src/testFixtures/java/tech/pegasys/teku/spec/generator/AttestationGenerator.java index f321b64040c..ed939a1fa8b 100644 --- a/ethereum/spec/src/testFixtures/java/tech/pegasys/teku/spec/generator/AttestationGenerator.java +++ b/ethereum/spec/src/testFixtures/java/tech/pegasys/teku/spec/generator/AttestationGenerator.java @@ -111,7 +111,7 @@ private static Attestation aggregateAttestations(final List srcAtte targetBitlist, srcAttestations.get(0).getData(), targetSig, - () -> srcAttestations.get(0).getCommitteeBitsRequired()); + () -> srcAttestations.get(0).getCommitteeBits()); } public Attestation validAttestation(final StateAndBlockSummary blockAndState) { @@ -432,7 +432,7 @@ private Supplier getCommitteeBitsSupplier( final AttestationSchema attestationSchema, final UInt64 committeeIndex) { return () -> attestationSchema - .getCommitteeBitsSchema() + .getCommitteeBitsSchemaOptional() .orElseThrow() .ofBits(committeeIndex.intValue()); } diff --git a/ethereum/statetransition/src/main/java/tech/pegasys/teku/statetransition/attestation/MatchingDataAttestationGroup.java b/ethereum/statetransition/src/main/java/tech/pegasys/teku/statetransition/attestation/MatchingDataAttestationGroup.java index 27303e656bd..0b03566d435 100644 --- a/ethereum/statetransition/src/main/java/tech/pegasys/teku/statetransition/attestation/MatchingDataAttestationGroup.java +++ b/ethereum/statetransition/src/main/java/tech/pegasys/teku/statetransition/attestation/MatchingDataAttestationGroup.java @@ -295,7 +295,7 @@ If we have attestations with committeeBits (Electra) then, if maybeCommitteeInde */ private boolean maybeFilterOnCommitteeIndex(final ValidatableAttestation candidate) { final Optional maybeCommitteeBits = - candidate.getAttestation().getCommitteeBits(); + candidate.getAttestation().getCommitteeBitsOptional(); if (maybeCommitteeBits.isEmpty() || maybeCommitteeIndex.isEmpty()) { return true; } diff --git a/ethereum/statetransition/src/main/java/tech/pegasys/teku/statetransition/attestation/utils/AttestationBitsAggregator.java b/ethereum/statetransition/src/main/java/tech/pegasys/teku/statetransition/attestation/utils/AttestationBitsAggregator.java index 7dacd61a5fe..6f44a601bd3 100644 --- a/ethereum/statetransition/src/main/java/tech/pegasys/teku/statetransition/attestation/utils/AttestationBitsAggregator.java +++ b/ethereum/statetransition/src/main/java/tech/pegasys/teku/statetransition/attestation/utils/AttestationBitsAggregator.java @@ -37,7 +37,7 @@ static AttestationBitsAggregator fromEmptyFromAttestationSchema( static AttestationBitsAggregator of(final ValidatableAttestation attestation) { return attestation .getAttestation() - .getCommitteeBits() + .getCommitteeBitsOptional() .map( committeeBits -> (AttestationBitsAggregator) @@ -54,7 +54,7 @@ static AttestationBitsAggregator of(final ValidatableAttestation attestation) { static AttestationBitsAggregator of( final Attestation attestation, final Optional committeesSize) { return attestation - .getCommitteeBits() + .getCommitteeBitsOptional() .map( committeeBits -> new AttestationBitsAggregatorElectra( diff --git a/ethereum/statetransition/src/main/java/tech/pegasys/teku/statetransition/attestation/utils/AttestationBitsAggregatorElectra.java b/ethereum/statetransition/src/main/java/tech/pegasys/teku/statetransition/attestation/utils/AttestationBitsAggregatorElectra.java index 4242922ed8a..2c400673564 100644 --- a/ethereum/statetransition/src/main/java/tech/pegasys/teku/statetransition/attestation/utils/AttestationBitsAggregatorElectra.java +++ b/ethereum/statetransition/src/main/java/tech/pegasys/teku/statetransition/attestation/utils/AttestationBitsAggregatorElectra.java @@ -54,12 +54,12 @@ public void or(final AttestationBitsAggregator other) { @Override public boolean aggregateWith(final Attestation other) { - return or(other.getCommitteeBitsRequired(), other.getAggregationBits(), true); + return or(other.getCommitteeBits(), other.getAggregationBits(), true); } @Override public void or(final Attestation other) { - or(other.getCommitteeBitsRequired(), other.getAggregationBits(), false); + or(other.getCommitteeBits(), other.getAggregationBits(), false); } private static class CannotAggregateException extends RuntimeException {} @@ -185,17 +185,17 @@ private Int2IntMap calculateCommitteeStartingPositions(final SszBitvector commit @Override public boolean isSuperSetOf(final Attestation other) { - if (!committeeBits.isSuperSetOf(other.getCommitteeBitsRequired())) { + if (!committeeBits.isSuperSetOf(other.getCommitteeBits())) { return false; } - if (committeeBits.getBitCount() == other.getCommitteeBitsRequired().getBitCount()) { + if (committeeBits.getBitCount() == other.getCommitteeBits().getBitCount()) { // this committeeBits is a superset of the other, and bit count is the same, so they are the // same set and we can directly compare aggregation bits. return aggregationBits.isSuperSetOf(other.getAggregationBits()); } - final SszBitvector otherCommitteeBits = other.getCommitteeBitsRequired(); + final SszBitvector otherCommitteeBits = other.getCommitteeBits(); final Int2IntMap otherCommitteeBitsStartingPositions = calculateCommitteeStartingPositions(otherCommitteeBits); diff --git a/ethereum/statetransition/src/main/java/tech/pegasys/teku/statetransition/validation/AttestationValidator.java b/ethereum/statetransition/src/main/java/tech/pegasys/teku/statetransition/validation/AttestationValidator.java index f652f597585..9cb2b7beb60 100644 --- a/ethereum/statetransition/src/main/java/tech/pegasys/teku/statetransition/validation/AttestationValidator.java +++ b/ethereum/statetransition/src/main/java/tech/pegasys/teku/statetransition/validation/AttestationValidator.java @@ -121,7 +121,7 @@ SafeFuture singleOrAggregateAttestationChecks if (attestation.requiresCommitteeBits()) { // [REJECT] len(committee_indices) == 1, where committee_indices = // get_committee_indices(attestation) - if (attestation.getCommitteeBitsRequired().getBitCount() != 1) { + if (attestation.getCommitteeBits().getBitCount() != 1) { return SafeFuture.completedFuture( InternalValidationResultWithState.reject( "Rejecting attestation because committee bits count is not 1")); diff --git a/ethereum/statetransition/src/test/java/tech/pegasys/teku/statetransition/attestation/AggregatingAttestationPoolTest.java b/ethereum/statetransition/src/test/java/tech/pegasys/teku/statetransition/attestation/AggregatingAttestationPoolTest.java index 05d82c5c265..6f43c146050 100644 --- a/ethereum/statetransition/src/test/java/tech/pegasys/teku/statetransition/attestation/AggregatingAttestationPoolTest.java +++ b/ethereum/statetransition/src/test/java/tech/pegasys/teku/statetransition/attestation/AggregatingAttestationPoolTest.java @@ -659,7 +659,7 @@ private Attestation createAttestation( committeeBits = () -> attestationSchema - .getCommitteeBitsSchema() + .getCommitteeBitsSchemaOptional() .orElseThrow() .ofBits(committeeIndex.orElseThrow().intValue()); } else { diff --git a/ethereum/statetransition/src/test/java/tech/pegasys/teku/statetransition/attestation/MatchingDataAttestationGroupTest.java b/ethereum/statetransition/src/test/java/tech/pegasys/teku/statetransition/attestation/MatchingDataAttestationGroupTest.java index c19dd5af076..3581e281c12 100644 --- a/ethereum/statetransition/src/test/java/tech/pegasys/teku/statetransition/attestation/MatchingDataAttestationGroupTest.java +++ b/ethereum/statetransition/src/test/java/tech/pegasys/teku/statetransition/attestation/MatchingDataAttestationGroupTest.java @@ -359,7 +359,7 @@ private ValidatableAttestation createAttestation( committeeBits = () -> attestationSchema - .getCommitteeBitsSchema() + .getCommitteeBitsSchemaOptional() .orElseThrow() .ofBits(committeeIndex.orElse(0)); } else { diff --git a/ethereum/statetransition/src/test/java/tech/pegasys/teku/statetransition/attestation/utils/AttestationBitsAggregatorElectraTest.java b/ethereum/statetransition/src/test/java/tech/pegasys/teku/statetransition/attestation/utils/AttestationBitsAggregatorElectraTest.java index cd0a102dcb7..7cb7300b05c 100644 --- a/ethereum/statetransition/src/test/java/tech/pegasys/teku/statetransition/attestation/utils/AttestationBitsAggregatorElectraTest.java +++ b/ethereum/statetransition/src/test/java/tech/pegasys/teku/statetransition/attestation/utils/AttestationBitsAggregatorElectraTest.java @@ -387,8 +387,7 @@ void bigAggregation() { 000000000000001000000000000000000000000000000000001\ """); - assertThat(aggregator.getCommitteeBits()) - .isEqualTo(result.getAttestation().getCommitteeBitsRequired()); + assertThat(aggregator.getCommitteeBits()).isEqualTo(result.getAttestation().getCommitteeBits()); assertThat(aggregator.getAggregationBits()) .isEqualTo(result.getAttestation().getAggregationBits()); } @@ -537,7 +536,11 @@ private ValidatableAttestation createAttestation( .getAggregationBitsSchema() .ofBits(committeeSizes.values().intStream().sum(), validators); final Supplier committeeBits = - () -> attestationSchema.getCommitteeBitsSchema().orElseThrow().ofBits(committeeIndices); + () -> + attestationSchema + .getCommitteeBitsSchemaOptional() + .orElseThrow() + .ofBits(committeeIndices); final ValidatableAttestation attestation = mock(ValidatableAttestation.class); when(attestation.getAttestation()) diff --git a/ethereum/statetransition/src/test/java/tech/pegasys/teku/statetransition/validation/AggregateAttestationValidatorTest.java b/ethereum/statetransition/src/test/java/tech/pegasys/teku/statetransition/validation/AggregateAttestationValidatorTest.java index e14769f17cd..95c96f9ae88 100644 --- a/ethereum/statetransition/src/test/java/tech/pegasys/teku/statetransition/validation/AggregateAttestationValidatorTest.java +++ b/ethereum/statetransition/src/test/java/tech/pegasys/teku/statetransition/validation/AggregateAttestationValidatorTest.java @@ -659,6 +659,9 @@ private CommitteeAssignment getCommitteeAssignment( private Supplier getCommitteeBitsSupplier( final AttestationSchema attestationSchema, final UInt64 committeeIndex) { return () -> - attestationSchema.getCommitteeBitsSchema().orElseThrow().ofBits(committeeIndex.intValue()); + attestationSchema + .getCommitteeBitsSchemaOptional() + .orElseThrow() + .ofBits(committeeIndex.intValue()); } } diff --git a/ethereum/statetransition/src/test/java/tech/pegasys/teku/statetransition/validation/ElectraAttestationValidatorTest.java b/ethereum/statetransition/src/test/java/tech/pegasys/teku/statetransition/validation/ElectraAttestationValidatorTest.java index b663e664092..373e0ac85b0 100644 --- a/ethereum/statetransition/src/test/java/tech/pegasys/teku/statetransition/validation/ElectraAttestationValidatorTest.java +++ b/ethereum/statetransition/src/test/java/tech/pegasys/teku/statetransition/validation/ElectraAttestationValidatorTest.java @@ -41,10 +41,15 @@ public void shouldRejectAttestationForMultipleCommittees() { attestation.getAggregationBits(), attestation.getData(), attestation.getAggregateSignature(), - () -> attestation.getSchema().getCommitteeBitsSchema().orElseThrow().ofBits(1, 3)); + () -> + attestation + .getSchema() + .getCommitteeBitsSchemaOptional() + .orElseThrow() + .ofBits(1, 3)); // Sanity check - assertThat(wrongAttestation.getCommitteeBitsRequired().getBitCount()).isGreaterThan(1); + assertThat(wrongAttestation.getCommitteeBits().getBitCount()).isGreaterThan(1); assertThat(validate(wrongAttestation)) .isEqualTo( @@ -74,7 +79,7 @@ public void shouldRejectAggregateWithAttestationDataIndexNonZero() { attestation.getAggregationBits(), nonZeroIndexData, attestation.getAggregateSignature(), - attestation::getCommitteeBitsRequired); + attestation::getCommitteeBits); // Sanity check assertThat(wrongAttestation.getData().getIndex()).isNotEqualTo(UInt64.ZERO); diff --git a/ethereum/statetransition/src/testFixtures/java/tech/pegasys/teku/statetransition/attestation/AggregatorUtil.java b/ethereum/statetransition/src/testFixtures/java/tech/pegasys/teku/statetransition/attestation/AggregatorUtil.java index 03f31a4a0db..67d87797fef 100644 --- a/ethereum/statetransition/src/testFixtures/java/tech/pegasys/teku/statetransition/attestation/AggregatorUtil.java +++ b/ethereum/statetransition/src/testFixtures/java/tech/pegasys/teku/statetransition/attestation/AggregatorUtil.java @@ -39,19 +39,19 @@ public static Attestation aggregateAttestations( for (Attestation attestation : attestations) { aggregateBits = aggregateBits.or(attestation.getAggregationBits()); signatures.add(attestation.getAggregateSignature()); - if (firstAttestation.getCommitteeBits().isPresent()) { - participationIndices.addAll(attestation.getCommitteeBitsRequired().getAllSetBits()); + if (firstAttestation.getCommitteeBitsOptional().isPresent()) { + participationIndices.addAll(attestation.getCommitteeBits().getAllSetBits()); checkState( participationIndices.size() == 1, "this test util doesn't support generating cross-committee aggregations"); } } - if (firstAttestation.getCommitteeBits().isPresent()) { + if (firstAttestation.getCommitteeBitsOptional().isPresent()) { committeeBitsSupplier = firstAttestation .getSchema() - .getCommitteeBitsSchema() + .getCommitteeBitsSchemaOptional() .map( committeeBitsSchema -> (Supplier) diff --git a/gradle/versions.gradle b/gradle/versions.gradle index 1d88d3b3afb..0e6e372f3bc 100644 --- a/gradle/versions.gradle +++ b/gradle/versions.gradle @@ -175,5 +175,7 @@ dependencyManagement { } dependency 'net.jqwik:jqwik:1.9.0' + + dependency 'org.javassist:javassist:3.30.2-GA' } } diff --git a/infrastructure/ssz/generator/build.gradle b/infrastructure/ssz/generator/build.gradle index c566f99fbd8..ceadb05ccd2 100644 --- a/infrastructure/ssz/generator/build.gradle +++ b/infrastructure/ssz/generator/build.gradle @@ -1,6 +1,8 @@ dependencies { compileOnly 'org.apache.tuweni:tuweni-bytes' implementation project(':infrastructure:ssz') + implementation 'org.javassist:javassist' + implementation 'org.apache.commons:commons-text' } task generateContainers(type: JavaExec) { diff --git a/infrastructure/ssz/generator/src/main/java/tech/pegasys/teku/infrastructure/ssz/SszTypeGenerator.java b/infrastructure/ssz/generator/src/main/java/tech/pegasys/teku/infrastructure/ssz/SszTypeGenerator.java new file mode 100644 index 00000000000..8570f150681 --- /dev/null +++ b/infrastructure/ssz/generator/src/main/java/tech/pegasys/teku/infrastructure/ssz/SszTypeGenerator.java @@ -0,0 +1,345 @@ +/* + * 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.infrastructure.ssz; + +import com.google.common.base.CaseFormat; +import com.google.common.base.Converter; +import com.google.errorprone.annotations.FormatMethod; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.util.List; +import javassist.CannotCompileException; +import javassist.ClassPool; +import javassist.CtClass; +import javassist.CtMethod; +import javassist.CtNewConstructor; +import javassist.CtNewMethod; +import javassist.NotFoundException; +import tech.pegasys.teku.infrastructure.ssz.impl.AbstractSszImmutableContainer; +import tech.pegasys.teku.infrastructure.ssz.schema.SszSchema; +import tech.pegasys.teku.infrastructure.ssz.schema.impl.AbstractSszContainerSchema; +import tech.pegasys.teku.infrastructure.ssz.schema.impl.AbstractSszContainerSchema.NamedSchema; + +public class SszTypeGenerator> { + private static final Converter LOWER_UNDERSCORE_TO_UPPER_CAMEL = + CaseFormat.LOWER_UNDERSCORE.converterTo(CaseFormat.UPPER_CAMEL); + + public static String snakeCaseToUpperCamel(final String camelCase) { + return LOWER_UNDERSCORE_TO_UPPER_CAMEL.convert(camelCase); + } + + private final ClassPool classPool = ClassPool.getDefault(); + private final Class typeInterface; + private final Class schemaInterface; + private final NamedSchema[] fields; + private final String interfaceName; + private final String typeImplClassName; + private final String schemaClassName; + + public SszTypeGenerator( + final Class typeInterface, + final Class schemaInterface, + final NamedSchema... fields) { + this.typeInterface = typeInterface; + this.schemaInterface = schemaInterface; + this.fields = fields; + + interfaceName = typeInterface.getCanonicalName(); + typeImplClassName = interfaceName + "Impl"; + schemaClassName = schemaInterface.getCanonicalName() + "Impl"; + } + + public S defineType() + throws NotFoundException, + CannotCompileException, + InvocationTargetException, + NoSuchMethodException, + InstantiationException, + IllegalAccessException { + + // try to reuse existing class + final S existingSchemaClassInstance = getInstanceViaExistingClass(); + if (existingSchemaClassInstance != null) { + return existingSchemaClassInstance; + } + + // Define the two new classes we'll create so they can reference each other + // Most of the class implementations come from the abstract super classes written in plain Java. + + final CtClass implClass = + classPool.makeClass(typeImplClassName, asCtClass(AbstractSszImmutableContainer.class)); + final CtClass schemaClass = + classPool.makeClass(schemaClassName, asCtClass(AbstractSszContainerSchema.class)); + defineTypeMethods(implClass); + defineSchemaMethods(schemaClass); + implClass.toClass(typeInterface); + return createSchema(schemaClass); + } + + @SuppressWarnings("unchecked") + private S getInstanceViaExistingClass() { + final Class existingSchemaClass; + try { + existingSchemaClass = (Class) Class.forName(schemaClassName); + return existingSchemaClass.getDeclaredConstructor(List.class).newInstance(List.of(fields)); + } catch (NoSuchMethodException + | InvocationTargetException + | IllegalAccessException + | InstantiationException e) { + throw new RuntimeException(e); + } catch (ClassNotFoundException ignored) { + return null; + } + } + + private void defineTypeMethods(final CtClass implClass) + throws CannotCompileException, NotFoundException, NoSuchMethodException { + // Declare the class as an implementation of the specified interface + implClass.addInterface(asCtClass(typeInterface)); + + // Add a single constructor that accepts the schema we're defining and a backing tree + addConstructor( + implClass, + """ + public %s(%s schema, tech.pegasys.teku.infrastructure.ssz.tree.TreeNode node) { + super($1, $2); + } + """, + typeInterface.getSimpleName() + "Impl", + schemaClassName); + + // For each field, generate a getter method for that field. + for (int i = 0; i < fields.length; i++) { + final NamedSchema field = fields[i]; + final String methodName = "get" + snakeCaseToUpperCamel(field.getName()); + final Method declaredMethod = validateInterfaceMethod(methodName, field); + addMethod( + implClass, + """ + public %s %s() { + return (%s) getAny(%d); + } + """, + declaredMethod.getReturnType().getCanonicalName(), + methodName, + declaredMethod.getReturnType().getCanonicalName(), + i); + } + + final String methodName = "getSchema"; + final Method declaredMethod; + try { + declaredMethod = typeInterface.getMethod(methodName); + } catch (NoSuchMethodException e) { + // interface doesn't care about this schema getter + return; + } + addMethod( + implClass, + """ + public %s getSchema() { + return (%s) super.getSchema(); + } + """, + declaredMethod.getReturnType().getCanonicalName(), + declaredMethod.getReturnType().getCanonicalName()); + + // + // implClass.addMethod(CtNewMethod.make( + // Modifier.PUBLIC, + // asCtClass(declaredMethod.getReturnType()), + // methodName, + // null, + // null, + // String.format("{ return (%s) super.getSchema(); }", + // declaredMethod.getReturnType().getCanonicalName()), + // implClass)); + + } + + private Method validateInterfaceMethod(final String methodName, final NamedSchema field) + throws NoSuchMethodException { + final Method declaredMethod = typeInterface.getMethod(methodName); + if (!declaredMethod.getReturnType().equals(field.getTypeClass())) { + throw new IllegalArgumentException( + String.format( + "Return type of method %s does not match field type %s", + methodName, field.getTypeClass())); + } + return declaredMethod; + } + + private void defineSchemaMethods(final CtClass schemaClass) + throws CannotCompileException, NotFoundException, NoSuchMethodException { + // Declare the schema class as an implementation of the schema interface + schemaClass.addInterface(asCtClass(schemaInterface)); + + // Add a constructor that accepts the list of NamedField defining the fields for this type + addConstructor( + schemaClass, + """ + public %s(java.util.List fields) { + super(\"%s\", $1); + } + """, + schemaClass.getSimpleName(), + typeInterface.getSimpleName()); + + // Define the createFromBackingNode abstract method to call the type class's constructor + addCreateFromBackingNode(schemaClass); + // addMethod( + // schemaClass, + // """ + // public %s + // createFromBackingNode(tech.pegasys.teku.infrastructure.ssz.tree.TreeNode node) { + // return new %s(this, node); + // } + // """, + // interfaceName, + // typeImplClassName); + + // For each create method in the schema, add a create method implementation that instantiates + // an instance of our new type class, passing the schema instance and a backing node tree + // generated from the arguments. + for (Method createMethod : schemaInterface.getDeclaredMethods()) { + if (!createMethod.getName().equals("create") + || !createMethod.getReturnType().equals(typeInterface) + // We skip default methods so the schema can define additional default create methods + // to make it easier to construct the object if required + || createMethod.isDefault()) { + continue; + } + // Validate parameter types + Class[] parameterTypes = createMethod.getParameterTypes(); + if (parameterTypes.length != fields.length) { + throw new IllegalArgumentException( + String.format( + "Create params count %s differ from declared field count %s", + parameterTypes.length, fields.length)); + } + for (int i = 0; i < parameterTypes.length; i++) { + if (!parameterTypes[i].equals(fields[i].getTypeClass())) { + throw new IllegalArgumentException( + String.format( + "Parameter type of method %s does not match field type %s", + createMethod.getName(), fields[i].getTypeClass().getCanonicalName())); + } + } + final CtMethod method = + new CtMethod( + asCtClass(typeInterface), + createMethod.getName(), + asCtClasses(createMethod.getParameterTypes()), + schemaClass); + method.setBody( + String.format( + "return new %s(this, createTreeFromFieldValues(java.util.Arrays.asList($args)));", + typeImplClassName)); + schemaClass.addMethod(method); + } + + // For each field, define a getter for its schema. + for (int i = 0; i < fields.length; i++) { + final NamedSchema field = fields[i]; + final String methodName = "get" + snakeCaseToUpperCamel(field.getName()) + "Schema"; + + final Method declaredMethod; + try { + declaredMethod = schemaInterface.getMethod(methodName); + } catch (NoSuchMethodException e) { + // interface doesn't care about this schema getter + continue; + } + // Validate that the return type matches the schema type + if (!declaredMethod.getReturnType().isAssignableFrom(field.getSchema().getClass())) { + throw new IllegalArgumentException( + String.format( + "Return type of method %s does not match schema type %s", + methodName, field.getSchema().getClass())); + } + addMethod( + schemaClass, + """ + public %s %s() { + return (%s) getChildSchema(%d); + } + """, + declaredMethod.getReturnType().getCanonicalName(), + methodName, + declaredMethod.getReturnType().getCanonicalName(), + i); + } + } + + @SuppressWarnings("unchecked") + private S createSchema(final CtClass schemaClass) + throws CannotCompileException, + NoSuchMethodException, + InvocationTargetException, + InstantiationException, + IllegalAccessException { + // Actually creates an instance of the schema to return. + // Instances of the type can be created from the schema create methods. + // The implementation classes are never exposed. + // TODO: Should validate that all methods on the interface is implemented + return (S) + schemaClass + .toClass(typeInterface) + .getDeclaredConstructor(List.class) + .newInstance(List.of(fields)); + } + + @FormatMethod + private void addConstructor(final CtClass ctClass, final String method, final Object... args) + throws CannotCompileException { + final String methodContent = String.format(method, args); + System.out.println(methodContent); + ctClass.addConstructor(CtNewConstructor.make(methodContent, ctClass)); + } + + @FormatMethod + private void addMethod(final CtClass ctClass, final String method, final Object... args) + throws CannotCompileException { + final String methodContent = String.format(method, args); + System.out.println(methodContent); + ctClass.addMethod(CtMethod.make(methodContent, ctClass)); + } + + private void addCreateFromBackingNode(final CtClass ctClass) + throws CannotCompileException, NotFoundException { + + ctClass.addMethod( + CtNewMethod.make( + Modifier.PUBLIC, + asCtClass(SszContainer.class), + "createFromBackingNode", + new CtClass[] {classPool.get("tech.pegasys.teku.infrastructure.ssz.tree.TreeNode")}, + null, + String.format("{ return new %s(this, $1); }", typeImplClassName), + ctClass)); + } + + private CtClass asCtClass(final Class clazz) throws NotFoundException { + return classPool.get(clazz.getCanonicalName()); + } + + private CtClass[] asCtClasses(final Class[] classes) throws NotFoundException { + final CtClass[] ctClasses = new CtClass[classes.length]; + for (int i = 0; i < ctClasses.length; i++) { + ctClasses[i] = asCtClass(classes[i]); + } + return ctClasses; + } +} diff --git a/infrastructure/ssz/generator/src/test/java/tech/pegasys/teku/infrastructure/ssz/SimpleType.java b/infrastructure/ssz/generator/src/test/java/tech/pegasys/teku/infrastructure/ssz/SimpleType.java new file mode 100644 index 00000000000..61bfbb6cd3e --- /dev/null +++ b/infrastructure/ssz/generator/src/test/java/tech/pegasys/teku/infrastructure/ssz/SimpleType.java @@ -0,0 +1,21 @@ +/* + * 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.infrastructure.ssz; + +import tech.pegasys.teku.infrastructure.ssz.primitive.SszUInt64; + +public interface SimpleType extends SszContainer { + + SszUInt64 getField1(); +} diff --git a/infrastructure/ssz/generator/src/test/java/tech/pegasys/teku/infrastructure/ssz/SimpleTypeSchema.java b/infrastructure/ssz/generator/src/test/java/tech/pegasys/teku/infrastructure/ssz/SimpleTypeSchema.java new file mode 100644 index 00000000000..e168269a6e2 --- /dev/null +++ b/infrastructure/ssz/generator/src/test/java/tech/pegasys/teku/infrastructure/ssz/SimpleTypeSchema.java @@ -0,0 +1,29 @@ +/* + * 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.infrastructure.ssz; + +import tech.pegasys.teku.infrastructure.ssz.primitive.SszUInt64; +import tech.pegasys.teku.infrastructure.ssz.schema.SszPrimitiveSchema; +import tech.pegasys.teku.infrastructure.ssz.schema.SszSchema; +import tech.pegasys.teku.infrastructure.unsigned.UInt64; + +public interface SimpleTypeSchema extends SszSchema { + SimpleType create(SszUInt64 field1); + + SszPrimitiveSchema getField1Schema(); + + default boolean asd() { + return true; + } +} diff --git a/infrastructure/ssz/generator/src/test/java/tech/pegasys/teku/infrastructure/ssz/SszTypeGeneratorTest.java b/infrastructure/ssz/generator/src/test/java/tech/pegasys/teku/infrastructure/ssz/SszTypeGeneratorTest.java new file mode 100644 index 00000000000..9561f4e0178 --- /dev/null +++ b/infrastructure/ssz/generator/src/test/java/tech/pegasys/teku/infrastructure/ssz/SszTypeGeneratorTest.java @@ -0,0 +1,38 @@ +/* + * 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.infrastructure.ssz; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.jupiter.api.Test; +import tech.pegasys.teku.infrastructure.ssz.primitive.SszUInt64; +import tech.pegasys.teku.infrastructure.ssz.schema.SszPrimitiveSchemas; +import tech.pegasys.teku.infrastructure.ssz.schema.impl.AbstractSszContainerSchema.NamedSchema; + +class SszTypeGeneratorTest { + + @Test + void shouldDefineASimpleType() throws Exception { + final SszTypeGenerator sszTypeGenerator = + new SszTypeGenerator<>( + SimpleType.class, + SimpleTypeSchema.class, + NamedSchema.of("field1", SszPrimitiveSchemas.UINT64_SCHEMA, SszUInt64.class)); + final SimpleTypeSchema schema = sszTypeGenerator.defineType(); + assertThat(schema.getField1Schema()).isSameAs(SszPrimitiveSchemas.UINT64_SCHEMA); + final SimpleType simpleType = schema.create(SszUInt64.ZERO); + assertThat(simpleType).isInstanceOf(SimpleType.class); + assertThat(simpleType.getField1()).isEqualTo(SszUInt64.ZERO); + } +} diff --git a/infrastructure/ssz/src/main/java/tech/pegasys/teku/infrastructure/ssz/schema/impl/AbstractSszContainerSchema.java b/infrastructure/ssz/src/main/java/tech/pegasys/teku/infrastructure/ssz/schema/impl/AbstractSszContainerSchema.java index a735b09e141..08cdc47a531 100644 --- a/infrastructure/ssz/src/main/java/tech/pegasys/teku/infrastructure/ssz/schema/impl/AbstractSszContainerSchema.java +++ b/infrastructure/ssz/src/main/java/tech/pegasys/teku/infrastructure/ssz/schema/impl/AbstractSszContainerSchema.java @@ -49,15 +49,28 @@ public abstract class AbstractSszContainerSchema public static class NamedSchema { private final String name; private final SszSchema schema; + private final Class typeClass; public static NamedSchema of( final String name, final SszSchema schema) { return new NamedSchema<>(name, schema); } + public static NamedSchema of( + final String name, final SszSchema schema, final Class typeClass) { + return new NamedSchema<>(name, schema, typeClass); + } + private NamedSchema(final String name, final SszSchema schema) { this.name = name; this.schema = schema; + this.typeClass = null; + } + + private NamedSchema(final String name, final SszSchema schema, final Class typeClass) { + this.name = name; + this.schema = schema; + this.typeClass = typeClass; } public String getName() { @@ -67,6 +80,10 @@ public String getName() { public SszSchema getSchema() { return schema; } + + public Class getTypeClass() { + return typeClass; + } } protected static NamedSchema namedSchema( diff --git a/validator/client/src/main/java/tech/pegasys/teku/validator/client/duties/attestations/AttestationProductionDuty.java b/validator/client/src/main/java/tech/pegasys/teku/validator/client/duties/attestations/AttestationProductionDuty.java index c6d97eab41e..be7255f7ddc 100644 --- a/validator/client/src/main/java/tech/pegasys/teku/validator/client/duties/attestations/AttestationProductionDuty.java +++ b/validator/client/src/main/java/tech/pegasys/teku/validator/client/duties/attestations/AttestationProductionDuty.java @@ -213,7 +213,7 @@ private Attestation createSignedAttestation( final Supplier committeeBitsSupplier = attestationSchema - .getCommitteeBitsSchema() + .getCommitteeBitsSchemaOptional() .>map( committeeBitsSchema -> () -> committeeBitsSchema.ofBits(validator.committeeIndex())) .orElse(() -> null); diff --git a/validator/client/src/test/java/tech/pegasys/teku/validator/client/duties/AttestationProductionDutyTest.java b/validator/client/src/test/java/tech/pegasys/teku/validator/client/duties/AttestationProductionDutyTest.java index 6a2d0a9e215..e3ff9a00221 100644 --- a/validator/client/src/test/java/tech/pegasys/teku/validator/client/duties/AttestationProductionDutyTest.java +++ b/validator/client/src/test/java/tech/pegasys/teku/validator/client/duties/AttestationProductionDutyTest.java @@ -541,7 +541,11 @@ private Attestation createExpectedAttestation( if (spec.atSlot(attestationData.getSlot()).getMilestone().isGreaterThanOrEqualTo(ELECTRA)) { committeeBits = - () -> attestationSchema.getCommitteeBitsSchema().orElseThrow().ofBits(committeeIndex); + () -> + attestationSchema + .getCommitteeBitsSchemaOptional() + .orElseThrow() + .ofBits(committeeIndex); } else { committeeBits = () -> null; } diff --git a/validator/remote/src/integration-test/java/tech/pegasys/teku/validator/remote/typedef/handlers/CreateAggregateAttestationRequestElectraTest.java b/validator/remote/src/integration-test/java/tech/pegasys/teku/validator/remote/typedef/handlers/CreateAggregateAttestationRequestElectraTest.java index 5dd3e1be30e..0e26fafd86f 100644 --- a/validator/remote/src/integration-test/java/tech/pegasys/teku/validator/remote/typedef/handlers/CreateAggregateAttestationRequestElectraTest.java +++ b/validator/remote/src/integration-test/java/tech/pegasys/teku/validator/remote/typedef/handlers/CreateAggregateAttestationRequestElectraTest.java @@ -92,7 +92,7 @@ public void shouldGetAggregateAttestation() { final UInt64 committeeIndex = specMilestone.isGreaterThanOrEqualTo(ELECTRA) ? UInt64.valueOf( - attestation.getCommitteeBitsRequired().streamAllSetBits().findFirst().orElseThrow()) + attestation.getCommitteeBits().streamAllSetBits().findFirst().orElseThrow()) : attestation.getData().getIndex(); createAggregateAttestationRequest =