diff --git a/beacon/validator/src/main/java/tech/pegasys/teku/validator/coordinator/ValidatorApiHandler.java b/beacon/validator/src/main/java/tech/pegasys/teku/validator/coordinator/ValidatorApiHandler.java index ad1798406b6..247bb3ce87d 100644 --- a/beacon/validator/src/main/java/tech/pegasys/teku/validator/coordinator/ValidatorApiHandler.java +++ b/beacon/validator/src/main/java/tech/pegasys/teku/validator/coordinator/ValidatorApiHandler.java @@ -78,11 +78,11 @@ import tech.pegasys.teku.spec.datastructures.blocks.SignedBlockAndState; import tech.pegasys.teku.spec.datastructures.blocks.SignedBlockContainer; import tech.pegasys.teku.spec.datastructures.builder.SignedValidatorRegistration; -import tech.pegasys.teku.spec.datastructures.execution.PayloadAttestationData; import tech.pegasys.teku.spec.datastructures.genesis.GenesisData; import tech.pegasys.teku.spec.datastructures.metadata.BlockContainerAndMetaData; import tech.pegasys.teku.spec.datastructures.operations.Attestation; import tech.pegasys.teku.spec.datastructures.operations.AttestationData; +import tech.pegasys.teku.spec.datastructures.operations.PayloadAttestationData; import tech.pegasys.teku.spec.datastructures.operations.PayloadAttestationMessage; import tech.pegasys.teku.spec.datastructures.operations.SignedAggregateAndProof; import tech.pegasys.teku.spec.datastructures.operations.versions.altair.SignedContributionAndProof; diff --git a/data/provider/src/main/java/tech/pegasys/teku/api/SchemaObjectProvider.java b/data/provider/src/main/java/tech/pegasys/teku/api/SchemaObjectProvider.java index 9562224914b..be1a6d481c7 100644 --- a/data/provider/src/main/java/tech/pegasys/teku/api/SchemaObjectProvider.java +++ b/data/provider/src/main/java/tech/pegasys/teku/api/SchemaObjectProvider.java @@ -36,6 +36,9 @@ import tech.pegasys.teku.api.schema.deneb.BeaconStateDeneb; import tech.pegasys.teku.api.schema.deneb.BlindedBeaconBlockBodyDeneb; import tech.pegasys.teku.api.schema.deneb.BlindedBlockDeneb; +import tech.pegasys.teku.api.schema.eip7732.BeaconBlockBodyEip7732; +import tech.pegasys.teku.api.schema.eip7732.BeaconBlockEip7732; +import tech.pegasys.teku.api.schema.eip7732.BeaconStateEip7732; import tech.pegasys.teku.api.schema.electra.BeaconBlockBodyElectra; import tech.pegasys.teku.api.schema.electra.BeaconBlockElectra; import tech.pegasys.teku.api.schema.electra.BeaconStateElectra; @@ -130,7 +133,13 @@ public BeaconBlock getBlindedBlock( block.getParentRoot(), block.getStateRoot(), getBlindedBlockBodyElectra(block.getBody())); - case EIP7732 -> throw new UnsupportedOperationException("EIP7732 TODO"); + case EIP7732 -> + new BeaconBlockEip7732( + block.getSlot(), + block.getProposerIndex(), + block.getParentRoot(), + block.getStateRoot(), + getBeaconBlockBodyEip7732(block.getBody())); }; } @@ -180,7 +189,13 @@ public BeaconBlock getBeaconBlock( block.getParentRoot(), block.getStateRoot(), getBeaconBlockBodyElectra(block.getBody())); - case EIP7732 -> throw new UnsupportedOperationException("EIP7732 TODO"); + case EIP7732 -> + new BeaconBlockEip7732( + block.getSlot(), + block.getProposerIndex(), + block.getParentRoot(), + block.getStateRoot(), + getBeaconBlockBodyEip7732(block.getBody())); }; } @@ -219,6 +234,13 @@ private BeaconBlockBodyElectra getBeaconBlockBodyElectra( .BeaconBlockBodyElectra.required(body)); } + private BeaconBlockBodyEip7732 getBeaconBlockBodyEip7732( + final tech.pegasys.teku.spec.datastructures.blocks.blockbody.BeaconBlockBody body) { + return new BeaconBlockBodyEip7732( + tech.pegasys.teku.spec.datastructures.blocks.blockbody.versions.eip7732 + .BeaconBlockBodyEip7732.required(body)); + } + private BlindedBeaconBlockBodyBellatrix getBlindedBlockBodyBellatrix( final tech.pegasys.teku.spec.datastructures.blocks.blockbody.BeaconBlockBody body) { return new BlindedBeaconBlockBodyBellatrix( @@ -257,7 +279,7 @@ public BeaconState getBeaconState( case CAPELLA -> new BeaconStateCapella(state); case DENEB -> new BeaconStateDeneb(state); case ELECTRA -> new BeaconStateElectra(state); - case EIP7732 -> throw new UnsupportedOperationException("EIP7732 TODO"); + case EIP7732 -> new BeaconStateEip7732(state); }; } } diff --git a/data/serializer/src/main/java/tech/pegasys/teku/api/schema/ExecutionPayloadHeader.java b/data/serializer/src/main/java/tech/pegasys/teku/api/schema/ExecutionPayloadHeader.java index f82dd3f7eff..37c87137bc5 100644 --- a/data/serializer/src/main/java/tech/pegasys/teku/api/schema/ExecutionPayloadHeader.java +++ b/data/serializer/src/main/java/tech/pegasys/teku/api/schema/ExecutionPayloadHeader.java @@ -17,6 +17,7 @@ import tech.pegasys.teku.api.schema.bellatrix.ExecutionPayloadHeaderBellatrix; import tech.pegasys.teku.api.schema.capella.ExecutionPayloadHeaderCapella; import tech.pegasys.teku.api.schema.deneb.ExecutionPayloadHeaderDeneb; +import tech.pegasys.teku.api.schema.eip7732.ExecutionPayloadHeaderEip7732; import tech.pegasys.teku.api.schema.electra.ExecutionPayloadHeaderElectra; import tech.pegasys.teku.spec.datastructures.execution.ExecutionPayloadHeaderSchema; @@ -39,4 +40,8 @@ default Optional toVersionDeneb() { default Optional toVersionElectra() { return Optional.empty(); } + + default Optional toVersionEip7732() { + return Optional.empty(); + } } diff --git a/data/serializer/src/main/java/tech/pegasys/teku/api/schema/SignedBeaconBlock.java b/data/serializer/src/main/java/tech/pegasys/teku/api/schema/SignedBeaconBlock.java index d88ff3a8b2b..8fad83457a1 100644 --- a/data/serializer/src/main/java/tech/pegasys/teku/api/schema/SignedBeaconBlock.java +++ b/data/serializer/src/main/java/tech/pegasys/teku/api/schema/SignedBeaconBlock.java @@ -29,6 +29,7 @@ import tech.pegasys.teku.api.schema.capella.SignedBlindedBeaconBlockCapella; import tech.pegasys.teku.api.schema.deneb.SignedBeaconBlockDeneb; import tech.pegasys.teku.api.schema.deneb.SignedBlindedBeaconBlockDeneb; +import tech.pegasys.teku.api.schema.eip7732.SignedBeaconBlockEip7732; import tech.pegasys.teku.api.schema.electra.SignedBeaconBlockElectra; import tech.pegasys.teku.api.schema.electra.SignedBlindedBeaconBlockElectra; import tech.pegasys.teku.api.schema.interfaces.SignedBlock; @@ -65,6 +66,14 @@ public static SignedBeaconBlock create( internalBlock.getMessage().getBody(); return Stream.of( + () -> + beaconBlock + .toBlindedVersionEip7732() + .map(__ -> new SignedBeaconBlockEip7732(internalBlock)), + () -> + beaconBlock + .toVersionEip7732() + .map(__ -> new SignedBeaconBlockEip7732(internalBlock)), () -> beaconBlock .toBlindedVersionElectra() diff --git a/data/serializer/src/main/java/tech/pegasys/teku/api/schema/eip7732/BeaconBlockBodyEip7732.java b/data/serializer/src/main/java/tech/pegasys/teku/api/schema/eip7732/BeaconBlockBodyEip7732.java new file mode 100644 index 00000000000..3496869af14 --- /dev/null +++ b/data/serializer/src/main/java/tech/pegasys/teku/api/schema/eip7732/BeaconBlockBodyEip7732.java @@ -0,0 +1,137 @@ +/* + * Copyright Consensys Software Inc., 2022 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package tech.pegasys.teku.api.schema.eip7732; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; +import java.util.List; +import org.apache.tuweni.bytes.Bytes32; +import tech.pegasys.teku.api.schema.Attestation; +import tech.pegasys.teku.api.schema.AttesterSlashing; +import tech.pegasys.teku.api.schema.BLSSignature; +import tech.pegasys.teku.api.schema.Deposit; +import tech.pegasys.teku.api.schema.Eth1Data; +import tech.pegasys.teku.api.schema.ProposerSlashing; +import tech.pegasys.teku.api.schema.SignedVoluntaryExit; +import tech.pegasys.teku.api.schema.altair.BeaconBlockBodyAltair; +import tech.pegasys.teku.api.schema.altair.SyncAggregate; +import tech.pegasys.teku.api.schema.capella.SignedBlsToExecutionChange; +import tech.pegasys.teku.infrastructure.async.SafeFuture; +import tech.pegasys.teku.infrastructure.ssz.schema.SszListSchema; +import tech.pegasys.teku.spec.SpecVersion; +import tech.pegasys.teku.spec.datastructures.blocks.blockbody.BeaconBlockBody; +import tech.pegasys.teku.spec.datastructures.blocks.blockbody.versions.eip7732.BeaconBlockBodySchemaEip7732; + +public class BeaconBlockBodyEip7732 extends BeaconBlockBodyAltair { + + @JsonProperty("bls_to_execution_changes") + public final List blsToExecutionChanges; + + @JsonProperty("signed_execution_payload_header") + public final SignedExecutionPayloadHeader signedExecutionPayloadHeader; + + @JsonProperty("payload_attestations") + public final List payloadAttestations; + + @JsonCreator + public BeaconBlockBodyEip7732( + @JsonProperty("randao_reveal") final BLSSignature randaoReveal, + @JsonProperty("eth1_data") final Eth1Data eth1Data, + @JsonProperty("graffiti") final Bytes32 graffiti, + @JsonProperty("proposer_slashings") final List proposerSlashings, + @JsonProperty("attester_slashings") final List attesterSlashings, + @JsonProperty("attestations") final List attestations, + @JsonProperty("deposits") final List deposits, + @JsonProperty("voluntary_exits") final List voluntaryExits, + @JsonProperty("sync_aggregate") final SyncAggregate syncAggregate, + @JsonProperty("bls_to_execution_changes") + final List blsToExecutionChanges, + @JsonProperty("signed_execution_payload_header") + final SignedExecutionPayloadHeader signedExecutionPayloadHeader, + @JsonProperty("payload_attestations") final List payloadAttestations) { + super( + randaoReveal, + eth1Data, + graffiti, + proposerSlashings, + attesterSlashings, + attestations, + deposits, + voluntaryExits, + syncAggregate); + checkNotNull(blsToExecutionChanges, "BlsToExecutionChanges is required for Eip7732 blocks"); + this.blsToExecutionChanges = blsToExecutionChanges; + checkNotNull( + signedExecutionPayloadHeader, + "SignedExecutionPayloadHeader is required for Eip7732 blocks"); + this.signedExecutionPayloadHeader = signedExecutionPayloadHeader; + checkNotNull(payloadAttestations, "PayloadAttestations is required for Eip7732 blocks"); + this.payloadAttestations = payloadAttestations; + } + + public BeaconBlockBodyEip7732( + final tech.pegasys.teku.spec.datastructures.blocks.blockbody.versions.eip7732 + .BeaconBlockBodyEip7732 + message) { + super(message); + checkNotNull( + message.getBlsToExecutionChanges(), + "BlsToExecutionChanges are required for Eip7732 blocks"); + this.blsToExecutionChanges = + message.getBlsToExecutionChanges().stream().map(SignedBlsToExecutionChange::new).toList(); + checkNotNull( + message.getSignedExecutionPayloadHeader(), + "SignedExecutionPayloadHeader are required for Eip7732 blocks"); + this.signedExecutionPayloadHeader = + new SignedExecutionPayloadHeader(message.getSignedExecutionPayloadHeader()); + checkNotNull( + message.getPayloadAttestations(), "PayloadAttestations are required for Eip7732 blocks"); + this.payloadAttestations = + message.getPayloadAttestations().stream().map(PayloadAttestation::new).toList(); + } + + @Override + public BeaconBlockBodySchemaEip7732 getBeaconBlockBodySchema(final SpecVersion spec) { + return (BeaconBlockBodySchemaEip7732) spec.getSchemaDefinitions().getBeaconBlockBodySchema(); + } + + @Override + public BeaconBlockBody asInternalBeaconBlockBody(final SpecVersion spec) { + final SszListSchema< + tech.pegasys.teku.spec.datastructures.operations.SignedBlsToExecutionChange, ?> + blsToExecutionChangesSchema = + getBeaconBlockBodySchema(spec).getBlsToExecutionChangesSchema(); + return super.asInternalBeaconBlockBody( + spec, + builder -> { + builder.blsToExecutionChanges( + this.blsToExecutionChanges.stream() + .map(b -> b.asInternalSignedBlsToExecutionChange(spec)) + .collect(blsToExecutionChangesSchema.collector())); + builder.signedExecutionPayloadHeader( + signedExecutionPayloadHeader.asInternalSignedExecutionPayloadHeader(spec)); + final SszListSchema< + tech.pegasys.teku.spec.datastructures.operations.PayloadAttestation, ?> + payloadAttestationsSchema = + getBeaconBlockBodySchema(spec).getPayloadAttestationsSchema(); + builder.payloadAttestations( + this.payloadAttestations.stream() + .map(pa -> pa.asInternalPayloadAttestation(spec)) + .collect(payloadAttestationsSchema.collector())); + return SafeFuture.COMPLETE; + }); + } +} diff --git a/data/serializer/src/main/java/tech/pegasys/teku/api/schema/eip7732/BeaconBlockEip7732.java b/data/serializer/src/main/java/tech/pegasys/teku/api/schema/eip7732/BeaconBlockEip7732.java new file mode 100644 index 00000000000..053e70a9f0f --- /dev/null +++ b/data/serializer/src/main/java/tech/pegasys/teku/api/schema/eip7732/BeaconBlockEip7732.java @@ -0,0 +1,65 @@ +/* + * Copyright Consensys Software Inc., 2022 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package tech.pegasys.teku.api.schema.eip7732; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; +import org.apache.tuweni.bytes.Bytes32; +import tech.pegasys.teku.api.schema.altair.BeaconBlockAltair; +import tech.pegasys.teku.infrastructure.unsigned.UInt64; +import tech.pegasys.teku.spec.Spec; +import tech.pegasys.teku.spec.SpecVersion; +import tech.pegasys.teku.spec.datastructures.blocks.BeaconBlock; +import tech.pegasys.teku.spec.schemas.SchemaDefinitionsEip7732; + +public class BeaconBlockEip7732 extends BeaconBlockAltair { + + public BeaconBlockEip7732(final BeaconBlock message) { + super( + message.getSlot(), + message.getProposerIndex(), + message.getParentRoot(), + message.getStateRoot(), + new BeaconBlockBodyEip7732(message.getBody().toVersionEip7732().orElseThrow())); + } + + @Override + public BeaconBlock asInternalBeaconBlock(final Spec spec) { + final SpecVersion specVersion = spec.atSlot(slot); + return SchemaDefinitionsEip7732.required(specVersion.getSchemaDefinitions()) + .getBeaconBlockSchema() + .create( + slot, + proposer_index, + parent_root, + state_root, + body.asInternalBeaconBlockBody(specVersion)); + } + + @JsonProperty("body") + @Override + public BeaconBlockBodyEip7732 getBody() { + return (BeaconBlockBodyEip7732) body; + } + + @JsonCreator + public BeaconBlockEip7732( + @JsonProperty("slot") final UInt64 slot, + @JsonProperty("proposer_index") final UInt64 proposerIndex, + @JsonProperty("parent_root") final Bytes32 parentRoot, + @JsonProperty("state_root") final Bytes32 stateRoot, + @JsonProperty("body") final BeaconBlockBodyEip7732 body) { + super(slot, proposerIndex, parentRoot, stateRoot, body); + } +} diff --git a/data/serializer/src/main/java/tech/pegasys/teku/api/schema/eip7732/BeaconStateEip7732.java b/data/serializer/src/main/java/tech/pegasys/teku/api/schema/eip7732/BeaconStateEip7732.java new file mode 100644 index 00000000000..90c4468d26c --- /dev/null +++ b/data/serializer/src/main/java/tech/pegasys/teku/api/schema/eip7732/BeaconStateEip7732.java @@ -0,0 +1,323 @@ +/* + * Copyright Consensys Software Inc., 2022 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package tech.pegasys.teku.api.schema.eip7732; + +import static tech.pegasys.teku.api.schema.SchemaConstants.DESCRIPTION_BYTES32; +import static tech.pegasys.teku.api.schema.SchemaConstants.EXAMPLE_UINT64; +import static tech.pegasys.teku.api.schema.SchemaConstants.PATTERN_BYTES32; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; +import java.util.List; +import org.apache.tuweni.bytes.Bytes32; +import tech.pegasys.teku.api.schema.BeaconBlockHeader; +import tech.pegasys.teku.api.schema.Checkpoint; +import tech.pegasys.teku.api.schema.Eth1Data; +import tech.pegasys.teku.api.schema.Fork; +import tech.pegasys.teku.api.schema.Validator; +import tech.pegasys.teku.api.schema.altair.BeaconStateAltair; +import tech.pegasys.teku.api.schema.altair.SyncCommittee; +import tech.pegasys.teku.api.schema.capella.HistoricalSummary; +import tech.pegasys.teku.api.schema.electra.PendingBalanceDeposit; +import tech.pegasys.teku.api.schema.electra.PendingConsolidation; +import tech.pegasys.teku.api.schema.electra.PendingPartialWithdrawal; +import tech.pegasys.teku.infrastructure.ssz.collections.SszBitvector; +import tech.pegasys.teku.infrastructure.ssz.schema.SszListSchema; +import tech.pegasys.teku.infrastructure.unsigned.UInt64; +import tech.pegasys.teku.spec.SpecVersion; +import tech.pegasys.teku.spec.datastructures.execution.versions.eip7732.ExecutionPayloadHeaderSchemaEip7732; +import tech.pegasys.teku.spec.datastructures.state.SyncCommittee.SyncCommitteeSchema; +import tech.pegasys.teku.spec.datastructures.state.beaconstate.BeaconState; +import tech.pegasys.teku.spec.datastructures.state.beaconstate.MutableBeaconState; +import tech.pegasys.teku.spec.datastructures.state.beaconstate.versions.eip7732.BeaconStateSchemaEip7732; +import tech.pegasys.teku.spec.datastructures.state.beaconstate.versions.eip7732.MutableBeaconStateEip7732; + +public class BeaconStateEip7732 extends BeaconStateAltair { + + @JsonProperty("latest_execution_payload_header") + public final ExecutionPayloadHeaderEip7732 latestExecutionPayloadHeader; + + @JsonProperty("next_withdrawal_index") + @Schema(type = "string", example = EXAMPLE_UINT64) + public final UInt64 nextWithdrawalIndex; + + @JsonProperty("next_withdrawal_validator_index") + @Schema(type = "string", example = EXAMPLE_UINT64) + public final UInt64 nextWithdrawalValidatorIndex; + + @JsonProperty("historical_summaries") + public final List historicalSummaries; + + @JsonProperty("deposit_requests_start_index") + public final UInt64 depositRequestsStartIndex; + + @JsonProperty("deposit_balance_to_consume") + public final UInt64 depositBalanceToConsume; + + @JsonProperty("exit_balance_to_consume") + public final UInt64 exitBalanceToConsume; + + @JsonProperty("earliest_exit_epoch") + public final UInt64 earliestExitEpoch; + + @JsonProperty("consolidation_balance_to_consume") + public final UInt64 consolidationBalanceToConsume; + + @JsonProperty("earliest_consolidation_epoch") + public final UInt64 earliestConsolidationEpoch; + + @JsonProperty("pending_balance_deposits") + public final List pendingBalanceDeposits; + + @JsonProperty("pending_partial_withdrawals") + public final List pendingPartialWithdrawals; + + @JsonProperty("pending_consolidations") + public final List pendingConsolidations; + + @JsonProperty("latest_block_hash") + @Schema( + type = "string", + format = "byte", + pattern = PATTERN_BYTES32, + description = DESCRIPTION_BYTES32) + public final Bytes32 latestBlockHash; + + @JsonProperty("latest_full_slot") + @Schema(type = "string", format = "uint64") + public final UInt64 latestFullSlot; + + @JsonProperty("latest_withdrawals_root") + @Schema( + type = "string", + format = "byte", + pattern = PATTERN_BYTES32, + description = DESCRIPTION_BYTES32) + public final Bytes32 latestWithdrawalsRoot; + + public BeaconStateEip7732( + @JsonProperty("genesis_time") final UInt64 genesisTime, + @JsonProperty("genesis_validators_root") final Bytes32 genesisValidatorsRoot, + @JsonProperty("slot") final UInt64 slot, + @JsonProperty("fork") final Fork fork, + @JsonProperty("latest_block_header") final BeaconBlockHeader latestBlockHeader, + @JsonProperty("block_roots") final List blockRoots, + @JsonProperty("state_roots") final List stateRoots, + @JsonProperty("historical_roots") final List historicalRoots, + @JsonProperty("eth1_data") final Eth1Data eth1Data, + @JsonProperty("eth1_data_votes") final List eth1DataVotes, + @JsonProperty("eth1_deposit_index") final UInt64 eth1DepositIndex, + @JsonProperty("validators") final List validators, + @JsonProperty("balances") final List balances, + @JsonProperty("randao_mixes") final List randaoMixes, + @JsonProperty("slashings") final List slashings, + @JsonProperty("previous_epoch_participation") final byte[] previousEpochParticipation, + @JsonProperty("current_epoch_participation") final byte[] currentEpochParticipation, + @JsonProperty("justification_bits") final SszBitvector justificationBits, + @JsonProperty("previous_justified_checkpoint") final Checkpoint previousJustifiedCheckpoint, + @JsonProperty("current_justified_checkpoint") final Checkpoint currentJustifiedCheckpoint, + @JsonProperty("finalized_checkpoint") final Checkpoint finalizedCheckpoint, + @JsonProperty("inactivity_scores") final List inactivityScores, + @JsonProperty("current_sync_committee") final SyncCommittee currentSyncCommittee, + @JsonProperty("next_sync_committee") final SyncCommittee nextSyncCommittee, + @JsonProperty("latest_execution_payload_header") + final ExecutionPayloadHeaderEip7732 latestExecutionPayloadHeader, + @JsonProperty("next_withdrawal_index") final UInt64 nextWithdrawalIndex, + @JsonProperty("next_withdrawal_validator_index") final UInt64 nextWithdrawalValidatorIndex, + @JsonProperty("historical_summaries") final List historicalSummaries, + @JsonProperty("deposit_requests_start_index") final UInt64 depositRequestsStartIndex, + @JsonProperty("deposit_balance_to_consume") final UInt64 depositBalanceToConsume, + @JsonProperty("exit_balance_to_consume") final UInt64 exitBalanceToConsume, + @JsonProperty("earliest_exit_epoch") final UInt64 earliestExitEpoch, + @JsonProperty("consolidation_balance_to_consume") final UInt64 consolidationBalanceToConsume, + @JsonProperty("earliest_consolidation_epoch") final UInt64 earliestConsolidationEpoch, + @JsonProperty("pending_balance_deposits") + final List pendingBalanceDeposits, + @JsonProperty("pending_partial_withdrawals") + final List pendingPartialWithdrawals, + @JsonProperty("pending_consolidations") + final List pendingConsolidations, + @JsonProperty("latest_block_hash") final Bytes32 latestBlockHash, + @JsonProperty("latest_full_slot") final UInt64 latestFullSlot, + @JsonProperty("latest_withdrawals_root") final Bytes32 latestWithdrawalsRoot) { + super( + genesisTime, + genesisValidatorsRoot, + slot, + fork, + latestBlockHeader, + blockRoots, + stateRoots, + historicalRoots, + eth1Data, + eth1DataVotes, + eth1DepositIndex, + validators, + balances, + randaoMixes, + slashings, + previousEpochParticipation, + currentEpochParticipation, + justificationBits, + previousJustifiedCheckpoint, + currentJustifiedCheckpoint, + finalizedCheckpoint, + inactivityScores, + currentSyncCommittee, + nextSyncCommittee); + this.latestExecutionPayloadHeader = latestExecutionPayloadHeader; + this.nextWithdrawalIndex = nextWithdrawalIndex; + this.nextWithdrawalValidatorIndex = nextWithdrawalValidatorIndex; + this.historicalSummaries = historicalSummaries; + this.depositRequestsStartIndex = depositRequestsStartIndex; + this.depositBalanceToConsume = depositBalanceToConsume; + this.exitBalanceToConsume = exitBalanceToConsume; + this.earliestExitEpoch = earliestExitEpoch; + this.consolidationBalanceToConsume = consolidationBalanceToConsume; + this.earliestConsolidationEpoch = earliestConsolidationEpoch; + this.pendingBalanceDeposits = pendingBalanceDeposits; + this.pendingPartialWithdrawals = pendingPartialWithdrawals; + this.pendingConsolidations = pendingConsolidations; + this.latestBlockHash = latestBlockHash; + this.latestFullSlot = latestFullSlot; + this.latestWithdrawalsRoot = latestWithdrawalsRoot; + } + + public BeaconStateEip7732(final BeaconState beaconState) { + super(beaconState); + final tech.pegasys.teku.spec.datastructures.state.beaconstate.versions.eip7732 + .BeaconStateEip7732 + eip7732 = beaconState.toVersionEip7732().orElseThrow(); + this.latestExecutionPayloadHeader = + new ExecutionPayloadHeaderEip7732( + tech.pegasys.teku.spec.datastructures.execution.versions.eip7732 + .ExecutionPayloadHeaderEip7732.required(eip7732.getLatestExecutionPayloadHeader())); + this.nextWithdrawalIndex = eip7732.getNextWithdrawalIndex(); + this.nextWithdrawalValidatorIndex = eip7732.getNextWithdrawalValidatorIndex(); + this.historicalSummaries = + eip7732.getHistoricalSummaries().stream().map(HistoricalSummary::new).toList(); + this.depositRequestsStartIndex = eip7732.getDepositRequestsStartIndex(); + this.depositBalanceToConsume = eip7732.getDepositBalanceToConsume(); + this.exitBalanceToConsume = eip7732.getExitBalanceToConsume(); + this.earliestExitEpoch = eip7732.getEarliestExitEpoch(); + this.consolidationBalanceToConsume = eip7732.getConsolidationBalanceToConsume(); + this.earliestConsolidationEpoch = eip7732.getEarliestConsolidationEpoch(); + this.pendingBalanceDeposits = + eip7732.getPendingBalanceDeposits().stream().map(PendingBalanceDeposit::new).toList(); + this.pendingPartialWithdrawals = + eip7732.getPendingPartialWithdrawals().stream().map(PendingPartialWithdrawal::new).toList(); + this.pendingConsolidations = + eip7732.getPendingConsolidations().stream().map(PendingConsolidation::new).toList(); + this.latestBlockHash = eip7732.getLatestBlockHash(); + this.latestFullSlot = eip7732.getLatestFullSlot(); + this.latestWithdrawalsRoot = eip7732.getLatestWithdrawalsRoot(); + } + + @Override + protected void applyAdditionalFields( + final MutableBeaconState state, final SpecVersion specVersion) { + state + .toMutableVersionEip7732() + .ifPresent( + mutableBeaconStateEip7732 -> + applyEip7732Fields( + specVersion, + mutableBeaconStateEip7732, + BeaconStateSchemaEip7732.required( + mutableBeaconStateEip7732.getBeaconStateSchema()) + .getCurrentSyncCommitteeSchema(), + BeaconStateSchemaEip7732.required( + mutableBeaconStateEip7732.getBeaconStateSchema()) + .getLastExecutionPayloadHeaderSchema(), + BeaconStateSchemaEip7732.required( + mutableBeaconStateEip7732.getBeaconStateSchema()) + .getHistoricalSummariesSchema(), + BeaconStateSchemaEip7732.required( + mutableBeaconStateEip7732.getBeaconStateSchema()) + .getPendingBalanceDepositsSchema(), + BeaconStateSchemaEip7732.required( + mutableBeaconStateEip7732.getBeaconStateSchema()) + .getPendingPartialWithdrawalsSchema(), + BeaconStateSchemaEip7732.required( + mutableBeaconStateEip7732.getBeaconStateSchema()) + .getPendingConsolidationsSchema(), + this)); + } + + protected static void applyEip7732Fields( + final SpecVersion specVersion, + final MutableBeaconStateEip7732 state, + final SyncCommitteeSchema syncCommitteeSchema, + final ExecutionPayloadHeaderSchemaEip7732 executionPayloadHeaderSchema, + final SszListSchema< + tech.pegasys.teku.spec.datastructures.state.versions.capella.HistoricalSummary, ?> + historicalSummariesSchema, + final SszListSchema< + tech.pegasys.teku.spec.datastructures.state.versions.electra.PendingBalanceDeposit, ?> + pendingBalanceDepositsSchema, + final SszListSchema< + tech.pegasys.teku.spec.datastructures.state.versions.electra.PendingPartialWithdrawal, + ?> + pendingPartialWithdrawalsSchema, + final SszListSchema< + tech.pegasys.teku.spec.datastructures.state.versions.electra.PendingConsolidation, ?> + pendingConsolidationsSchema, + final BeaconStateEip7732 instance) { + + BeaconStateAltair.applyAltairFields(state, syncCommitteeSchema, instance); + + state.setLatestExecutionPayloadHeader( + instance.latestExecutionPayloadHeader.asInternalExecutionPayloadHeader( + executionPayloadHeaderSchema)); + + state.setNextWithdrawalIndex(instance.nextWithdrawalIndex); + state.setNextWithdrawalValidatorIndex(instance.nextWithdrawalValidatorIndex); + state.setHistoricalSummaries( + historicalSummariesSchema.createFromElements( + instance.historicalSummaries.stream() + .map( + historicalSummary -> historicalSummary.asInternalHistoricalSummary(specVersion)) + .toList())); + state.setDepositRequestsStartIndex(instance.depositRequestsStartIndex); + state.setDepositBalanceToConsume(instance.depositBalanceToConsume); + state.setExitBalanceToConsume(instance.exitBalanceToConsume); + state.setEarliestExitEpoch(instance.earliestExitEpoch); + state.setConsolidationBalanceToConsume(instance.consolidationBalanceToConsume); + state.setEarliestConsolidationEpoch(instance.earliestConsolidationEpoch); + state.setPendingBalanceDeposits( + pendingBalanceDepositsSchema.createFromElements( + instance.pendingBalanceDeposits.stream() + .map( + pendingBalanceDeposit -> + pendingBalanceDeposit.asInternalPendingBalanceDeposit(specVersion)) + .toList())); + state.setPendingPartialWithdrawals( + pendingPartialWithdrawalsSchema.createFromElements( + instance.pendingPartialWithdrawals.stream() + .map( + pendingPartialWithdrawal -> + pendingPartialWithdrawal.asInternalPendingPartialWithdrawal(specVersion)) + .toList())); + state.setPendingConsolidations( + pendingConsolidationsSchema.createFromElements( + instance.pendingConsolidations.stream() + .map( + pendingConsolidation -> + pendingConsolidation.asInternalPendingConsolidation(specVersion)) + .toList())); + state.setLatestBlockHash(instance.latestBlockHash); + state.setLatestFullSlot(instance.latestFullSlot); + state.setLatestWithdrawalsRoot(instance.latestWithdrawalsRoot); + } +} diff --git a/data/serializer/src/main/java/tech/pegasys/teku/api/schema/eip7732/ExecutionPayloadHeaderEip7732.java b/data/serializer/src/main/java/tech/pegasys/teku/api/schema/eip7732/ExecutionPayloadHeaderEip7732.java new file mode 100644 index 00000000000..ffbf087449b --- /dev/null +++ b/data/serializer/src/main/java/tech/pegasys/teku/api/schema/eip7732/ExecutionPayloadHeaderEip7732.java @@ -0,0 +1,175 @@ +/* + * 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.api.schema.eip7732; + +import static tech.pegasys.teku.api.schema.SchemaConstants.DESCRIPTION_BYTES32; +import static tech.pegasys.teku.api.schema.SchemaConstants.PATTERN_BYTES32; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.google.common.base.MoreObjects; +import io.swagger.v3.oas.annotations.media.Schema; +import java.util.Objects; +import java.util.Optional; +import org.apache.tuweni.bytes.Bytes32; +import tech.pegasys.teku.api.schema.ExecutionPayloadHeader; +import tech.pegasys.teku.infrastructure.unsigned.UInt64; +import tech.pegasys.teku.spec.datastructures.execution.ExecutionPayloadHeaderSchema; + +public class ExecutionPayloadHeaderEip7732 implements ExecutionPayloadHeader { + + @JsonProperty("parent_block_hash") + @Schema( + type = "string", + format = "byte", + pattern = PATTERN_BYTES32, + description = DESCRIPTION_BYTES32) + public final Bytes32 parentBlockHash; + + @JsonProperty("parent_block_root") + @Schema( + type = "string", + format = "byte", + pattern = PATTERN_BYTES32, + description = DESCRIPTION_BYTES32) + public final Bytes32 parentBlockRoot; + + @JsonProperty("block_hash") + @Schema( + type = "string", + format = "byte", + pattern = PATTERN_BYTES32, + description = DESCRIPTION_BYTES32) + public final Bytes32 blockHash; + + @JsonProperty("gas_limit") + @Schema(type = "string", format = "uint64") + public final UInt64 gasLimit; + + @JsonProperty("builder_index") + @Schema(type = "string", format = "uint64") + public final UInt64 builderIndex; + + @JsonProperty("slot") + @Schema(type = "string", format = "uint64") + public final UInt64 slot; + + @JsonProperty("value") + @Schema(type = "string", format = "uint64") + public final UInt64 value; + + @JsonProperty("blob_kzg_commitments_root") + @Schema( + type = "string", + format = "byte", + pattern = PATTERN_BYTES32, + description = DESCRIPTION_BYTES32) + public final Bytes32 blobKzgCommitmentsRoot; + + @JsonCreator + public ExecutionPayloadHeaderEip7732( + final @JsonProperty("parent_block_hash") Bytes32 parentBlockHash, + final @JsonProperty("parent_block_root") Bytes32 parentBlockRoot, + final @JsonProperty("block_hash") Bytes32 blockHash, + final @JsonProperty("gas_limit") UInt64 gasLimit, + final @JsonProperty("builder_index") UInt64 builderIndex, + final @JsonProperty("slot") UInt64 slot, + final @JsonProperty("value") UInt64 value, + final @JsonProperty("blob_kzg_commitments_root") Bytes32 blobKzgCommitmentsRoot) { + this.parentBlockHash = parentBlockHash; + this.parentBlockRoot = parentBlockRoot; + this.blockHash = blockHash; + this.gasLimit = gasLimit; + this.builderIndex = builderIndex; + this.slot = slot; + this.value = value; + this.blobKzgCommitmentsRoot = blobKzgCommitmentsRoot; + } + + public ExecutionPayloadHeaderEip7732( + tech.pegasys.teku.spec.datastructures.execution.versions.eip7732.ExecutionPayloadHeaderEip7732 + executionPayloadHeader) { + this( + executionPayloadHeader.getParentBlockHash(), + executionPayloadHeader.getParentBlockRoot(), + executionPayloadHeader.getBlockHash(), + executionPayloadHeader.getGasLimit(), + executionPayloadHeader.getBuilderIndex(), + executionPayloadHeader.getSlot(), + executionPayloadHeader.getValue(), + executionPayloadHeader.getBlobKzgCommitmentsRoot()); + } + + @Override + public tech.pegasys.teku.spec.datastructures.execution.ExecutionPayloadHeader + asInternalExecutionPayloadHeader(final ExecutionPayloadHeaderSchema schema) { + return schema.createExecutionPayloadHeader( + payloadBuilder -> + payloadBuilder + .parentBlockHash(() -> parentBlockHash) + .parentBlockRoot(() -> parentBlockRoot) + .blockHash(blockHash) + .gasLimit(gasLimit) + .builderIndex(() -> builderIndex) + .slot(() -> slot) + .value(() -> value) + .blobKzgCommitmentsRoot(() -> blobKzgCommitmentsRoot)); + } + + @Override + public Optional toVersionEip7732() { + return Optional.of(this); + } + + @Override + public boolean equals(final Object object) { + if (this == object) return true; + if (!(object instanceof final ExecutionPayloadHeaderEip7732 that)) return false; + return Objects.equals(parentBlockHash, that.parentBlockHash) + && Objects.equals(parentBlockRoot, that.parentBlockRoot) + && Objects.equals(blockHash, that.blockHash) + && Objects.equals(gasLimit, that.gasLimit) + && Objects.equals(builderIndex, that.builderIndex) + && Objects.equals(slot, that.slot) + && Objects.equals(value, that.value) + && Objects.equals(blobKzgCommitmentsRoot, that.blobKzgCommitmentsRoot); + } + + @Override + public int hashCode() { + return Objects.hash( + parentBlockHash, + parentBlockRoot, + blockHash, + gasLimit, + builderIndex, + slot, + value, + blobKzgCommitmentsRoot); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("parentBlockHash", parentBlockHash) + .add("parentBlockRoot", parentBlockRoot) + .add("blockHash", blockHash) + .add("gasLimit", gasLimit) + .add("builderIndex", builderIndex) + .add("slot", slot) + .add("value", value) + .add("blobKzgCommitmentsRoot", blobKzgCommitmentsRoot) + .toString(); + } +} diff --git a/data/serializer/src/main/java/tech/pegasys/teku/api/schema/eip7732/PayloadAttestation.java b/data/serializer/src/main/java/tech/pegasys/teku/api/schema/eip7732/PayloadAttestation.java new file mode 100644 index 00000000000..4de1369b54f --- /dev/null +++ b/data/serializer/src/main/java/tech/pegasys/teku/api/schema/eip7732/PayloadAttestation.java @@ -0,0 +1,69 @@ +/* + * 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.api.schema.eip7732; + +import static tech.pegasys.teku.api.schema.SchemaConstants.DESCRIPTION_BYTES96; +import static tech.pegasys.teku.api.schema.SchemaConstants.DESCRIPTION_BYTES_SSZ; + +import io.swagger.v3.oas.annotations.media.Schema; +import java.util.Objects; +import org.apache.tuweni.bytes.Bytes; +import tech.pegasys.teku.api.schema.BLSSignature; +import tech.pegasys.teku.spec.SpecVersion; +import tech.pegasys.teku.spec.datastructures.operations.PayloadAttestationSchema; +import tech.pegasys.teku.spec.schemas.SchemaDefinitionsEip7732; + +public class PayloadAttestation { + + @Schema(type = "string", format = "byte", description = DESCRIPTION_BYTES_SSZ) + public final Bytes aggregation_bits; + + public final PayloadAttestationData data; + + @Schema(type = "string", format = "byte", description = DESCRIPTION_BYTES96) + public final BLSSignature signature; + + public PayloadAttestation( + final tech.pegasys.teku.spec.datastructures.operations.PayloadAttestation + payloadAttestation) { + this.aggregation_bits = payloadAttestation.getAggregationBits().sszSerialize(); + this.data = new PayloadAttestationData(payloadAttestation.getData()); + this.signature = new BLSSignature(payloadAttestation.getSignature()); + } + + @Override + public boolean equals(final Object object) { + if (this == object) return true; + if (!(object instanceof final PayloadAttestation that)) return false; + return Objects.equals(aggregation_bits, that.aggregation_bits) + && Objects.equals(data, that.data) + && Objects.equals(signature, that.signature); + } + + public tech.pegasys.teku.spec.datastructures.operations.PayloadAttestation + asInternalPayloadAttestation(final SpecVersion spec) { + final PayloadAttestationSchema payloadAttestationSchema = + SchemaDefinitionsEip7732.required(spec.getSchemaDefinitions()) + .getPayloadAttestationSchema(); + return payloadAttestationSchema.create( + payloadAttestationSchema.getAggregationBitsSchema().sszDeserialize(aggregation_bits), + data.asInternalPayloadAttestationData(), + signature.asInternalBLSSignature()); + } + + @Override + public int hashCode() { + return Objects.hash(aggregation_bits, data, signature); + } +} diff --git a/data/serializer/src/main/java/tech/pegasys/teku/api/schema/eip7732/PayloadAttestationData.java b/data/serializer/src/main/java/tech/pegasys/teku/api/schema/eip7732/PayloadAttestationData.java new file mode 100644 index 00000000000..adeb8157fee --- /dev/null +++ b/data/serializer/src/main/java/tech/pegasys/teku/api/schema/eip7732/PayloadAttestationData.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.api.schema.eip7732; + +import static tech.pegasys.teku.api.schema.SchemaConstants.DESCRIPTION_BYTES32; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; +import java.util.Objects; +import org.apache.tuweni.bytes.Bytes32; +import tech.pegasys.teku.infrastructure.unsigned.UInt64; + +public class PayloadAttestationData { + + @Schema(type = "string", format = "byte", description = DESCRIPTION_BYTES32) + public final Bytes32 beaconBlockRoot; + + @Schema(type = "string", format = "uint64") + public final UInt64 slot; + + @Schema(type = "string", format = "byte") + public final Byte payloadStatus; + + @JsonCreator + public PayloadAttestationData( + @JsonProperty("beacon_block_root") final Bytes32 beaconBlockRoot, + @JsonProperty("slot") final UInt64 slot, + @JsonProperty("index") final Byte payloadStatus) { + this.beaconBlockRoot = beaconBlockRoot; + this.slot = slot; + this.payloadStatus = payloadStatus; + } + + public PayloadAttestationData( + final tech.pegasys.teku.spec.datastructures.operations.PayloadAttestationData data) { + this.beaconBlockRoot = data.getBeaconBlockRoot(); + this.slot = data.getSlot(); + this.payloadStatus = data.getPayloadStatus(); + } + + public tech.pegasys.teku.spec.datastructures.operations.PayloadAttestationData + asInternalPayloadAttestationData() { + return tech.pegasys.teku.spec.datastructures.operations.PayloadAttestationData.SSZ_SCHEMA + .create(beaconBlockRoot, slot, payloadStatus); + } + + @Override + public boolean equals(final Object object) { + if (this == object) return true; + if (!(object instanceof final PayloadAttestationData that)) return false; + return Objects.equals(beaconBlockRoot, that.beaconBlockRoot) + && Objects.equals(slot, that.slot) + && Objects.equals(payloadStatus, that.payloadStatus); + } + + @Override + public int hashCode() { + return Objects.hash(beaconBlockRoot, slot, payloadStatus); + } +} diff --git a/data/serializer/src/main/java/tech/pegasys/teku/api/schema/eip7732/SignedBeaconBlockEip7732.java b/data/serializer/src/main/java/tech/pegasys/teku/api/schema/eip7732/SignedBeaconBlockEip7732.java new file mode 100644 index 00000000000..cd323ecf6ee --- /dev/null +++ b/data/serializer/src/main/java/tech/pegasys/teku/api/schema/eip7732/SignedBeaconBlockEip7732.java @@ -0,0 +1,43 @@ +/* + * Copyright Consensys Software Inc., 2022 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package tech.pegasys.teku.api.schema.eip7732; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; +import tech.pegasys.teku.api.schema.BLSSignature; +import tech.pegasys.teku.api.schema.SignedBeaconBlock; +import tech.pegasys.teku.api.schema.interfaces.SignedBlock; + +public class SignedBeaconBlockEip7732 extends SignedBeaconBlock implements SignedBlock { + private final BeaconBlockEip7732 message; + + public SignedBeaconBlockEip7732( + final tech.pegasys.teku.spec.datastructures.blocks.SignedBeaconBlock internalBlock) { + super(internalBlock); + this.message = new BeaconBlockEip7732(internalBlock.getMessage()); + } + + @Override + public BeaconBlockEip7732 getMessage() { + return message; + } + + @JsonCreator + public SignedBeaconBlockEip7732( + @JsonProperty("message") final BeaconBlockEip7732 message, + @JsonProperty("signature") final BLSSignature signature) { + super(message, signature); + this.message = message; + } +} diff --git a/data/serializer/src/main/java/tech/pegasys/teku/api/schema/eip7732/SignedExecutionPayloadHeader.java b/data/serializer/src/main/java/tech/pegasys/teku/api/schema/eip7732/SignedExecutionPayloadHeader.java new file mode 100644 index 00000000000..a65b1bde18c --- /dev/null +++ b/data/serializer/src/main/java/tech/pegasys/teku/api/schema/eip7732/SignedExecutionPayloadHeader.java @@ -0,0 +1,69 @@ +/* + * 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.api.schema.eip7732; + +import static tech.pegasys.teku.api.schema.SchemaConstants.DESCRIPTION_BYTES96; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; +import tech.pegasys.teku.api.schema.BLSSignature; +import tech.pegasys.teku.spec.SpecVersion; +import tech.pegasys.teku.spec.schemas.SchemaDefinitionsEip7732; + +public class SignedExecutionPayloadHeader { + private final ExecutionPayloadHeaderEip7732 message; + + @Schema(type = "string", format = "byte", description = DESCRIPTION_BYTES96) + private final BLSSignature signature; + + public SignedExecutionPayloadHeader( + final tech.pegasys.teku.spec.datastructures.execution.SignedExecutionPayloadHeader + internalSignedExecutionPayloadHeader) { + this.message = + new ExecutionPayloadHeaderEip7732( + tech.pegasys.teku.spec.datastructures.execution.versions.eip7732 + .ExecutionPayloadHeaderEip7732.required( + internalSignedExecutionPayloadHeader.getMessage())); + this.signature = new BLSSignature(internalSignedExecutionPayloadHeader.getSignature()); + } + + @JsonCreator + public SignedExecutionPayloadHeader( + @JsonProperty("message") final ExecutionPayloadHeaderEip7732 message, + @JsonProperty("signature") final BLSSignature signature) { + this.message = message; + this.signature = signature; + } + + public tech.pegasys.teku.spec.datastructures.execution.SignedExecutionPayloadHeader + asInternalSignedExecutionPayloadHeader(final SpecVersion spec) { + final SchemaDefinitionsEip7732 schemaDefinitions = + SchemaDefinitionsEip7732.required(spec.getSchemaDefinitions()); + return schemaDefinitions + .getSignedExecutionPayloadHeaderSchema() + .create( + message.asInternalExecutionPayloadHeader( + schemaDefinitions.getExecutionPayloadHeaderSchema()), + signature.asInternalBLSSignature()); + } + + public ExecutionPayloadHeaderEip7732 getMessage() { + return message; + } + + public BLSSignature getSignature() { + return signature; + } +} diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/Spec.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/Spec.java index 675a035bfca..4b3407c6dc1 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/Spec.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/Spec.java @@ -68,7 +68,6 @@ import tech.pegasys.teku.spec.datastructures.blocks.blockbody.BeaconBlockBodyBuilder; import tech.pegasys.teku.spec.datastructures.execution.ExecutionPayloadEnvelope; import tech.pegasys.teku.spec.datastructures.execution.ExecutionPayloadHeader; -import tech.pegasys.teku.spec.datastructures.execution.PayloadAttestationData; import tech.pegasys.teku.spec.datastructures.execution.SignedExecutionPayloadHeader; import tech.pegasys.teku.spec.datastructures.execution.versions.capella.Withdrawal; import tech.pegasys.teku.spec.datastructures.execution.versions.eip7732.ExecutionPayloadHeaderEip7732; @@ -81,6 +80,7 @@ import tech.pegasys.teku.spec.datastructures.operations.AttesterSlashing; import tech.pegasys.teku.spec.datastructures.operations.BlsToExecutionChange; import tech.pegasys.teku.spec.datastructures.operations.Deposit; +import tech.pegasys.teku.spec.datastructures.operations.PayloadAttestationData; import tech.pegasys.teku.spec.datastructures.operations.ProposerSlashing; import tech.pegasys.teku.spec.datastructures.operations.SignedBlsToExecutionChange; import tech.pegasys.teku.spec.datastructures.operations.SignedVoluntaryExit; diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/config/SpecConfigLoader.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/config/SpecConfigLoader.java index 683e6491302..3200a314533 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/config/SpecConfigLoader.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/config/SpecConfigLoader.java @@ -32,7 +32,7 @@ public class SpecConfigLoader { private static final Logger LOG = LogManager.getLogger(); private static final List AVAILABLE_PRESETS = - List.of("phase0", "altair", "bellatrix", "capella", "deneb", "electra"); + List.of("phase0", "altair", "bellatrix", "capella", "deneb", "electra", "eip7732"); private static final String CONFIG_PATH = "configs/"; private static final String PRESET_PATH = "presets/"; diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/constants/PayloadStatus.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/constants/PayloadStatus.java index c05a98089e6..c1745fd4cc4 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/constants/PayloadStatus.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/constants/PayloadStatus.java @@ -13,6 +13,8 @@ package tech.pegasys.teku.spec.constants; +import java.util.Arrays; + public enum PayloadStatus { PAYLOAD_ABSENT((byte) 0), PAYLOAD_PRESENT((byte) 1), @@ -28,4 +30,12 @@ public enum PayloadStatus { public byte getCode() { return code; } + + public static PayloadStatus forCode(final byte code) { + return Arrays.stream(PayloadStatus.values()) + .filter(status -> status.code == code) + .findFirst() + .orElseThrow( + () -> new IllegalArgumentException("No PayloadStatus available for code " + code)); + } } diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/blocks/blockbody/BeaconBlockBody.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/blocks/blockbody/BeaconBlockBody.java index 448d37baa90..a0d9cc171dc 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/blocks/blockbody/BeaconBlockBody.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/blocks/blockbody/BeaconBlockBody.java @@ -144,4 +144,8 @@ default Optional toBlindedVersionDeneb() { default Optional toBlindedVersionElectra() { return Optional.empty(); } + + default Optional toBlindedVersionEip7732() { + return Optional.empty(); + } } diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/blocks/blockbody/BeaconBlockBodyBuilder.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/blocks/blockbody/BeaconBlockBodyBuilder.java index 30fcc4a8a46..37808aba119 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/blocks/blockbody/BeaconBlockBodyBuilder.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/blocks/blockbody/BeaconBlockBodyBuilder.java @@ -75,9 +75,17 @@ default Boolean supportsKzgCommitments() { BeaconBlockBodyBuilder blobKzgCommitments(SszList blobKzgCommitments); + default Boolean supportsSignedExecutionPayloadHeader() { + return false; + } + BeaconBlockBodyBuilder signedExecutionPayloadHeader( SignedExecutionPayloadHeader signedExecutionPayloadHeader); + default Boolean supportsPayloadAttestations() { + return false; + } + BeaconBlockBodyBuilder payloadAttestations(SszList payloadAttestations); BeaconBlockBody build(); diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/blocks/blockbody/versions/eip7732/BeaconBlockBodyBuilderEip7732.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/blocks/blockbody/versions/eip7732/BeaconBlockBodyBuilderEip7732.java index 4dde72829bd..29c779fee9f 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/blocks/blockbody/versions/eip7732/BeaconBlockBodyBuilderEip7732.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/blocks/blockbody/versions/eip7732/BeaconBlockBodyBuilderEip7732.java @@ -35,6 +35,11 @@ public BeaconBlockBodyBuilderEip7732( super(schema, null); } + @Override + public Boolean supportsSignedExecutionPayloadHeader() { + return true; + } + @Override public BeaconBlockBodyBuilder signedExecutionPayloadHeader( final SignedExecutionPayloadHeader signedExecutionPayloadHeader) { @@ -42,6 +47,11 @@ public BeaconBlockBodyBuilder signedExecutionPayloadHeader( return this; } + @Override + public Boolean supportsPayloadAttestations() { + return true; + } + @Override public BeaconBlockBodyBuilder payloadAttestations( final SszList payloadAttestations) { diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/blocks/blockbody/versions/eip7732/BeaconBlockBodyEip7732.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/blocks/blockbody/versions/eip7732/BeaconBlockBodyEip7732.java index 384db1227a4..be9cfacd611 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/blocks/blockbody/versions/eip7732/BeaconBlockBodyEip7732.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/blocks/blockbody/versions/eip7732/BeaconBlockBodyEip7732.java @@ -62,4 +62,9 @@ default SszList getBlobKzgCommitments() { default Optional toVersionEip7732() { return Optional.of(this); } + + @Override + default Optional toBlindedVersionEip7732() { + return Optional.of(this); + } } diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/operations/IndexedPayloadAttestation.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/operations/IndexedPayloadAttestation.java index c8602d7594f..c112bbc7ac4 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/operations/IndexedPayloadAttestation.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/operations/IndexedPayloadAttestation.java @@ -17,7 +17,6 @@ import tech.pegasys.teku.infrastructure.ssz.collections.SszUInt64List; import tech.pegasys.teku.infrastructure.ssz.containers.Container3; import tech.pegasys.teku.infrastructure.ssz.tree.TreeNode; -import tech.pegasys.teku.spec.datastructures.execution.PayloadAttestationData; import tech.pegasys.teku.spec.datastructures.type.SszSignature; public class IndexedPayloadAttestation diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/operations/IndexedPayloadAttestationSchema.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/operations/IndexedPayloadAttestationSchema.java index e47d80c2e48..658addd8adb 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/operations/IndexedPayloadAttestationSchema.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/operations/IndexedPayloadAttestationSchema.java @@ -18,7 +18,6 @@ import tech.pegasys.teku.infrastructure.ssz.containers.ContainerSchema3; import tech.pegasys.teku.infrastructure.ssz.schema.collections.SszUInt64ListSchema; import tech.pegasys.teku.infrastructure.ssz.tree.TreeNode; -import tech.pegasys.teku.spec.datastructures.execution.PayloadAttestationData; import tech.pegasys.teku.spec.datastructures.type.SszSignature; import tech.pegasys.teku.spec.datastructures.type.SszSignatureSchema; diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/operations/PayloadAttestation.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/operations/PayloadAttestation.java index 725d3e36591..daf658105ed 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/operations/PayloadAttestation.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/operations/PayloadAttestation.java @@ -17,7 +17,6 @@ import tech.pegasys.teku.infrastructure.ssz.collections.SszBitvector; import tech.pegasys.teku.infrastructure.ssz.containers.Container3; import tech.pegasys.teku.infrastructure.ssz.tree.TreeNode; -import tech.pegasys.teku.spec.datastructures.execution.PayloadAttestationData; import tech.pegasys.teku.spec.datastructures.type.SszSignature; public class PayloadAttestation diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/execution/PayloadAttestationData.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/operations/PayloadAttestationData.java similarity index 97% rename from ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/execution/PayloadAttestationData.java rename to ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/operations/PayloadAttestationData.java index 828428ea8c5..82542f94cba 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/execution/PayloadAttestationData.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/operations/PayloadAttestationData.java @@ -11,7 +11,7 @@ * specific language governing permissions and limitations under the License. */ -package tech.pegasys.teku.spec.datastructures.execution; +package tech.pegasys.teku.spec.datastructures.operations; import org.apache.tuweni.bytes.Bytes32; import tech.pegasys.teku.infrastructure.ssz.containers.Container3; diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/execution/PayloadAttestationDataSchema.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/operations/PayloadAttestationDataSchema.java similarity index 97% rename from ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/execution/PayloadAttestationDataSchema.java rename to ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/operations/PayloadAttestationDataSchema.java index 399d97c0223..67dadc45a57 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/execution/PayloadAttestationDataSchema.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/operations/PayloadAttestationDataSchema.java @@ -11,7 +11,7 @@ * specific language governing permissions and limitations under the License. */ -package tech.pegasys.teku.spec.datastructures.execution; +package tech.pegasys.teku.spec.datastructures.operations; import org.apache.tuweni.bytes.Bytes32; import tech.pegasys.teku.infrastructure.ssz.containers.ContainerSchema3; diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/operations/PayloadAttestationMessage.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/operations/PayloadAttestationMessage.java index 8a3a152ff79..ab151432d5e 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/operations/PayloadAttestationMessage.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/operations/PayloadAttestationMessage.java @@ -18,7 +18,6 @@ import tech.pegasys.teku.infrastructure.ssz.primitive.SszUInt64; import tech.pegasys.teku.infrastructure.ssz.tree.TreeNode; import tech.pegasys.teku.infrastructure.unsigned.UInt64; -import tech.pegasys.teku.spec.datastructures.execution.PayloadAttestationData; import tech.pegasys.teku.spec.datastructures.type.SszSignature; public class PayloadAttestationMessage diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/operations/PayloadAttestationMessageSchema.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/operations/PayloadAttestationMessageSchema.java index 20a2bf88d85..c84bd0c0c30 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/operations/PayloadAttestationMessageSchema.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/operations/PayloadAttestationMessageSchema.java @@ -19,7 +19,6 @@ import tech.pegasys.teku.infrastructure.ssz.schema.SszPrimitiveSchemas; import tech.pegasys.teku.infrastructure.ssz.tree.TreeNode; import tech.pegasys.teku.infrastructure.unsigned.UInt64; -import tech.pegasys.teku.spec.datastructures.execution.PayloadAttestationData; import tech.pegasys.teku.spec.datastructures.type.SszSignature; import tech.pegasys.teku.spec.datastructures.type.SszSignatureSchema; diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/operations/PayloadAttestationSchema.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/operations/PayloadAttestationSchema.java index a83f60dac8a..7a1066160ec 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/operations/PayloadAttestationSchema.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/operations/PayloadAttestationSchema.java @@ -18,7 +18,6 @@ import tech.pegasys.teku.infrastructure.ssz.containers.ContainerSchema3; import tech.pegasys.teku.infrastructure.ssz.schema.collections.SszBitvectorSchema; import tech.pegasys.teku.infrastructure.ssz.tree.TreeNode; -import tech.pegasys.teku.spec.datastructures.execution.PayloadAttestationData; import tech.pegasys.teku.spec.datastructures.type.SszSignature; import tech.pegasys.teku.spec.datastructures.type.SszSignatureSchema; @@ -45,4 +44,8 @@ public PayloadAttestation create( public PayloadAttestation createFromBackingNode(final TreeNode node) { return new PayloadAttestation(this, node); } + + public SszBitvectorSchema getAggregationBitsSchema() { + return (SszBitvectorSchema) getFieldSchema0(); + } } diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/common/util/AttestationUtil.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/common/util/AttestationUtil.java index 218555aafa8..dadedbd6c06 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/common/util/AttestationUtil.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/common/util/AttestationUtil.java @@ -37,11 +37,11 @@ import tech.pegasys.teku.spec.constants.Domain; import tech.pegasys.teku.spec.datastructures.attestation.ValidatableAttestation; import tech.pegasys.teku.spec.datastructures.blocks.BeaconBlockSummary; -import tech.pegasys.teku.spec.datastructures.execution.PayloadAttestationData; import tech.pegasys.teku.spec.datastructures.operations.Attestation; import tech.pegasys.teku.spec.datastructures.operations.AttestationData; import tech.pegasys.teku.spec.datastructures.operations.IndexedAttestation; import tech.pegasys.teku.spec.datastructures.operations.IndexedAttestation.IndexedAttestationSchema; +import tech.pegasys.teku.spec.datastructures.operations.PayloadAttestationData; import tech.pegasys.teku.spec.datastructures.state.Checkpoint; import tech.pegasys.teku.spec.datastructures.state.Fork; import tech.pegasys.teku.spec.datastructures.state.beaconstate.BeaconState; diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/eip7732/block/BlockProcessorEip7732.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/eip7732/block/BlockProcessorEip7732.java index 2db5d37f348..a93d8f7a05e 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/eip7732/block/BlockProcessorEip7732.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/eip7732/block/BlockProcessorEip7732.java @@ -34,11 +34,11 @@ import tech.pegasys.teku.spec.datastructures.blocks.blockbody.BeaconBlockBody; import tech.pegasys.teku.spec.datastructures.blocks.blockbody.versions.eip7732.BeaconBlockBodyEip7732; import tech.pegasys.teku.spec.datastructures.execution.ExecutionPayload; -import tech.pegasys.teku.spec.datastructures.execution.PayloadAttestationData; import tech.pegasys.teku.spec.datastructures.execution.SignedExecutionPayloadHeader; import tech.pegasys.teku.spec.datastructures.execution.versions.eip7732.ExecutionPayloadHeaderEip7732; import tech.pegasys.teku.spec.datastructures.operations.IndexedPayloadAttestation; import tech.pegasys.teku.spec.datastructures.operations.PayloadAttestation; +import tech.pegasys.teku.spec.datastructures.operations.PayloadAttestationData; import tech.pegasys.teku.spec.datastructures.state.Validator; import tech.pegasys.teku.spec.datastructures.state.beaconstate.MutableBeaconState; import tech.pegasys.teku.spec.datastructures.state.beaconstate.versions.eip7732.MutableBeaconStateEip7732; diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/eip7732/util/AttestationUtilEip7732.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/eip7732/util/AttestationUtilEip7732.java index 121bd588fd1..bfa21842f85 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/eip7732/util/AttestationUtilEip7732.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/eip7732/util/AttestationUtilEip7732.java @@ -28,9 +28,9 @@ import tech.pegasys.teku.spec.config.SpecConfig; import tech.pegasys.teku.spec.constants.Domain; import tech.pegasys.teku.spec.constants.PayloadStatus; -import tech.pegasys.teku.spec.datastructures.execution.PayloadAttestationData; import tech.pegasys.teku.spec.datastructures.operations.Attestation; import tech.pegasys.teku.spec.datastructures.operations.IndexedPayloadAttestation; +import tech.pegasys.teku.spec.datastructures.operations.PayloadAttestationData; import tech.pegasys.teku.spec.datastructures.state.beaconstate.BeaconState; import tech.pegasys.teku.spec.logic.common.helpers.BeaconStateAccessors; import tech.pegasys.teku.spec.logic.common.helpers.MiscHelpers; diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/signatures/DeletableSigner.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/signatures/DeletableSigner.java index 4eb4a46823f..cc1b6a96764 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/signatures/DeletableSigner.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/signatures/DeletableSigner.java @@ -25,9 +25,9 @@ import tech.pegasys.teku.infrastructure.unsigned.UInt64; import tech.pegasys.teku.spec.datastructures.blocks.BeaconBlock; import tech.pegasys.teku.spec.datastructures.builder.ValidatorRegistration; -import tech.pegasys.teku.spec.datastructures.execution.PayloadAttestationData; import tech.pegasys.teku.spec.datastructures.operations.AggregateAndProof; import tech.pegasys.teku.spec.datastructures.operations.AttestationData; +import tech.pegasys.teku.spec.datastructures.operations.PayloadAttestationData; import tech.pegasys.teku.spec.datastructures.operations.VoluntaryExit; import tech.pegasys.teku.spec.datastructures.operations.versions.altair.ContributionAndProof; import tech.pegasys.teku.spec.datastructures.operations.versions.altair.SyncAggregatorSelectionData; diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/signatures/LocalSigner.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/signatures/LocalSigner.java index 211d94dee02..8958737f5a2 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/signatures/LocalSigner.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/signatures/LocalSigner.java @@ -27,9 +27,9 @@ import tech.pegasys.teku.spec.Spec; import tech.pegasys.teku.spec.datastructures.blocks.BeaconBlock; import tech.pegasys.teku.spec.datastructures.builder.ValidatorRegistration; -import tech.pegasys.teku.spec.datastructures.execution.PayloadAttestationData; import tech.pegasys.teku.spec.datastructures.operations.AggregateAndProof; import tech.pegasys.teku.spec.datastructures.operations.AttestationData; +import tech.pegasys.teku.spec.datastructures.operations.PayloadAttestationData; import tech.pegasys.teku.spec.datastructures.operations.VoluntaryExit; import tech.pegasys.teku.spec.datastructures.operations.versions.altair.ContributionAndProof; import tech.pegasys.teku.spec.datastructures.operations.versions.altair.SyncAggregatorSelectionData; diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/signatures/Signer.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/signatures/Signer.java index 23fa1e3a5d6..f892ef90c7a 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/signatures/Signer.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/signatures/Signer.java @@ -21,9 +21,9 @@ import tech.pegasys.teku.infrastructure.unsigned.UInt64; import tech.pegasys.teku.spec.datastructures.blocks.BeaconBlock; import tech.pegasys.teku.spec.datastructures.builder.ValidatorRegistration; -import tech.pegasys.teku.spec.datastructures.execution.PayloadAttestationData; import tech.pegasys.teku.spec.datastructures.operations.AggregateAndProof; import tech.pegasys.teku.spec.datastructures.operations.AttestationData; +import tech.pegasys.teku.spec.datastructures.operations.PayloadAttestationData; import tech.pegasys.teku.spec.datastructures.operations.VoluntaryExit; import tech.pegasys.teku.spec.datastructures.operations.versions.altair.ContributionAndProof; import tech.pegasys.teku.spec.datastructures.operations.versions.altair.SyncAggregatorSelectionData; diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/signatures/SigningRootUtil.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/signatures/SigningRootUtil.java index 9f51f6f5493..04e3f5522de 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/signatures/SigningRootUtil.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/signatures/SigningRootUtil.java @@ -22,9 +22,9 @@ import tech.pegasys.teku.spec.datastructures.blocks.BeaconBlock; import tech.pegasys.teku.spec.datastructures.blocks.BeaconBlockHeader; import tech.pegasys.teku.spec.datastructures.builder.ValidatorRegistration; -import tech.pegasys.teku.spec.datastructures.execution.PayloadAttestationData; import tech.pegasys.teku.spec.datastructures.operations.AggregateAndProof; import tech.pegasys.teku.spec.datastructures.operations.AttestationData; +import tech.pegasys.teku.spec.datastructures.operations.PayloadAttestationData; import tech.pegasys.teku.spec.datastructures.operations.VoluntaryExit; import tech.pegasys.teku.spec.datastructures.state.ForkInfo; import tech.pegasys.teku.spec.logic.common.helpers.MiscHelpers; diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/signatures/SlashingProtectedSigner.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/signatures/SlashingProtectedSigner.java index d4180a7eaa5..d92a925a34e 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/signatures/SlashingProtectedSigner.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/signatures/SlashingProtectedSigner.java @@ -24,9 +24,9 @@ import tech.pegasys.teku.infrastructure.unsigned.UInt64; import tech.pegasys.teku.spec.datastructures.blocks.BeaconBlock; import tech.pegasys.teku.spec.datastructures.builder.ValidatorRegistration; -import tech.pegasys.teku.spec.datastructures.execution.PayloadAttestationData; import tech.pegasys.teku.spec.datastructures.operations.AggregateAndProof; import tech.pegasys.teku.spec.datastructures.operations.AttestationData; +import tech.pegasys.teku.spec.datastructures.operations.PayloadAttestationData; import tech.pegasys.teku.spec.datastructures.operations.VoluntaryExit; import tech.pegasys.teku.spec.datastructures.operations.versions.altair.ContributionAndProof; import tech.pegasys.teku.spec.datastructures.operations.versions.altair.SyncAggregatorSelectionData; diff --git a/ethereum/spec/src/main/resources/tech/pegasys/teku/spec/config/configs/swift.yaml b/ethereum/spec/src/main/resources/tech/pegasys/teku/spec/config/configs/swift.yaml index fd76be015b7..6d73fea4039 100644 --- a/ethereum/spec/src/main/resources/tech/pegasys/teku/spec/config/configs/swift.yaml +++ b/ethereum/spec/src/main/resources/tech/pegasys/teku/spec/config/configs/swift.yaml @@ -140,4 +140,7 @@ BLOB_SIDECAR_SUBNET_COUNT: 6 # [New in Electra:EIP7251] MIN_PER_EPOCH_CHURN_LIMIT_ELECTRA: 64000000000 # 2**6 * 10**9 (= 64,000,000,000) -MAX_PER_EPOCH_ACTIVATION_EXIT_CHURN_LIMIT: 128000000000 # 2**7 * 10**9 (= 128,000,000,000) \ No newline at end of file +MAX_PER_EPOCH_ACTIVATION_EXIT_CHURN_LIMIT: 128000000000 # 2**7 * 10**9 (= 128,000,000,000) + +# EIP7732 +MAX_REQUEST_PAYLOADS: 128 \ No newline at end of file diff --git a/ethereum/spec/src/main/resources/tech/pegasys/teku/spec/config/presets/swift/eip7732.yaml b/ethereum/spec/src/main/resources/tech/pegasys/teku/spec/config/presets/swift/eip7732.yaml new file mode 100644 index 00000000000..5aaa69caf5d --- /dev/null +++ b/ethereum/spec/src/main/resources/tech/pegasys/teku/spec/config/presets/swift/eip7732.yaml @@ -0,0 +1,9 @@ +# Minimal preset - EIP7732 + +# Execution +# --------------------------------------------------------------- +# 2**1(= 2) +PTC_SIZE: 2 +# 2**2 (= 4) +MAX_PAYLOAD_ATTESTATIONS: 4 +KZG_COMMITMENT_INCLUSION_PROOF_DEPTH_EIP7732: 13 \ No newline at end of file diff --git a/ethereum/spec/src/test/java/tech/pegasys/teku/spec/config/SpecConfigEip7732Test.java b/ethereum/spec/src/test/java/tech/pegasys/teku/spec/config/SpecConfigEip7732Test.java new file mode 100644 index 00000000000..7e44588ca81 --- /dev/null +++ b/ethereum/spec/src/test/java/tech/pegasys/teku/spec/config/SpecConfigEip7732Test.java @@ -0,0 +1,92 @@ +/* + * 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.config; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.jupiter.api.Test; +import tech.pegasys.teku.spec.Spec; +import tech.pegasys.teku.spec.TestSpecFactory; +import tech.pegasys.teku.spec.util.DataStructureUtil; + +public class SpecConfigEip7732Test { + private final Spec spec = TestSpecFactory.createMinimalElectra(); + + @Test + public void equals_mainnet() { + final SpecConfigEip7732 configA = + SpecConfigLoader.loadConfig("mainnet").toVersionEip7732().orElseThrow(); + final SpecConfigEip7732 configB = + SpecConfigLoader.loadConfig("mainnet").toVersionEip7732().orElseThrow(); + + assertThat(configA).isEqualTo(configB); + assertThat(configA.hashCode()).isEqualTo(configB.hashCode()); + } + + @Test + public void equals_sameRandomValues() { + final SpecConfigElectra specConfigElectra = + SpecConfigLoader.loadConfig("mainnet").toVersionElectra().orElseThrow(); + final SpecConfigEip7732 configA = createRandomEip7732Config(specConfigElectra, 1); + final SpecConfigEip7732 configB = createRandomEip7732Config(specConfigElectra, 1); + + assertThat(configA).isEqualTo(configB); + assertThat(configA.hashCode()).isEqualTo(configB.hashCode()); + } + + @Test + public void equals_differentRandomValues() { + final SpecConfigElectra specConfigElectra = + SpecConfigLoader.loadConfig("mainnet").toVersionElectra().orElseThrow(); + final SpecConfigEip7732 configA = createRandomEip7732Config(specConfigElectra, 1); + final SpecConfigEip7732 configB = createRandomEip7732Config(specConfigElectra, 2); + + assertThat(configA).isNotEqualTo(configB); + assertThat(configA.hashCode()).isNotEqualTo(configB.hashCode()); + } + + @Test + public void equals_electraConfigDiffer() { + final SpecConfigElectra electraA = + SpecConfigLoader.loadConfig("mainnet").toVersionElectra().orElseThrow(); + final SpecConfigElectra electraB = + SpecConfigLoader.loadConfig( + "mainnet", + b -> + b.electraBuilder( + eb -> eb.maxAttestationsElectra(electraA.getMaxAttestationsElectra() + 4))) + .toVersionElectra() + .orElseThrow(); + + final SpecConfigEip7732 configA = createRandomEip7732Config(electraA, 1); + final SpecConfigEip7732 configB = createRandomEip7732Config(electraB, 1); + + assertThat(configA).isNotEqualTo(configB); + assertThat(configA.hashCode()).isNotEqualTo(configB.hashCode()); + } + + private SpecConfigEip7732 createRandomEip7732Config( + final SpecConfigElectra electraConfig, final int seed) { + final DataStructureUtil dataStructureUtil = new DataStructureUtil(seed, spec); + + return new SpecConfigEip7732Impl( + electraConfig, + dataStructureUtil.randomBytes4(), + dataStructureUtil.randomUInt64(999_999), + dataStructureUtil.randomPositiveInt(2), + dataStructureUtil.randomPositiveInt(4), + dataStructureUtil.randomPositiveInt(13), + dataStructureUtil.randomPositiveInt(128)) {}; + } +} diff --git a/ethereum/spec/src/testFixtures/java/tech/pegasys/teku/spec/TestSpecFactory.java b/ethereum/spec/src/testFixtures/java/tech/pegasys/teku/spec/TestSpecFactory.java index cef4c00b035..71134507c37 100644 --- a/ethereum/spec/src/testFixtures/java/tech/pegasys/teku/spec/TestSpecFactory.java +++ b/ethereum/spec/src/testFixtures/java/tech/pegasys/teku/spec/TestSpecFactory.java @@ -179,6 +179,19 @@ public static Spec createMinimalWithElectraForkEpoch(final UInt64 electraForkEpo return create(config, SpecMilestone.ELECTRA); } + /** + * Create a spec that forks to EIP7732 at the provided epoch + * + * @param eip7732ForkEpoch The EIP7732 fork epoch + * @return A spec with EIP7732 enabled, forking to EIP7732 at the given epoch + */ + public static Spec createMinimalWithEip7732ForkEpoch(final UInt64 eip7732ForkEpoch) { + final SpecConfigElectra config = + getEip7732SpecConfig( + Eth2Network.MINIMAL, UInt64.ZERO, UInt64.ZERO, UInt64.ZERO, eip7732ForkEpoch); + return create(config, SpecMilestone.EIP7732); + } + public static Spec createMinimalPhase0() { final SpecConfig specConfig = SpecConfigLoader.loadConfig(Eth2Network.MINIMAL.configName()); return create(specConfig, SpecMilestone.PHASE0); @@ -424,6 +437,24 @@ private static SpecConfigElectra getElectraSpecConfig( })); } + private static SpecConfigElectra getEip7732SpecConfig( + final Eth2Network network, + final UInt64 capellaForkEpoch, + final UInt64 denebForkEpoch, + final UInt64 electraForkEpoch, + final UInt64 eip7732ForkEpoch) { + return getElectraSpecConfig( + network, + builder -> + builder + .altairBuilder(a -> a.altairForkEpoch(UInt64.ZERO)) + .bellatrixBuilder(b -> b.bellatrixForkEpoch(UInt64.ZERO)) + .capellaBuilder(c -> c.capellaForkEpoch(capellaForkEpoch)) + .denebBuilder(d -> d.denebForkEpoch(denebForkEpoch)) + .electraBuilder(e -> e.electraForkEpoch(electraForkEpoch)) + .eip7732Builder(eip7732 -> eip7732.eip7732ForkEpoch(eip7732ForkEpoch))); + } + public static Spec createMinimalWithCapellaDenebAndElectraForkEpoch( final UInt64 capellaForkEpoch, final UInt64 denebForkEpoch, final UInt64 electraForkEpoch) { final SpecConfigBellatrix config = diff --git a/ethereum/spec/src/testFixtures/java/tech/pegasys/teku/spec/generator/signatures/NoOpSigner.java b/ethereum/spec/src/testFixtures/java/tech/pegasys/teku/spec/generator/signatures/NoOpSigner.java index f6655ada198..14bfda4860e 100644 --- a/ethereum/spec/src/testFixtures/java/tech/pegasys/teku/spec/generator/signatures/NoOpSigner.java +++ b/ethereum/spec/src/testFixtures/java/tech/pegasys/teku/spec/generator/signatures/NoOpSigner.java @@ -21,9 +21,9 @@ import tech.pegasys.teku.infrastructure.unsigned.UInt64; import tech.pegasys.teku.spec.datastructures.blocks.BeaconBlock; import tech.pegasys.teku.spec.datastructures.builder.ValidatorRegistration; -import tech.pegasys.teku.spec.datastructures.execution.PayloadAttestationData; import tech.pegasys.teku.spec.datastructures.operations.AggregateAndProof; import tech.pegasys.teku.spec.datastructures.operations.AttestationData; +import tech.pegasys.teku.spec.datastructures.operations.PayloadAttestationData; import tech.pegasys.teku.spec.datastructures.operations.VoluntaryExit; import tech.pegasys.teku.spec.datastructures.operations.versions.altair.ContributionAndProof; import tech.pegasys.teku.spec.datastructures.operations.versions.altair.SyncAggregatorSelectionData; diff --git a/ethereum/spec/src/testFixtures/java/tech/pegasys/teku/spec/util/BeaconStateBuilderEip7732.java b/ethereum/spec/src/testFixtures/java/tech/pegasys/teku/spec/util/BeaconStateBuilderEip7732.java new file mode 100644 index 00000000000..2d06b92488a --- /dev/null +++ b/ethereum/spec/src/testFixtures/java/tech/pegasys/teku/spec/util/BeaconStateBuilderEip7732.java @@ -0,0 +1,194 @@ +/* + * 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.util; + +import static com.google.common.base.Preconditions.checkNotNull; + +import java.util.List; +import org.apache.tuweni.bytes.Bytes32; +import tech.pegasys.teku.infrastructure.ssz.SszList; +import tech.pegasys.teku.infrastructure.ssz.collections.SszUInt64List; +import tech.pegasys.teku.infrastructure.ssz.primitive.SszByte; +import tech.pegasys.teku.infrastructure.unsigned.UInt64; +import tech.pegasys.teku.spec.Spec; +import tech.pegasys.teku.spec.SpecMilestone; +import tech.pegasys.teku.spec.SpecVersion; +import tech.pegasys.teku.spec.config.SpecConfigElectra; +import tech.pegasys.teku.spec.datastructures.execution.ExecutionPayloadHeader; +import tech.pegasys.teku.spec.datastructures.state.SyncCommittee; +import tech.pegasys.teku.spec.datastructures.state.beaconstate.versions.eip7732.BeaconStateEip7732; +import tech.pegasys.teku.spec.datastructures.state.beaconstate.versions.eip7732.BeaconStateSchemaEip7732; +import tech.pegasys.teku.spec.datastructures.state.beaconstate.versions.eip7732.MutableBeaconStateEip7732; +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 BeaconStateBuilderEip7732 + extends AbstractBeaconStateBuilder< + BeaconStateEip7732, MutableBeaconStateEip7732, BeaconStateBuilderEip7732> { + private UInt64 nextWithdrawalIndex; + private UInt64 nextWithdrawalValidatorIndex; + + private SszList previousEpochParticipation; + private SszList currentEpochParticipation; + private SszUInt64List inactivityScores; + private SyncCommittee currentSyncCommittee; + private SyncCommittee nextSyncCommittee; + private ExecutionPayloadHeader latestExecutionPayloadHeader; + + private UInt64 depositRequestsStartIndex; + private UInt64 depositBalanceToConsume; + private UInt64 exitBalanceToConsume; + private UInt64 earliestExitEpoch; + + private UInt64 consolidationBalanceToConsume; + + private UInt64 earliestConsolidationEpoch; + + private SszList pendingBalanceDeposits; + private SszList pendingPartialWithdrawals; + private SszList pendingConsolidations; + + private Bytes32 latestBlockHash; + private UInt64 latestFullSlot; + private Bytes32 latestWithdrawalsRoot; + + protected BeaconStateBuilderEip7732( + final SpecVersion spec, + final DataStructureUtil dataStructureUtil, + final int defaultValidatorCount, + final int defaultItemsInSSZLists) { + super(spec, dataStructureUtil, defaultValidatorCount, defaultItemsInSSZLists); + } + + @Override + protected BeaconStateEip7732 getEmptyState() { + return BeaconStateSchemaEip7732.create(spec.getConfig()).createEmpty(); + } + + @Override + protected void setUniqueFields(final MutableBeaconStateEip7732 state) { + state.setPreviousEpochParticipation(previousEpochParticipation); + state.setCurrentEpochParticipation(currentEpochParticipation); + state.setInactivityScores(inactivityScores); + state.setCurrentSyncCommittee(currentSyncCommittee); + state.setNextSyncCommittee(nextSyncCommittee); + state.setLatestExecutionPayloadHeader(latestExecutionPayloadHeader); + state.setNextWithdrawalIndex(nextWithdrawalIndex); + state.setNextWithdrawalValidatorIndex(nextWithdrawalValidatorIndex); + state.setDepositRequestsStartIndex(depositRequestsStartIndex); + state.setDepositBalanceToConsume(depositBalanceToConsume); + state.setExitBalanceToConsume(exitBalanceToConsume); + state.setEarliestExitEpoch(earliestExitEpoch); + state.setConsolidationBalanceToConsume(consolidationBalanceToConsume); + state.setEarliestConsolidationEpoch(earliestConsolidationEpoch); + state.setPendingBalanceDeposits(pendingBalanceDeposits); + state.setPendingPartialWithdrawals(pendingPartialWithdrawals); + state.setPendingConsolidations(pendingConsolidations); + state.setLatestBlockHash(latestBlockHash); + state.setLatestFullSlot(latestFullSlot); + state.setLatestWithdrawalsRoot(latestWithdrawalsRoot); + } + + public static BeaconStateBuilderEip7732 create( + final DataStructureUtil dataStructureUtil, + final Spec spec, + final int defaultValidatorCount, + final int defaultItemsInSSZLists) { + return new BeaconStateBuilderEip7732( + spec.forMilestone(SpecMilestone.EIP7732), + dataStructureUtil, + defaultValidatorCount, + defaultItemsInSSZLists); + } + + public BeaconStateBuilderEip7732 nextWithdrawalIndex(final UInt64 nextWithdrawalIndex) { + checkNotNull(nextWithdrawalIndex); + this.nextWithdrawalIndex = nextWithdrawalIndex; + return this; + } + + public BeaconStateBuilderEip7732 nextWithdrawalValidatorIndex( + final UInt64 nextWithdrawalValidatorIndex) { + checkNotNull(nextWithdrawalValidatorIndex); + this.nextWithdrawalValidatorIndex = nextWithdrawalValidatorIndex; + return this; + } + + public BeaconStateBuilderEip7732 depositRequestsStartIndex( + final UInt64 depositRequestsStartIndex) { + checkNotNull(depositRequestsStartIndex); + this.depositRequestsStartIndex = depositRequestsStartIndex; + return this; + } + + public BeaconStateBuilderEip7732 depositBalanceToConsume(final UInt64 depositBalanceToConsume) { + checkNotNull(depositBalanceToConsume); + this.depositBalanceToConsume = depositBalanceToConsume; + return this; + } + + private BeaconStateSchemaEip7732 getBeaconStateSchema() { + return (BeaconStateSchemaEip7732) spec.getSchemaDefinitions().getBeaconStateSchema(); + } + + @Override + protected void initDefaults() { + super.initDefaults(); + + final BeaconStateSchemaEip7732 schema = getBeaconStateSchema(); + + previousEpochParticipation = + dataStructureUtil.randomSszList( + schema.getPreviousEpochParticipationSchema(), + defaultValidatorCount, + dataStructureUtil::randomSszByte); + currentEpochParticipation = + dataStructureUtil.randomSszList( + schema.getCurrentEpochParticipationSchema(), + defaultValidatorCount, + dataStructureUtil::randomSszByte); + inactivityScores = + dataStructureUtil.randomSszUInt64List( + schema.getInactivityScoresSchema(), defaultItemsInSSZLists); + currentSyncCommittee = dataStructureUtil.randomSyncCommittee(); + nextSyncCommittee = dataStructureUtil.randomSyncCommittee(); + latestExecutionPayloadHeader = + dataStructureUtil.randomExecutionPayloadHeader( + dataStructureUtil.getSpec().forMilestone(SpecMilestone.EIP7732)); + + this.nextWithdrawalIndex = UInt64.ZERO; + this.nextWithdrawalValidatorIndex = + defaultValidatorCount > 0 + ? dataStructureUtil.randomUInt64(defaultValidatorCount) + : UInt64.ZERO; + + this.depositRequestsStartIndex = SpecConfigElectra.UNSET_DEPOSIT_REQUESTS_START_INDEX; + this.depositBalanceToConsume = UInt64.ZERO; + this.exitBalanceToConsume = UInt64.ZERO; + this.earliestExitEpoch = UInt64.ZERO; + this.consolidationBalanceToConsume = UInt64.ZERO; + this.earliestConsolidationEpoch = UInt64.ZERO; + this.pendingBalanceDeposits = + schema.getPendingBalanceDepositsSchema().createFromElements(List.of()); + this.pendingPartialWithdrawals = + schema.getPendingPartialWithdrawalsSchema().createFromElements(List.of()); + this.pendingConsolidations = + schema.getPendingConsolidationsSchema().createFromElements(List.of()); + + this.latestBlockHash = Bytes32.ZERO; + this.latestFullSlot = UInt64.ZERO; + this.latestWithdrawalsRoot = Bytes32.ZERO; + } +} diff --git a/ethereum/spec/src/testFixtures/java/tech/pegasys/teku/spec/util/DataStructureUtil.java b/ethereum/spec/src/testFixtures/java/tech/pegasys/teku/spec/util/DataStructureUtil.java index f1a745ab2d7..857b7968daf 100644 --- a/ethereum/spec/src/testFixtures/java/tech/pegasys/teku/spec/util/DataStructureUtil.java +++ b/ethereum/spec/src/testFixtures/java/tech/pegasys/teku/spec/util/DataStructureUtil.java @@ -84,7 +84,9 @@ 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.SpecConfigEip7732; import tech.pegasys.teku.spec.constants.Domain; +import tech.pegasys.teku.spec.constants.PayloadStatus; import tech.pegasys.teku.spec.datastructures.blobs.versions.deneb.Blob; import tech.pegasys.teku.spec.datastructures.blobs.versions.deneb.BlobKzgCommitmentsSchema; import tech.pegasys.teku.spec.datastructures.blobs.versions.deneb.BlobSchema; @@ -107,6 +109,7 @@ import tech.pegasys.teku.spec.datastructures.blocks.blockbody.versions.capella.BeaconBlockBodySchemaCapella; import tech.pegasys.teku.spec.datastructures.blocks.blockbody.versions.deneb.BeaconBlockBodyDeneb; import tech.pegasys.teku.spec.datastructures.blocks.blockbody.versions.deneb.BeaconBlockBodySchemaDeneb; +import tech.pegasys.teku.spec.datastructures.blocks.blockbody.versions.eip7732.BeaconBlockBodySchemaEip7732; import tech.pegasys.teku.spec.datastructures.blocks.versions.deneb.BlockContents; import tech.pegasys.teku.spec.datastructures.blocks.versions.deneb.SignedBlockContents; import tech.pegasys.teku.spec.datastructures.builder.BlobsBundleSchema; @@ -123,6 +126,7 @@ import tech.pegasys.teku.spec.datastructures.execution.ExecutionPayloadBuilder; import tech.pegasys.teku.spec.datastructures.execution.ExecutionPayloadContext; import tech.pegasys.teku.spec.datastructures.execution.ExecutionPayloadHeader; +import tech.pegasys.teku.spec.datastructures.execution.SignedExecutionPayloadHeader; import tech.pegasys.teku.spec.datastructures.execution.Transaction; import tech.pegasys.teku.spec.datastructures.execution.TransactionSchema; import tech.pegasys.teku.spec.datastructures.execution.versions.capella.Withdrawal; @@ -151,6 +155,8 @@ import tech.pegasys.teku.spec.datastructures.operations.DepositWithIndex; import tech.pegasys.teku.spec.datastructures.operations.IndexedAttestation; import tech.pegasys.teku.spec.datastructures.operations.IndexedAttestation.IndexedAttestationSchema; +import tech.pegasys.teku.spec.datastructures.operations.PayloadAttestation; +import tech.pegasys.teku.spec.datastructures.operations.PayloadAttestationData; import tech.pegasys.teku.spec.datastructures.operations.ProposerSlashing; import tech.pegasys.teku.spec.datastructures.operations.SignedAggregateAndProof; import tech.pegasys.teku.spec.datastructures.operations.SignedBlsToExecutionChange; @@ -192,6 +198,7 @@ import tech.pegasys.teku.spec.schemas.SchemaDefinitionsBellatrix; import tech.pegasys.teku.spec.schemas.SchemaDefinitionsCapella; import tech.pegasys.teku.spec.schemas.SchemaDefinitionsDeneb; +import tech.pegasys.teku.spec.schemas.SchemaDefinitionsEip7732; import tech.pegasys.teku.spec.schemas.SchemaDefinitionsElectra; public final class DataStructureUtil { @@ -401,6 +408,10 @@ public SszBitvector randomCommitteeBitvector() { return randomSszBitvector(getMaxCommitteesPerSlot()); } + public SszBitvector randomPtcBitVector() { + return randomSszBitvector(getPtcSize()); + } + public SszBitvector randomSszBitvector(final int n) { Random random = new Random(nextSeed()); int[] bits = IntStream.range(0, n).sequential().filter(__ -> random.nextBoolean()).toArray(); @@ -600,7 +611,13 @@ public ExecutionPayloadHeader randomExecutionPayloadHeader( .excessBlobGas(this::randomUInt64) .depositRequestsRoot(this::randomBytes32) .withdrawalRequestsRoot(this::randomBytes32) - .consolidationRequestsRoot(this::randomBytes32)); + .consolidationRequestsRoot(this::randomBytes32) + .parentBlockHash(this::randomBytes32) + .parentBlockRoot(this::randomBytes32) + .builderIndex(this::randomUInt64) + .slot(this::randomSlot) + .value(this::randomUInt64) + .blobKzgCommitmentsRoot(this::randomBytes32)); } public ExecutionPayloadHeader randomExecutionPayloadHeader(final SpecVersion specVersion) { @@ -1430,6 +1447,17 @@ public BeaconBlockBody randomBeaconBlockBody( if (builder.supportsKzgCommitments()) { builder.blobKzgCommitments(randomBlobKzgCommitments()); } + if (builder.supportsSignedExecutionPayloadHeader()) { + builder.signedExecutionPayloadHeader(randomSignedExecutionPayloadHeader()); + } + if (builder.supportsPayloadAttestations()) { + builder.payloadAttestations( + randomSszList( + BeaconBlockBodySchemaEip7732.required(schema) + .getPayloadAttestationsSchema(), + this::randomPayloadAttestation, + 3)); + } builderModifier.accept(builder); return SafeFuture.COMPLETE; }) @@ -1857,7 +1885,7 @@ public BeaconState randomBeaconState( case CAPELLA -> stateBuilderCapella(validatorCount, numItemsInSszLists); case DENEB -> stateBuilderDeneb(validatorCount, numItemsInSszLists); case ELECTRA -> stateBuilderElectra(validatorCount, numItemsInSszLists); - case EIP7732 -> throw new UnsupportedOperationException("EIP7732 TODO"); + case EIP7732 -> stateBuilderEip7732(validatorCount, numItemsInSszLists); }; } @@ -1908,6 +1936,12 @@ public BeaconStateBuilderElectra stateBuilderElectra( this, spec, defaultValidatorCount, defaultItemsInSSZLists); } + public BeaconStateBuilderEip7732 stateBuilderEip7732( + final int defaultValidatorCount, final int defaultItemsInSSZLists) { + return BeaconStateBuilderEip7732.create( + this, spec, defaultValidatorCount, defaultItemsInSSZLists); + } + public BeaconState randomBeaconState(final UInt64 slot) { return randomBeaconState().updated(state -> state.setSlot(slot)); } @@ -2528,6 +2562,28 @@ public PendingPartialWithdrawal randomPendingPartialWithdrawal() { SszUInt64.of(randomUInt64())); } + public SignedExecutionPayloadHeader randomSignedExecutionPayloadHeader() { + return getEip7732SchemaDefinitions(randomSlot()) + .getSignedExecutionPayloadHeaderSchema() + .create( + randomExecutionPayloadHeader(getSpec().forMilestone(SpecMilestone.EIP7732)), + randomSignature()); + } + + public PayloadAttestation randomPayloadAttestation() { + return getEip7732SchemaDefinitions(randomSlot()) + .getPayloadAttestationSchema() + .create( + randomPtcBitVector(), + PayloadAttestationData.SSZ_SCHEMA.create( + randomBytes32(), randomSlot(), randomPayloadStatus().getCode()), + randomSignature()); + } + + public PayloadStatus randomPayloadStatus() { + return PayloadStatus.values()[randomInt(0, PayloadStatus.values().length)]; + } + public UInt64 randomBlobSidecarIndex() { return randomUInt64(spec.getMaxBlobsPerBlock().orElseThrow()); } @@ -2565,6 +2621,10 @@ private SchemaDefinitionsElectra getElectraSchemaDefinitions(final UInt64 slot) return SchemaDefinitionsElectra.required(spec.atSlot(slot).getSchemaDefinitions()); } + private SchemaDefinitionsEip7732 getEip7732SchemaDefinitions(final UInt64 slot) { + return SchemaDefinitionsEip7732.required(spec.atSlot(slot).getSchemaDefinitions()); + } + int getEpochsPerEth1VotingPeriod() { return getConstant(SpecConfig::getEpochsPerEth1VotingPeriod); } @@ -2593,6 +2653,10 @@ private UInt64 getMaxEffectiveBalance() { return getConstant(SpecConfig::getMaxEffectiveBalance); } + private int getPtcSize() { + return getConstant(specConfig -> SpecConfigEip7732.required(specConfig).getPtcSize()); + } + private Bytes32 computeDepositDomain() { final SpecVersion genesisSpec = spec.getGenesisSpec(); final Bytes4 domain = Domain.DEPOSIT; diff --git a/ethereum/statetransition/src/main/java/tech/pegasys/teku/statetransition/validation/PayloadAttestationValidator.java b/ethereum/statetransition/src/main/java/tech/pegasys/teku/statetransition/validation/PayloadAttestationValidator.java index 49a85c2ead7..89e7ac250fb 100644 --- a/ethereum/statetransition/src/main/java/tech/pegasys/teku/statetransition/validation/PayloadAttestationValidator.java +++ b/ethereum/statetransition/src/main/java/tech/pegasys/teku/statetransition/validation/PayloadAttestationValidator.java @@ -29,7 +29,7 @@ import tech.pegasys.teku.spec.Spec; import tech.pegasys.teku.spec.constants.Domain; import tech.pegasys.teku.spec.constants.PayloadStatus; -import tech.pegasys.teku.spec.datastructures.execution.PayloadAttestationData; +import tech.pegasys.teku.spec.datastructures.operations.PayloadAttestationData; import tech.pegasys.teku.spec.datastructures.operations.PayloadAttestationMessage; import tech.pegasys.teku.spec.datastructures.state.Validator; import tech.pegasys.teku.spec.datastructures.state.beaconstate.BeaconState; diff --git a/networking/eth2/src/integration-test/java/tech/pegasys/teku/networking/eth2/AbstractRpcMethodIntegrationTest.java b/networking/eth2/src/integration-test/java/tech/pegasys/teku/networking/eth2/AbstractRpcMethodIntegrationTest.java index ad2c9cf070d..7c65360c7ba 100644 --- a/networking/eth2/src/integration-test/java/tech/pegasys/teku/networking/eth2/AbstractRpcMethodIntegrationTest.java +++ b/networking/eth2/src/integration-test/java/tech/pegasys/teku/networking/eth2/AbstractRpcMethodIntegrationTest.java @@ -35,6 +35,7 @@ import tech.pegasys.teku.spec.datastructures.blocks.blockbody.versions.bellatrix.BeaconBlockBodyBellatrix; import tech.pegasys.teku.spec.datastructures.blocks.blockbody.versions.capella.BeaconBlockBodyCapella; import tech.pegasys.teku.spec.datastructures.blocks.blockbody.versions.deneb.BeaconBlockBodyDeneb; +import tech.pegasys.teku.spec.datastructures.blocks.blockbody.versions.eip7732.BeaconBlockBodyEip7732; import tech.pegasys.teku.spec.datastructures.blocks.blockbody.versions.electra.BeaconBlockBodyElectra; import tech.pegasys.teku.spec.datastructures.blocks.blockbody.versions.phase0.BeaconBlockBodyPhase0; import tech.pegasys.teku.storage.storageSystem.InMemoryStorageSystemBuilder; @@ -84,8 +85,13 @@ private void setUpNextSpec(final SpecMilestone nextSpecMilestone) { checkState(nextSpecMilestone.equals(SpecMilestone.ELECTRA), "next spec should be electra"); nextSpec = Optional.of(TestSpecFactory.createMinimalWithElectraForkEpoch(nextSpecEpoch)); } - case ELECTRA -> throw new RuntimeException("Base spec is already latest supported milestone"); - case EIP7732 -> throw new UnsupportedOperationException("EIP7732 TODO"); + case ELECTRA -> { + checkState(nextSpecMilestone.equals(SpecMilestone.EIP7732), "next spec should be eip7732"); + nextSpec = Optional.of(TestSpecFactory.createMinimalWithEip7732ForkEpoch(nextSpecEpoch)); + } + case EIP7732 -> + throw new UnsupportedOperationException( + "Base spec is already latest supported milestone"); } nextSpecSlot = nextSpec.orElseThrow().computeStartSlotAtEpoch(nextSpecEpoch); } @@ -263,7 +269,7 @@ protected static Class milestoneToBeaconBlockBodyClass(final SpecMilestone mi case CAPELLA -> BeaconBlockBodyCapella.class; case DENEB -> BeaconBlockBodyDeneb.class; case ELECTRA -> BeaconBlockBodyElectra.class; - case EIP7732 -> throw new UnsupportedOperationException("EIP7732 TODO"); + case EIP7732 -> BeaconBlockBodyEip7732.class; }; } } diff --git a/networking/eth2/src/main/java/tech/pegasys/teku/networking/eth2/rpc/beaconchain/BeaconChainMethods.java b/networking/eth2/src/main/java/tech/pegasys/teku/networking/eth2/rpc/beaconchain/BeaconChainMethods.java index 5797f152249..739d768cfec 100644 --- a/networking/eth2/src/main/java/tech/pegasys/teku/networking/eth2/rpc/beaconchain/BeaconChainMethods.java +++ b/networking/eth2/src/main/java/tech/pegasys/teku/networking/eth2/rpc/beaconchain/BeaconChainMethods.java @@ -376,7 +376,7 @@ private static Eth2RpcMethod createGoodBye( final RpcContextCodec forkDigestContextCodec = RpcContextCodec.forkDigest( - spec, recentChainData, ForkDigestPayloadContext.EXECUTION_PAYLOAD_ENVELOPE); + spec, recentChainData, ForkDigestPayloadContext.executionPayloadEnvelope(spec)); final ExecutionPayloadEnvelopesByRootMessageHandler executionPayloadEnvelopesByRootMessageHandler = diff --git a/networking/eth2/src/main/java/tech/pegasys/teku/networking/eth2/rpc/core/encodings/context/ForkDigestPayloadContext.java b/networking/eth2/src/main/java/tech/pegasys/teku/networking/eth2/rpc/core/encodings/context/ForkDigestPayloadContext.java index 88b404c688e..33bf7ae8d1e 100644 --- a/networking/eth2/src/main/java/tech/pegasys/teku/networking/eth2/rpc/core/encodings/context/ForkDigestPayloadContext.java +++ b/networking/eth2/src/main/java/tech/pegasys/teku/networking/eth2/rpc/core/encodings/context/ForkDigestPayloadContext.java @@ -16,6 +16,7 @@ import tech.pegasys.teku.infrastructure.ssz.SszData; import tech.pegasys.teku.infrastructure.ssz.schema.SszSchema; import tech.pegasys.teku.infrastructure.unsigned.UInt64; +import tech.pegasys.teku.spec.Spec; import tech.pegasys.teku.spec.datastructures.blobs.versions.deneb.BlobSidecar; import tech.pegasys.teku.spec.datastructures.blocks.SignedBeaconBlock; import tech.pegasys.teku.spec.datastructures.execution.SignedExecutionPayloadEnvelope; @@ -51,23 +52,30 @@ public SszSchema getSchemaFromSchemaDefinitions( } }; - ForkDigestPayloadContext EXECUTION_PAYLOAD_ENVELOPE = - new ForkDigestPayloadContext<>() { - // EIP7732 TODO: not sure here - @Override - public UInt64 getSlotFromPayload(final SignedExecutionPayloadEnvelope responsePayload) { - return UInt64.ZERO; - } + static ForkDigestPayloadContext executionPayloadEnvelope( + final Spec spec) { + return new ForkDigestPayloadContext<>() { + @Override + public UInt64 getSlotFromPayload(final SignedExecutionPayloadEnvelope responsePayload) { + // used only for the fork digest, so no need to be accurate (there is no slot field in the + // ExecutionPayload) + final UInt64 epoch = + spec.getForkSchedule() + .getFork(responsePayload.getMessage().getPayload().getMilestone()) + .getEpoch(); + return spec.computeStartSlotAtEpoch(epoch); + } - @Override - public SszSchema getSchemaFromSchemaDefinitions( - final SchemaDefinitions schemaDefinitions) { - return schemaDefinitions - .toVersionEip7732() - .orElseThrow() - .getSignedExecutionPayloadEnvelopeSchema(); - } - }; + @Override + public SszSchema getSchemaFromSchemaDefinitions( + final SchemaDefinitions schemaDefinitions) { + return schemaDefinitions + .toVersionEip7732() + .orElseThrow() + .getSignedExecutionPayloadEnvelopeSchema(); + } + }; + } UInt64 getSlotFromPayload(final TPayload responsePayload); diff --git a/validator/api/src/main/java/tech/pegasys/teku/validator/api/ValidatorApiChannel.java b/validator/api/src/main/java/tech/pegasys/teku/validator/api/ValidatorApiChannel.java index 0d4bc82cb40..ff758a52fcb 100644 --- a/validator/api/src/main/java/tech/pegasys/teku/validator/api/ValidatorApiChannel.java +++ b/validator/api/src/main/java/tech/pegasys/teku/validator/api/ValidatorApiChannel.java @@ -38,11 +38,11 @@ import tech.pegasys.teku.infrastructure.unsigned.UInt64; import tech.pegasys.teku.spec.datastructures.blocks.SignedBlockContainer; import tech.pegasys.teku.spec.datastructures.builder.SignedValidatorRegistration; -import tech.pegasys.teku.spec.datastructures.execution.PayloadAttestationData; import tech.pegasys.teku.spec.datastructures.genesis.GenesisData; import tech.pegasys.teku.spec.datastructures.metadata.BlockContainerAndMetaData; import tech.pegasys.teku.spec.datastructures.operations.Attestation; import tech.pegasys.teku.spec.datastructures.operations.AttestationData; +import tech.pegasys.teku.spec.datastructures.operations.PayloadAttestationData; import tech.pegasys.teku.spec.datastructures.operations.PayloadAttestationMessage; import tech.pegasys.teku.spec.datastructures.operations.SignedAggregateAndProof; import tech.pegasys.teku.spec.datastructures.operations.versions.altair.SignedContributionAndProof; diff --git a/validator/beaconnode/src/main/java/tech/pegasys/teku/validator/beaconnode/metrics/MetricRecordingValidatorApiChannel.java b/validator/beaconnode/src/main/java/tech/pegasys/teku/validator/beaconnode/metrics/MetricRecordingValidatorApiChannel.java index 7fc587c9edb..e12e49d4d1b 100644 --- a/validator/beaconnode/src/main/java/tech/pegasys/teku/validator/beaconnode/metrics/MetricRecordingValidatorApiChannel.java +++ b/validator/beaconnode/src/main/java/tech/pegasys/teku/validator/beaconnode/metrics/MetricRecordingValidatorApiChannel.java @@ -47,11 +47,11 @@ import tech.pegasys.teku.infrastructure.unsigned.UInt64; import tech.pegasys.teku.spec.datastructures.blocks.SignedBlockContainer; import tech.pegasys.teku.spec.datastructures.builder.SignedValidatorRegistration; -import tech.pegasys.teku.spec.datastructures.execution.PayloadAttestationData; import tech.pegasys.teku.spec.datastructures.genesis.GenesisData; import tech.pegasys.teku.spec.datastructures.metadata.BlockContainerAndMetaData; import tech.pegasys.teku.spec.datastructures.operations.Attestation; import tech.pegasys.teku.spec.datastructures.operations.AttestationData; +import tech.pegasys.teku.spec.datastructures.operations.PayloadAttestationData; import tech.pegasys.teku.spec.datastructures.operations.PayloadAttestationMessage; import tech.pegasys.teku.spec.datastructures.operations.SignedAggregateAndProof; import tech.pegasys.teku.spec.datastructures.operations.versions.altair.SignedContributionAndProof; diff --git a/validator/client/src/main/java/tech/pegasys/teku/validator/client/duties/attestations/PayloadAttestationDuty.java b/validator/client/src/main/java/tech/pegasys/teku/validator/client/duties/attestations/PayloadAttestationDuty.java index 86f599b7967..60a941b633f 100644 --- a/validator/client/src/main/java/tech/pegasys/teku/validator/client/duties/attestations/PayloadAttestationDuty.java +++ b/validator/client/src/main/java/tech/pegasys/teku/validator/client/duties/attestations/PayloadAttestationDuty.java @@ -28,7 +28,7 @@ import tech.pegasys.teku.infrastructure.metrics.Validator.ValidatorDutyMetricsSteps; import tech.pegasys.teku.infrastructure.unsigned.UInt64; import tech.pegasys.teku.spec.Spec; -import tech.pegasys.teku.spec.datastructures.execution.PayloadAttestationData; +import tech.pegasys.teku.spec.datastructures.operations.PayloadAttestationData; import tech.pegasys.teku.spec.datastructures.operations.PayloadAttestationMessage; import tech.pegasys.teku.spec.datastructures.operations.PayloadAttestationMessageSchema; import tech.pegasys.teku.spec.datastructures.state.ForkInfo; diff --git a/validator/client/src/main/java/tech/pegasys/teku/validator/client/signer/ExternalSigner.java b/validator/client/src/main/java/tech/pegasys/teku/validator/client/signer/ExternalSigner.java index b1f46e95f39..23c344e0a07 100644 --- a/validator/client/src/main/java/tech/pegasys/teku/validator/client/signer/ExternalSigner.java +++ b/validator/client/src/main/java/tech/pegasys/teku/validator/client/signer/ExternalSigner.java @@ -48,9 +48,9 @@ import tech.pegasys.teku.spec.Spec; import tech.pegasys.teku.spec.datastructures.blocks.BeaconBlock; import tech.pegasys.teku.spec.datastructures.builder.ValidatorRegistration; -import tech.pegasys.teku.spec.datastructures.execution.PayloadAttestationData; import tech.pegasys.teku.spec.datastructures.operations.AggregateAndProof; import tech.pegasys.teku.spec.datastructures.operations.AttestationData; +import tech.pegasys.teku.spec.datastructures.operations.PayloadAttestationData; import tech.pegasys.teku.spec.datastructures.operations.VoluntaryExit; import tech.pegasys.teku.spec.datastructures.operations.versions.altair.ContributionAndProof; import tech.pegasys.teku.spec.datastructures.operations.versions.altair.SyncAggregatorSelectionData; diff --git a/validator/remote/src/main/java/tech/pegasys/teku/validator/remote/FailoverValidatorApiHandler.java b/validator/remote/src/main/java/tech/pegasys/teku/validator/remote/FailoverValidatorApiHandler.java index ede442d128e..8de5f0befaa 100644 --- a/validator/remote/src/main/java/tech/pegasys/teku/validator/remote/FailoverValidatorApiHandler.java +++ b/validator/remote/src/main/java/tech/pegasys/teku/validator/remote/FailoverValidatorApiHandler.java @@ -49,11 +49,11 @@ import tech.pegasys.teku.spec.datastructures.blocks.BlockContainer; import tech.pegasys.teku.spec.datastructures.blocks.SignedBlockContainer; import tech.pegasys.teku.spec.datastructures.builder.SignedValidatorRegistration; -import tech.pegasys.teku.spec.datastructures.execution.PayloadAttestationData; import tech.pegasys.teku.spec.datastructures.genesis.GenesisData; import tech.pegasys.teku.spec.datastructures.metadata.BlockContainerAndMetaData; import tech.pegasys.teku.spec.datastructures.operations.Attestation; import tech.pegasys.teku.spec.datastructures.operations.AttestationData; +import tech.pegasys.teku.spec.datastructures.operations.PayloadAttestationData; import tech.pegasys.teku.spec.datastructures.operations.PayloadAttestationMessage; import tech.pegasys.teku.spec.datastructures.operations.SignedAggregateAndProof; import tech.pegasys.teku.spec.datastructures.operations.versions.altair.SignedContributionAndProof; diff --git a/validator/remote/src/main/java/tech/pegasys/teku/validator/remote/RemoteValidatorApiHandler.java b/validator/remote/src/main/java/tech/pegasys/teku/validator/remote/RemoteValidatorApiHandler.java index b0546421ce5..5c29b436d28 100644 --- a/validator/remote/src/main/java/tech/pegasys/teku/validator/remote/RemoteValidatorApiHandler.java +++ b/validator/remote/src/main/java/tech/pegasys/teku/validator/remote/RemoteValidatorApiHandler.java @@ -55,12 +55,12 @@ import tech.pegasys.teku.spec.Spec; import tech.pegasys.teku.spec.datastructures.blocks.SignedBlockContainer; import tech.pegasys.teku.spec.datastructures.builder.SignedValidatorRegistration; -import tech.pegasys.teku.spec.datastructures.execution.PayloadAttestationData; import tech.pegasys.teku.spec.datastructures.genesis.GenesisData; import tech.pegasys.teku.spec.datastructures.metadata.BlockContainerAndMetaData; import tech.pegasys.teku.spec.datastructures.metadata.ObjectAndMetaData; import tech.pegasys.teku.spec.datastructures.operations.Attestation; import tech.pegasys.teku.spec.datastructures.operations.AttestationData; +import tech.pegasys.teku.spec.datastructures.operations.PayloadAttestationData; import tech.pegasys.teku.spec.datastructures.operations.PayloadAttestationMessage; import tech.pegasys.teku.spec.datastructures.operations.SignedAggregateAndProof; import tech.pegasys.teku.spec.datastructures.operations.versions.altair.SignedContributionAndProof; diff --git a/validator/remote/src/main/java/tech/pegasys/teku/validator/remote/sentry/SentryValidatorApiChannel.java b/validator/remote/src/main/java/tech/pegasys/teku/validator/remote/sentry/SentryValidatorApiChannel.java index e28eee59def..efa1c55bfad 100644 --- a/validator/remote/src/main/java/tech/pegasys/teku/validator/remote/sentry/SentryValidatorApiChannel.java +++ b/validator/remote/src/main/java/tech/pegasys/teku/validator/remote/sentry/SentryValidatorApiChannel.java @@ -37,11 +37,11 @@ import tech.pegasys.teku.infrastructure.unsigned.UInt64; import tech.pegasys.teku.spec.datastructures.blocks.SignedBlockContainer; import tech.pegasys.teku.spec.datastructures.builder.SignedValidatorRegistration; -import tech.pegasys.teku.spec.datastructures.execution.PayloadAttestationData; import tech.pegasys.teku.spec.datastructures.genesis.GenesisData; import tech.pegasys.teku.spec.datastructures.metadata.BlockContainerAndMetaData; import tech.pegasys.teku.spec.datastructures.operations.Attestation; import tech.pegasys.teku.spec.datastructures.operations.AttestationData; +import tech.pegasys.teku.spec.datastructures.operations.PayloadAttestationData; import tech.pegasys.teku.spec.datastructures.operations.PayloadAttestationMessage; import tech.pegasys.teku.spec.datastructures.operations.SignedAggregateAndProof; import tech.pegasys.teku.spec.datastructures.operations.versions.altair.SignedContributionAndProof;