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 1c9d7edc31a..6fb57967995 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 @@ -18,8 +18,9 @@ import tech.pegasys.teku.spec.datastructures.blocks.blockbody.BeaconBlockBody; import tech.pegasys.teku.spec.datastructures.blocks.blockbody.versions.electra.BeaconBlockBodyElectra; import tech.pegasys.teku.spec.datastructures.execution.ExecutionPayload; +import tech.pegasys.teku.spec.datastructures.execution.ExecutionPayloadSummary; import tech.pegasys.teku.spec.datastructures.execution.SignedExecutionPayloadHeader; -import tech.pegasys.teku.spec.datastructures.execution.versions.electra.ExecutionPayloadElectra; +import tech.pegasys.teku.spec.datastructures.execution.versions.eip7732.ExecutionPayloadEip7732; import tech.pegasys.teku.spec.datastructures.operations.PayloadAttestation; import tech.pegasys.teku.spec.datastructures.type.SszKZGCommitment; @@ -44,6 +45,11 @@ default Optional getOptionalExecutionPayload() { return Optional.empty(); } + @Override + default Optional getOptionalExecutionPayloadSummary() { + return Optional.empty(); + } + @Override default Optional> getOptionalBlobKzgCommitments() { return Optional.empty(); @@ -60,7 +66,7 @@ default Optional> getOptionalPayloadAttestations() { } @Override - default ExecutionPayloadElectra getExecutionPayload() { + default ExecutionPayloadEip7732 getExecutionPayload() { throw new UnsupportedOperationException("ExecutionPayload removed in Eip7732"); } diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/execution/ExpectedWithdrawals.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/execution/ExpectedWithdrawals.java index 128c4e76bbf..830c1a8da96 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/execution/ExpectedWithdrawals.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/execution/ExpectedWithdrawals.java @@ -287,6 +287,13 @@ void processWithdrawalsUnchecked( final SszList expectedWithdrawals = getExpectedWithdrawalsSszList(schemaDefinitionsCapella); + // new in ePBS + genericState + .toMutableVersionEip7732() + .ifPresent( + genericStateEip7732 -> + genericStateEip7732.setLatestWithdrawalsRoot(expectedWithdrawals.hashTreeRoot())); + for (int i = 0; i < expectedWithdrawals.size(); i++) { final Withdrawal withdrawal = expectedWithdrawals.get(i); beaconStateMutators.decreaseBalance( diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/eip7732/forktransition/Eip7732StateUpgrade.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/eip7732/forktransition/Eip7732StateUpgrade.java index 98e9b03d74f..eeae1c60f1d 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/eip7732/forktransition/Eip7732StateUpgrade.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/eip7732/forktransition/Eip7732StateUpgrade.java @@ -138,7 +138,7 @@ public BeaconStateEip7732 upgrade(final BeaconState preState) { state.setLatestBlockHash( preStateElectra.getLatestExecutionPayloadHeader().getBlockHash()); - state.setLatestFullSlot(UInt64.ZERO); + state.setLatestFullSlot(preState.getSlot()); state.setLatestWithdrawalsRoot(Bytes32.ZERO); }); } diff --git a/ethereum/statetransition/src/main/java/tech/pegasys/teku/statetransition/blobs/BlockBlobSidecarsTracker.java b/ethereum/statetransition/src/main/java/tech/pegasys/teku/statetransition/blobs/BlockBlobSidecarsTracker.java index 78e1fd5db92..4a40a138659 100644 --- a/ethereum/statetransition/src/main/java/tech/pegasys/teku/statetransition/blobs/BlockBlobSidecarsTracker.java +++ b/ethereum/statetransition/src/main/java/tech/pegasys/teku/statetransition/blobs/BlockBlobSidecarsTracker.java @@ -30,6 +30,7 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import tech.pegasys.teku.infrastructure.async.SafeFuture; +import tech.pegasys.teku.infrastructure.ssz.SszList; import tech.pegasys.teku.infrastructure.unsigned.UInt64; import tech.pegasys.teku.spec.datastructures.blobs.versions.deneb.BlobSidecar; import tech.pegasys.teku.spec.datastructures.blocks.SignedBeaconBlock; @@ -109,7 +110,7 @@ public Optional getBlobSidecar(final UInt64 index) { } public Stream getMissingBlobSidecars() { - final Optional blockCommitmentsCount = getBlockKzgCommitmentsCount(); + final Optional blockCommitmentsCount = getBlobKzgCommitmentsCount(); if (blockCommitmentsCount.isPresent()) { return UInt64.range(UInt64.ZERO, UInt64.valueOf(blockCommitmentsCount.get())) .filter(blobIndex -> !blobSidecars.containsKey(blobIndex)) @@ -127,7 +128,7 @@ public Stream getMissingBlobSidecars() { } public Stream getUnusedBlobSidecarsForBlock() { - final Optional blockCommitmentsCount = getBlockKzgCommitmentsCount(); + final Optional blockCommitmentsCount = getBlobKzgCommitmentsCount(); checkState(blockCommitmentsCount.isPresent(), "Block must me known to call this method"); final UInt64 firstUnusedIndex = UInt64.valueOf(blockCommitmentsCount.get()); @@ -231,12 +232,12 @@ private void checkCompletion() { } private void pruneExcessiveBlobSidecars() { - getBlockKzgCommitmentsCount() + getBlobKzgCommitmentsCount() .ifPresent(count -> blobSidecars.tailMap(UInt64.valueOf(count), true).clear()); } private boolean isExcessiveBlobSidecar(final BlobSidecar blobSidecar) { - return getBlockKzgCommitmentsCount() + return getBlobKzgCommitmentsCount() .map(count -> blobSidecar.getIndex().isGreaterThanOrEqualTo(count)) .orElse(false); } @@ -256,17 +257,17 @@ public void setFetchTriggered() { } private boolean areBlobsComplete() { - return getBlockKzgCommitmentsCount().map(count -> blobSidecars.size() >= count).orElse(false); + return getBlobKzgCommitmentsCount().map(count -> blobSidecars.size() >= count).orElse(false); } - private Optional getBlockKzgCommitmentsCount() { + private Optional getBlobKzgCommitmentsCount() { return block .get() - .map( + .flatMap( b -> BeaconBlockBodyDeneb.required(b.getMessage().getBody()) - .getBlobKzgCommitments() - .size()); + .getOptionalBlobKzgCommitments() + .map(SszList::size)); } /** diff --git a/ethereum/statetransition/src/main/java/tech/pegasys/teku/statetransition/validation/ExecutionPayloadValidator.java b/ethereum/statetransition/src/main/java/tech/pegasys/teku/statetransition/validation/ExecutionPayloadValidator.java index e5e80bbe13d..e41cc6e67ff 100644 --- a/ethereum/statetransition/src/main/java/tech/pegasys/teku/statetransition/validation/ExecutionPayloadValidator.java +++ b/ethereum/statetransition/src/main/java/tech/pegasys/teku/statetransition/validation/ExecutionPayloadValidator.java @@ -26,7 +26,6 @@ import tech.pegasys.teku.infrastructure.unsigned.UInt64; import tech.pegasys.teku.spec.Spec; import tech.pegasys.teku.spec.constants.Domain; -import tech.pegasys.teku.spec.datastructures.blocks.SignedBeaconBlock; import tech.pegasys.teku.spec.datastructures.execution.ExecutionPayloadEnvelope; import tech.pegasys.teku.spec.datastructures.execution.SignedExecutionPayloadEnvelope; import tech.pegasys.teku.spec.datastructures.execution.versions.eip7732.ExecutionPayloadEip7732; @@ -34,16 +33,13 @@ import tech.pegasys.teku.spec.datastructures.state.Validator; import tech.pegasys.teku.spec.datastructures.state.beaconstate.BeaconState; import tech.pegasys.teku.spec.datastructures.state.beaconstate.versions.eip7732.BeaconStateEip7732; -import tech.pegasys.teku.statetransition.block.ReceivedBlockEventsChannel; import tech.pegasys.teku.storage.client.RecentChainData; -public class ExecutionPayloadValidator implements ReceivedBlockEventsChannel { +public class ExecutionPayloadValidator { private final Spec spec; private final RecentChainData recentChainData; - private final Set seenBlockRootInfoSet = - LimitedSet.createSynchronized(VALID_BLOCK_SET_SIZE); private final Set receivedValidEnvelopeInfoSet = LimitedSet.createSynchronized(VALID_BLOCK_SET_SIZE); @@ -58,7 +54,7 @@ public SafeFuture validate( /* * [IGNORE] The envelope's block root envelope.block_root has been seen (via both gossip and non-gossip sources) (a client MAY queue payload for processing once the block is retrieved). */ - if (seenBlockRootInfoSet.add(envelope.getBeaconBlockRoot())) { + if (!recentChainData.containsBlock(envelope.getBeaconBlockRoot())) { return SafeFuture.completedFuture(InternalValidationResult.IGNORE); } /* @@ -138,15 +134,5 @@ private boolean verifyBuilderSignature( return BLS.verify(publicKey, signingRoot, signedExecutionPayloadEnvelope.getSignature()); } - @Override - public void onBlockValidated(final SignedBeaconBlock block) { - seenBlockRootInfoSet.add(block.getRoot()); - } - - @Override - public void onBlockImported(final SignedBeaconBlock block, final boolean executionOptimistic) { - // NO-OP - } - record BlockRootAndBuilderIndex(Bytes32 blockRoot, UInt64 builderIndex) {} } diff --git a/services/beaconchain/src/main/java/tech/pegasys/teku/services/beaconchain/BeaconChainController.java b/services/beaconchain/src/main/java/tech/pegasys/teku/services/beaconchain/BeaconChainController.java index b3ddac30903..e8876031ed8 100644 --- a/services/beaconchain/src/main/java/tech/pegasys/teku/services/beaconchain/BeaconChainController.java +++ b/services/beaconchain/src/main/java/tech/pegasys/teku/services/beaconchain/BeaconChainController.java @@ -1340,7 +1340,6 @@ public void initExecutionPayloadManager() { executionPayloadManager = new ExecutionPayloadManager( executionPayloadValidator, forkChoice, recentChainData, executionLayer); - eventChannels.subscribe(ReceivedBlockEventsChannel.class, executionPayloadValidator); } public void initPayloadAttestationManager() { diff --git a/validator/client/src/main/java/tech/pegasys/teku/validator/client/duties/BlockProductionDuty.java b/validator/client/src/main/java/tech/pegasys/teku/validator/client/duties/BlockProductionDuty.java index 5da90c79336..3eda389bf96 100644 --- a/validator/client/src/main/java/tech/pegasys/teku/validator/client/duties/BlockProductionDuty.java +++ b/validator/client/src/main/java/tech/pegasys/teku/validator/client/duties/BlockProductionDuty.java @@ -116,7 +116,9 @@ private SafeFuture produceBlock(final ForkInfo forkInfo) { .thenCompose( signedBlockContainer -> validatorDutyMetrics.record( - () -> sendBlock(signedBlockContainer), this, ValidatorDutyMetricsSteps.SEND)) + () -> sendBlock(signedBlockContainer, milestone), + this, + ValidatorDutyMetricsSteps.SEND)) .thenCompose( dutyResult -> { if (milestone.isGreaterThanOrEqualTo(SpecMilestone.EIP7732)) { @@ -202,9 +204,16 @@ private SafeFuture signBlockContainer( return blockContainerSigner.sign(blockContainer, validator, forkInfo); } - private SafeFuture sendBlock(final SignedBlockContainer signedBlockContainer) { + private SafeFuture sendBlock( + final SignedBlockContainer signedBlockContainer, final SpecMilestone milestone) { return validatorApiChannel - .sendSignedBlock(signedBlockContainer, BroadcastValidationLevel.GOSSIP) + .sendSignedBlock( + signedBlockContainer, + // EIP7732 TODO: need to make sure block is imported for ePBS (at least for the "naive" + // flow) + milestone.isGreaterThanOrEqualTo(SpecMilestone.EIP7732) + ? BroadcastValidationLevel.CONSENSUS + : BroadcastValidationLevel.GOSSIP) .thenApply( result -> { if (result.isPublished()) {