From 24c942b66ed43b4dbad4c76f2eb0015c6dab6ff9 Mon Sep 17 00:00:00 2001 From: Anton Nashatyrev Date: Tue, 28 Sep 2021 11:42:33 +0300 Subject: [PATCH] [Merge] Adopt some recent Merge spec PRs (#4408) * Replace consts in all configs with TERMINAL_TOTAL_DIFFICULTY * Remove TransitionStore and targetSecondsToMerge, minAnchorPowBlockDifficulty constants * Adopt merge PR https://github.com/ethereum/consensus-specs/pull/2522/files * Adopt merge PR https://github.com/ethereum/consensus-specs/pull/2595 --- .../java/tech/pegasys/teku/spec/Spec.java | 9 +- .../teku/spec/config/SpecConfigBuilder.java | 21 +-- .../teku/spec/config/SpecConfigMerge.java | 23 +-- .../forkchoice/MemTransitionStore.java | 30 ---- .../forkchoice/TransitionStore.java | 24 --- .../teku/spec/logic/DelegatingSpecLogic.java | 14 -- .../pegasys/teku/spec/logic/SpecLogic.java | 7 - .../teku/spec/logic/StateTransition.java | 1 - .../helpers/MergeTransitionHelpers.java | 16 +- .../spec/logic/common/helpers/PowBlock.java | 15 +- .../logic/common/util/ForkChoiceUtil.java | 33 ++-- .../versions/altair/SpecLogicAltair.java | 14 -- .../logic/versions/merge/SpecLogicMerge.java | 41 +---- .../forktransition/TransitionStoreUtil.java | 52 ------ .../versions/phase0/SpecLogicPhase0.java | 14 -- .../config/invalid/invalidPreset_unknown.yaml | 8 +- .../invalid/invalidPreset_wrongType.yaml | 8 +- .../invalid/multifile_dupFields/config.yaml | 8 +- .../teku/spec/config/standard/mainnet.yaml | 8 +- .../teku/spec/config/standard/minimal.yaml | 8 +- .../teku/cli/subcommand/test-spec.yaml | 6 +- .../teku/util/config/ConstantsReader.java | 3 +- .../teku/util/config/configs/mainnet.yaml | 8 +- .../teku/util/config/configs/minimal.yaml | 8 +- .../teku/util/config/configs/prater.yaml | 8 +- .../teku/util/config/configs/pyrmont.yaml | 8 +- .../config/invalid/invalidPresetType.yaml | 8 +- .../util/config/invalid/unknownPreset.yaml | 8 +- .../validator/coordinator/BlockFactory.java | 148 ++++++++++-------- 29 files changed, 180 insertions(+), 379 deletions(-) delete mode 100644 ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/forkchoice/MemTransitionStore.java delete mode 100644 ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/forkchoice/TransitionStore.java delete mode 100644 ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/merge/forktransition/TransitionStoreUtil.java 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 329ecf46cbe..cfce9505b21 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 @@ -43,7 +43,6 @@ import tech.pegasys.teku.spec.datastructures.forkchoice.MutableStore; import tech.pegasys.teku.spec.datastructures.forkchoice.ReadOnlyForkChoiceStrategy; import tech.pegasys.teku.spec.datastructures.forkchoice.ReadOnlyStore; -import tech.pegasys.teku.spec.datastructures.forkchoice.TransitionStore; import tech.pegasys.teku.spec.datastructures.operations.Attestation; import tech.pegasys.teku.spec.datastructures.operations.AttestationData; import tech.pegasys.teku.spec.datastructures.operations.AttesterSlashing; @@ -481,16 +480,10 @@ public BlockImportResult onBlock( final BeaconState blockSlotState, final IndexedAttestationCache indexedAttestationCache) { SpecVersion specVersion = atBlock(signedBlock); - Optional maybeTransitionStore = specVersion.getTransitionStore(); return specVersion .getForkChoiceUtil() .onBlock( - executionEngineChannel, - store, - signedBlock, - blockSlotState, - indexedAttestationCache, - maybeTransitionStore); + executionEngineChannel, store, signedBlock, blockSlotState, indexedAttestationCache); } public boolean blockDescendsFromLatestFinalizedBlock( diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/config/SpecConfigBuilder.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/config/SpecConfigBuilder.java index 6a4695aa86a..da37640b920 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/config/SpecConfigBuilder.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/config/SpecConfigBuilder.java @@ -679,25 +679,19 @@ public class MergeBuilder { private UInt64 mergeForkEpoch; // Transition - private UInt64 targetSecondsToMerge; - private UInt256 minAnchorPowBlockDifficulty; + private UInt256 terminalTotalDifficulty; private MergeBuilder() {} SpecConfigMerge build(final SpecConfigAltair specConfig) { return new SpecConfigMerge( - specConfig, - mergeForkVersion, - mergeForkEpoch, - targetSecondsToMerge, - minAnchorPowBlockDifficulty); + specConfig, mergeForkVersion, mergeForkEpoch, terminalTotalDifficulty); } void validate() { validateConstant("mergeForkVersion", mergeForkVersion); validateConstant("mergeForkEpoch", mergeForkEpoch); - validateConstant("targetSecondsToMerge", targetSecondsToMerge); - validateConstant("minAnchorPowBlockDifficulty", minAnchorPowBlockDifficulty); + validateConstant("terminalTotalDifficulty", terminalTotalDifficulty); } public MergeBuilder mergeForkVersion(Bytes4 mergeForkVersion) { @@ -712,13 +706,8 @@ public MergeBuilder mergeForkEpoch(UInt64 mergeForkEpoch) { return this; } - public MergeBuilder targetSecondsToMerge(UInt64 targetSecondsToMerge) { - this.targetSecondsToMerge = targetSecondsToMerge; - return this; - } - - public MergeBuilder minAnchorPowBlockDifficulty(UInt256 minAnchorPowBlockDifficulty) { - this.minAnchorPowBlockDifficulty = minAnchorPowBlockDifficulty; + public MergeBuilder terminalTotalDifficulty(UInt256 terminalTotalDifficulty) { + this.terminalTotalDifficulty = terminalTotalDifficulty; return this; } } diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/config/SpecConfigMerge.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/config/SpecConfigMerge.java index 825afb96422..76111f7a284 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/config/SpecConfigMerge.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/config/SpecConfigMerge.java @@ -27,20 +27,17 @@ public class SpecConfigMerge extends DelegatingSpecConfigAltair { private final UInt64 mergeForkEpoch; // Transition - private final UInt64 targetSecondsToMerge; - private final UInt256 minAnchorPowBlockDifficulty; + private final UInt256 terminalTotalDifficulty; public SpecConfigMerge( SpecConfigAltair specConfig, Bytes4 mergeForkVersion, UInt64 mergeForkEpoch, - UInt64 targetSecondsToMerge, - UInt256 minAnchorPowBlockDifficulty) { + UInt256 terminalTotalDifficulty) { super(specConfig); this.mergeForkVersion = mergeForkVersion; this.mergeForkEpoch = mergeForkEpoch; - this.targetSecondsToMerge = targetSecondsToMerge; - this.minAnchorPowBlockDifficulty = minAnchorPowBlockDifficulty; + this.terminalTotalDifficulty = terminalTotalDifficulty; } public static SpecConfigMerge required(final SpecConfig specConfig) { @@ -73,12 +70,8 @@ public UInt64 getMergeForkEpoch() { return mergeForkEpoch; } - public UInt64 getTargetSecondsToMerge() { - return targetSecondsToMerge; - } - - public UInt256 getMinAnchorPowBlockDifficulty() { - return minAnchorPowBlockDifficulty; + public UInt256 getTerminalTotalDifficulty() { + return terminalTotalDifficulty; } @Override @@ -97,13 +90,11 @@ public boolean equals(Object o) { SpecConfigMerge that = (SpecConfigMerge) o; return Objects.equals(mergeForkVersion, that.mergeForkVersion) && Objects.equals(mergeForkEpoch, that.mergeForkEpoch) - && Objects.equals(targetSecondsToMerge, that.targetSecondsToMerge) - && Objects.equals(minAnchorPowBlockDifficulty, that.minAnchorPowBlockDifficulty); + && Objects.equals(terminalTotalDifficulty, that.terminalTotalDifficulty); } @Override public int hashCode() { - return Objects.hash( - mergeForkVersion, mergeForkEpoch, targetSecondsToMerge, minAnchorPowBlockDifficulty); + return Objects.hash(mergeForkVersion, mergeForkEpoch, terminalTotalDifficulty); } } diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/forkchoice/MemTransitionStore.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/forkchoice/MemTransitionStore.java deleted file mode 100644 index 04694b3b795..00000000000 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/forkchoice/MemTransitionStore.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 2021 ConsenSys AG. - * - * 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.datastructures.forkchoice; - -import org.apache.tuweni.units.bigints.UInt256; - -public class MemTransitionStore implements TransitionStore { - - private final UInt256 transitionTotalDifficulty; - - public MemTransitionStore(UInt256 transitionTotalDifficulty) { - this.transitionTotalDifficulty = transitionTotalDifficulty; - } - - @Override - public UInt256 getTransitionTotalDifficulty() { - return transitionTotalDifficulty; - } -} diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/forkchoice/TransitionStore.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/forkchoice/TransitionStore.java deleted file mode 100644 index 4c13d026371..00000000000 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/forkchoice/TransitionStore.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright 2021 ConsenSys AG. - * - * 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.datastructures.forkchoice; - -import org.apache.tuweni.units.bigints.UInt256; - -public interface TransitionStore { - UInt256 getTransitionTotalDifficulty(); - - static TransitionStore create(UInt256 transitionTotalDifficulty) { - return new MemTransitionStore(transitionTotalDifficulty); - } -} diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/DelegatingSpecLogic.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/DelegatingSpecLogic.java index 6b4597e47d9..633efa1d4f0 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/DelegatingSpecLogic.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/DelegatingSpecLogic.java @@ -14,9 +14,6 @@ package tech.pegasys.teku.spec.logic; import java.util.Optional; -import tech.pegasys.teku.spec.datastructures.forkchoice.TransitionStore; -import tech.pegasys.teku.spec.datastructures.state.beaconstate.BeaconState; -import tech.pegasys.teku.spec.executionengine.ExecutionEngineChannel; import tech.pegasys.teku.spec.logic.common.block.BlockProcessor; import tech.pegasys.teku.spec.logic.common.forktransition.StateUpgrade; import tech.pegasys.teku.spec.logic.common.helpers.BeaconStateAccessors; @@ -48,12 +45,6 @@ public Optional> getStateUpgrade() { return specLogic.getStateUpgrade(); } - @Override - public void initializeTransitionStore( - ExecutionEngineChannel executionEngineChannel, BeaconState state) { - specLogic.initializeTransitionStore(executionEngineChannel, state); - } - @Override public ValidatorsUtil getValidatorsUtil() { return specLogic.getValidatorsUtil(); @@ -134,11 +125,6 @@ public Optional getMergeTransitionHelpers() { return specLogic.getMergeTransitionHelpers(); } - @Override - public Optional getTransitionStore() { - return specLogic.getTransitionStore(); - } - @Override public OperationSignatureVerifier operationSignatureVerifier() { return specLogic.operationSignatureVerifier(); diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/SpecLogic.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/SpecLogic.java index 6543058a9bc..b72ea960d91 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/SpecLogic.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/SpecLogic.java @@ -14,9 +14,6 @@ package tech.pegasys.teku.spec.logic; import java.util.Optional; -import tech.pegasys.teku.spec.datastructures.forkchoice.TransitionStore; -import tech.pegasys.teku.spec.datastructures.state.beaconstate.BeaconState; -import tech.pegasys.teku.spec.executionengine.ExecutionEngineChannel; import tech.pegasys.teku.spec.logic.common.block.BlockProcessor; import tech.pegasys.teku.spec.logic.common.forktransition.StateUpgrade; import tech.pegasys.teku.spec.logic.common.helpers.BeaconStateAccessors; @@ -39,8 +36,6 @@ public interface SpecLogic { Optional> getStateUpgrade(); - void initializeTransitionStore(ExecutionEngineChannel executionEngineChannel, BeaconState state); - ValidatorsUtil getValidatorsUtil(); BeaconStateUtil getBeaconStateUtil(); @@ -74,6 +69,4 @@ public interface SpecLogic { Optional getExecutionPayloadUtil(); Optional getMergeTransitionHelpers(); - - Optional getTransitionStore(); } diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/StateTransition.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/StateTransition.java index a186e881724..a340e3f8e1f 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/StateTransition.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/StateTransition.java @@ -75,7 +75,6 @@ public BeaconState processSlots( .orElse(prevMilestoneState); // Update spec currentSpec = newSpec; - newSpec.initializeTransitionStore(executionEngineChannel, state); } } } diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/common/helpers/MergeTransitionHelpers.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/common/helpers/MergeTransitionHelpers.java index c291355dc16..5eb16523d50 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/common/helpers/MergeTransitionHelpers.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/common/helpers/MergeTransitionHelpers.java @@ -15,8 +15,8 @@ import org.apache.tuweni.bytes.Bytes32; import org.apache.tuweni.units.bigints.UInt256; +import tech.pegasys.teku.spec.config.SpecConfigMerge; import tech.pegasys.teku.spec.datastructures.blocks.BeaconBlock; -import tech.pegasys.teku.spec.datastructures.forkchoice.TransitionStore; import tech.pegasys.teku.spec.datastructures.state.beaconstate.BeaconState; import tech.pegasys.teku.spec.executionengine.ExecutionEngineChannel; import tech.pegasys.teku.spec.logic.versions.merge.helpers.MiscHelpersMerge; @@ -24,9 +24,11 @@ public class MergeTransitionHelpers { private final MiscHelpersMerge miscHelpers; + private final SpecConfigMerge specConfig; - public MergeTransitionHelpers(MiscHelpersMerge miscHelpers) { + public MergeTransitionHelpers(MiscHelpersMerge miscHelpers, SpecConfigMerge specConfig) { this.miscHelpers = miscHelpers; + this.specConfig = specConfig; } public boolean isMergeComplete(BeaconState state) { @@ -37,10 +39,12 @@ public boolean isMergeBlock(BeaconState state, BeaconBlock block) { return miscHelpers.isMergeBlock(state, block); } - public boolean isValidTerminalPowBlock(PowBlock powBlock, TransitionStore transitionStore) { + public boolean isValidTerminalPowBlock(PowBlock powBlock, PowBlock parentPowBlock) { boolean isTotalDifficultyReached = - powBlock.totalDifficulty.compareTo(transitionStore.getTransitionTotalDifficulty()) >= 0; - return powBlock.isValid && isTotalDifficultyReached; + powBlock.totalDifficulty.compareTo(specConfig.getTerminalTotalDifficulty()) >= 0; + boolean isParentTotalDifficultyValid = + parentPowBlock.totalDifficulty.compareTo(specConfig.getTerminalTotalDifficulty()) < 0; + return isTotalDifficultyReached && isParentTotalDifficultyValid; } public PowBlock getPowBlock(ExecutionEngineChannel executionEngineChannel, Bytes32 blockHash) { @@ -48,7 +52,7 @@ public PowBlock getPowBlock(ExecutionEngineChannel executionEngineChannel, Bytes .getPowBlock(blockHash) .join() .map(PowBlock::new) - .orElse(new PowBlock(blockHash, false, false, UInt256.ZERO, UInt256.ZERO)); + .orElse(new PowBlock(blockHash, Bytes32.ZERO, UInt256.ZERO, UInt256.ZERO)); } public PowBlock getPowChainHead(ExecutionEngineChannel executionEngineChannel) { diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/common/helpers/PowBlock.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/common/helpers/PowBlock.java index ec00d0864db..bea67835762 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/common/helpers/PowBlock.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/common/helpers/PowBlock.java @@ -20,20 +20,14 @@ public class PowBlock { public final Bytes32 blockHash; - public final boolean isProcessed; - public final boolean isValid; + public final Bytes32 parentHash; public final UInt256 totalDifficulty; public final UInt256 difficulty; public PowBlock( - Bytes32 blockHash, - boolean isProcessed, - boolean isValid, - UInt256 totalDifficulty, - UInt256 difficulty) { + Bytes32 blockHash, Bytes32 parentHash, UInt256 totalDifficulty, UInt256 difficulty) { this.blockHash = blockHash; - this.isProcessed = isProcessed; - this.isValid = isValid; + this.parentHash = parentHash; this.totalDifficulty = totalDifficulty; this.difficulty = difficulty; } @@ -41,8 +35,7 @@ public PowBlock( PowBlock(EthBlock.Block block) { this( Bytes32.fromHexString(block.getHash()), - true, - true, + Bytes32.fromHexString(block.getParentHash()), UInt256.valueOf(block.getTotalDifficulty()), UInt256.valueOf(block.getDifficulty())); } diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/common/util/ForkChoiceUtil.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/common/util/ForkChoiceUtil.java index 91c4f1419a5..0a0611f867e 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/common/util/ForkChoiceUtil.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/common/util/ForkChoiceUtil.java @@ -31,7 +31,6 @@ import tech.pegasys.teku.spec.datastructures.forkchoice.MutableStore; import tech.pegasys.teku.spec.datastructures.forkchoice.ReadOnlyForkChoiceStrategy; import tech.pegasys.teku.spec.datastructures.forkchoice.ReadOnlyStore; -import tech.pegasys.teku.spec.datastructures.forkchoice.TransitionStore; import tech.pegasys.teku.spec.datastructures.operations.Attestation; import tech.pegasys.teku.spec.datastructures.operations.AttestationData; import tech.pegasys.teku.spec.datastructures.state.Checkpoint; @@ -333,8 +332,7 @@ public BlockImportResult onBlock( final MutableStore store, final SignedBeaconBlock signedBlock, final BeaconState blockSlotState, - final IndexedAttestationCache indexedAttestationCache, - final Optional maybeTransitionStore) { + final IndexedAttestationCache indexedAttestationCache) { checkArgument( blockSlotState.getSlot().equals(signedBlock.getSlot()), "State must have slots processed up to the block slot"); @@ -347,14 +345,6 @@ public BlockImportResult onBlock( return maybeFailure.get(); } - // [Merge] Return if transition condition checks fail - final Optional maybeTerminalPowBlockFailure = - checkOnTerminalPowBlockConditions( - executionEngineChannel, block, blockSlotState, maybeTransitionStore); - if (maybeTerminalPowBlockFailure.isPresent()) { - return maybeTerminalPowBlockFailure.get(); - } - // Make a copy of the state to avoid mutability issues BeaconState state; @@ -367,6 +357,13 @@ public BlockImportResult onBlock( return BlockImportResult.failedStateTransition(e); } + // [Merge] Return if transition condition checks fail + final Optional maybeTerminalPowBlockFailure = + checkOnTerminalPowBlockConditions(executionEngineChannel, block, blockSlotState); + if (maybeTerminalPowBlockFailure.isPresent()) { + return maybeTerminalPowBlockFailure.get(); + } + // Add new block to store store.putBlockAndState(signedBlock, state); @@ -422,10 +419,10 @@ private UInt64 getFinalizedCheckpointStartSlot(final ReadOnlyStore store) { private Optional checkOnTerminalPowBlockConditions( final ExecutionEngineChannel executionEngineChannel, final BeaconBlock block, - final BeaconState blockSlotState, - final Optional maybeTransitionStore) { + final BeaconState blockSlotState) { + // not a merge version of the spec - if (maybeTransitionStore.isEmpty() || mergeTransitionHelpers == null) { + if (mergeTransitionHelpers == null) { return Optional.empty(); } @@ -436,10 +433,10 @@ private Optional checkOnTerminalPowBlockConditions( PowBlock powBlock = mergeTransitionHelpers.getPowBlock( executionEngineChannel, blockBodyMerge.getExecution_payload().getParent_hash()); - if (!powBlock.isProcessed) { - return Optional.of(BlockImportResult.FAILED_UNKNOWN_TERMINAL_POW_BLOCK); - } - if (!mergeTransitionHelpers.isValidTerminalPowBlock(powBlock, maybeTransitionStore.get())) { + PowBlock parentPowBlock = + mergeTransitionHelpers.getPowBlock(executionEngineChannel, powBlock.parentHash); + + if (!mergeTransitionHelpers.isValidTerminalPowBlock(powBlock, parentPowBlock)) { return Optional.of(BlockImportResult.FAILED_INVALID_TERMINAL_POW_BLOCK); } return Optional.empty(); diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/altair/SpecLogicAltair.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/altair/SpecLogicAltair.java index 05879266362..ae45cc72d99 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/altair/SpecLogicAltair.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/altair/SpecLogicAltair.java @@ -15,9 +15,6 @@ import java.util.Optional; import tech.pegasys.teku.spec.config.SpecConfigAltair; -import tech.pegasys.teku.spec.datastructures.forkchoice.TransitionStore; -import tech.pegasys.teku.spec.datastructures.state.beaconstate.BeaconState; -import tech.pegasys.teku.spec.executionengine.ExecutionEngineChannel; import tech.pegasys.teku.spec.logic.common.AbstractSpecLogic; import tech.pegasys.teku.spec.logic.common.helpers.BeaconStateMutators; import tech.pegasys.teku.spec.logic.common.helpers.MergeTransitionHelpers; @@ -166,12 +163,6 @@ public static SpecLogicAltair create( stateUpgrade); } - @Override - public void initializeTransitionStore( - ExecutionEngineChannel executionEngineChannel, BeaconState state) { - // no transition store in Altair - } - @Override public Optional getSyncCommitteeUtil() { return syncCommitteeUtil; @@ -186,9 +177,4 @@ public Optional getMergeTransitionHelpers() { public Optional getExecutionPayloadUtil() { return Optional.empty(); } - - @Override - public Optional getTransitionStore() { - return Optional.empty(); - } } diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/merge/SpecLogicMerge.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/merge/SpecLogicMerge.java index a08d67c14bd..c82a9c66a61 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/merge/SpecLogicMerge.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/merge/SpecLogicMerge.java @@ -13,16 +13,10 @@ package tech.pegasys.teku.spec.logic.versions.merge; -import com.google.common.base.Preconditions; import java.util.Optional; -import org.apache.tuweni.units.bigints.UInt256; import tech.pegasys.teku.spec.config.SpecConfigMerge; -import tech.pegasys.teku.spec.datastructures.forkchoice.TransitionStore; -import tech.pegasys.teku.spec.datastructures.state.beaconstate.BeaconState; -import tech.pegasys.teku.spec.executionengine.ExecutionEngineChannel; import tech.pegasys.teku.spec.logic.common.AbstractSpecLogic; import tech.pegasys.teku.spec.logic.common.helpers.MergeTransitionHelpers; -import tech.pegasys.teku.spec.logic.common.helpers.PowBlock; import tech.pegasys.teku.spec.logic.common.helpers.Predicates; import tech.pegasys.teku.spec.logic.common.operations.OperationSignatureVerifier; import tech.pegasys.teku.spec.logic.common.operations.validation.OperationValidator; @@ -38,7 +32,6 @@ import tech.pegasys.teku.spec.logic.versions.altair.statetransition.epoch.ValidatorStatusFactoryAltair; import tech.pegasys.teku.spec.logic.versions.merge.block.BlockProcessorMerge; import tech.pegasys.teku.spec.logic.versions.merge.forktransition.MergeStateUpgrade; -import tech.pegasys.teku.spec.logic.versions.merge.forktransition.TransitionStoreUtil; import tech.pegasys.teku.spec.logic.versions.merge.helpers.BeaconStateAccessorsMerge; import tech.pegasys.teku.spec.logic.versions.merge.helpers.MiscHelpersMerge; import tech.pegasys.teku.spec.schemas.SchemaDefinitionsMerge; @@ -47,9 +40,6 @@ public class SpecLogicMerge extends AbstractSpecLogic { private final ExecutionPayloadUtil executionPayloadUtil; private final MergeTransitionHelpers mergeTransitionHelpers; - private final TransitionStoreUtil transitionStoreUtil; - - private TransitionStore transitionStore; private SpecLogicMerge( final Predicates predicates, @@ -68,8 +58,6 @@ private SpecLogicMerge( final BlockProposalUtil blockProposalUtil, final ExecutionPayloadUtil executionPayloadUtil, final MergeTransitionHelpers mergeTransitionHelpers, - final TransitionStore transitionStore, - final TransitionStoreUtil transitionStoreUtil, final MergeStateUpgrade stateUpgrade) { super( predicates, @@ -89,9 +77,6 @@ private SpecLogicMerge( Optional.of(stateUpgrade)); this.executionPayloadUtil = executionPayloadUtil; this.mergeTransitionHelpers = mergeTransitionHelpers; - this.transitionStoreUtil = transitionStoreUtil; - - this.transitionStore = transitionStore; } public static SpecLogicMerge create( @@ -149,7 +134,8 @@ public static SpecLogicMerge create( validatorsUtil, operationValidator, executionPayloadUtil); - final MergeTransitionHelpers mergeTransitionHelpers = new MergeTransitionHelpers(miscHelpers); + final MergeTransitionHelpers mergeTransitionHelpers = + new MergeTransitionHelpers(miscHelpers, config); final ForkChoiceUtil forkChoiceUtil = new ForkChoiceUtil( config, @@ -165,10 +151,6 @@ public static SpecLogicMerge create( final MergeStateUpgrade stateUpgrade = new MergeStateUpgrade(config, schemaDefinitions, beaconStateAccessors); - // Transition total difficulty is set on transition logic upgrade - final TransitionStore transitionStore = TransitionStore.create(UInt256.ZERO); - final TransitionStoreUtil transitionStoreUtil = new TransitionStoreUtil(config); - return new SpecLogicMerge( predicates, miscHelpers, @@ -186,23 +168,9 @@ public static SpecLogicMerge create( blockProposalUtil, executionPayloadUtil, mergeTransitionHelpers, - transitionStore, - transitionStoreUtil, stateUpgrade); } - @Override - public void initializeTransitionStore( - ExecutionEngineChannel executionEngineChannel, BeaconState state) { - PowBlock powBlock = - mergeTransitionHelpers.getPowBlock( - executionEngineChannel, state.getEth1_data().getBlock_hash()); - Preconditions.checkArgument(powBlock.isProcessed, "Anchor PowBlock is not processed"); - Preconditions.checkArgument(powBlock.isValid, "Anchor PowBlock is invalid"); - - this.transitionStore = transitionStoreUtil.getTransitionStore(powBlock); - } - @Override public Optional getSyncCommitteeUtil() { return Optional.empty(); @@ -217,9 +185,4 @@ public Optional getMergeTransitionHelpers() { public Optional getExecutionPayloadUtil() { return Optional.of(executionPayloadUtil); } - - @Override - public Optional getTransitionStore() { - return Optional.of(transitionStore); - } } diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/merge/forktransition/TransitionStoreUtil.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/merge/forktransition/TransitionStoreUtil.java deleted file mode 100644 index 5c0dfb8f1ed..00000000000 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/merge/forktransition/TransitionStoreUtil.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2021 ConsenSys AG. - * - * 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.logic.versions.merge.forktransition; - -import org.apache.tuweni.units.bigints.UInt256; -import org.apache.tuweni.units.bigints.UInt256s; -import tech.pegasys.teku.infrastructure.unsigned.UInt64; -import tech.pegasys.teku.spec.config.SpecConfigMerge; -import tech.pegasys.teku.spec.datastructures.forkchoice.TransitionStore; -import tech.pegasys.teku.spec.logic.common.helpers.PowBlock; - -public class TransitionStoreUtil { - private final SpecConfigMerge config; - - public TransitionStoreUtil(SpecConfigMerge config) { - this.config = config; - } - - public TransitionStore getTransitionStore(PowBlock anchorPowBlock) { - UInt256 transitionTotalDifficulty = computeTransitionTotalDifficulty(anchorPowBlock); - return TransitionStore.create(transitionTotalDifficulty); - } - - private UInt256 computeTransitionTotalDifficulty(PowBlock anchorPowBlock) { - UInt64 secondsPerVotingPeriod = - UInt64.valueOf(config.getEpochsPerEth1VotingPeriod()) - .times(config.getSlotsPerEpoch()) - .times(config.getSecondsPerSlot()); - UInt64 powBlocksPerVotingPeriod = - secondsPerVotingPeriod.dividedBy(config.getSecondsPerEth1Block()); - UInt64 powBlocksToMerge = - config.getTargetSecondsToMerge().dividedBy(config.getSecondsPerEth1Block()); - UInt64 powBlocksAfterAnchorBlock = - config.getEth1FollowDistance().plus(powBlocksPerVotingPeriod).plus(powBlocksToMerge); - UInt256 anchorDifficulty = - UInt256s.max(config.getMinAnchorPowBlockDifficulty(), anchorPowBlock.difficulty); - - return anchorPowBlock.totalDifficulty.plus( - anchorDifficulty.multiply(powBlocksAfterAnchorBlock.longValue())); - } -} diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/phase0/SpecLogicPhase0.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/phase0/SpecLogicPhase0.java index e34139a0440..04bf6f6f32b 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/phase0/SpecLogicPhase0.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/phase0/SpecLogicPhase0.java @@ -15,9 +15,6 @@ import java.util.Optional; import tech.pegasys.teku.spec.config.SpecConfig; -import tech.pegasys.teku.spec.datastructures.forkchoice.TransitionStore; -import tech.pegasys.teku.spec.datastructures.state.beaconstate.BeaconState; -import tech.pegasys.teku.spec.executionengine.ExecutionEngineChannel; import tech.pegasys.teku.spec.logic.common.AbstractSpecLogic; import tech.pegasys.teku.spec.logic.common.helpers.BeaconStateAccessors; import tech.pegasys.teku.spec.logic.common.helpers.BeaconStateMutators; @@ -145,12 +142,6 @@ public static SpecLogicPhase0 create( blockProposalUtil); } - @Override - public void initializeTransitionStore( - ExecutionEngineChannel executionEngineChannel, BeaconState state) { - // no transition store in Altair - } - @Override public Optional getSyncCommitteeUtil() { return Optional.empty(); @@ -165,9 +156,4 @@ public Optional getMergeTransitionHelpers() { public Optional getExecutionPayloadUtil() { return Optional.empty(); } - - @Override - public Optional getTransitionStore() { - return Optional.empty(); - } } diff --git a/ethereum/spec/src/test/resources/tech/pegasys/teku/spec/config/invalid/invalidPreset_unknown.yaml b/ethereum/spec/src/test/resources/tech/pegasys/teku/spec/config/invalid/invalidPreset_unknown.yaml index d0cb500fe14..f5f4642037a 100644 --- a/ethereum/spec/src/test/resources/tech/pegasys/teku/spec/config/invalid/invalidPreset_unknown.yaml +++ b/ethereum/spec/src/test/resources/tech/pegasys/teku/spec/config/invalid/invalidPreset_unknown.yaml @@ -30,10 +30,10 @@ MERGE_FORK_EPOCH: 18446744073709551615 SHARDING_FORK_VERSION: 0x03000001 SHARDING_FORK_EPOCH: 18446744073709551615 -# TBD, 2**32 is a placeholder. Merge transition approach is in active R&D. -TARGET_SECONDS_TO_MERGE: 4294967296 -MIN_ANCHOR_POW_BLOCK_DIFFICULTY: 0 - +# Transition +# --------------------------------------------------------------- +# TBD, 2**256-1 is a placeholder +TERMINAL_TOTAL_DIFFICULTY: 115792089237316195423570985008687907853269984665640564039457584007913129639935 # Time parameters # --------------------------------------------------------------- diff --git a/ethereum/spec/src/test/resources/tech/pegasys/teku/spec/config/invalid/invalidPreset_wrongType.yaml b/ethereum/spec/src/test/resources/tech/pegasys/teku/spec/config/invalid/invalidPreset_wrongType.yaml index 852fc213e6f..8a498dc804b 100644 --- a/ethereum/spec/src/test/resources/tech/pegasys/teku/spec/config/invalid/invalidPreset_wrongType.yaml +++ b/ethereum/spec/src/test/resources/tech/pegasys/teku/spec/config/invalid/invalidPreset_wrongType.yaml @@ -30,10 +30,10 @@ MERGE_FORK_EPOCH: 18446744073709551615 SHARDING_FORK_VERSION: 0x03000001 SHARDING_FORK_EPOCH: 18446744073709551615 -# TBD, 2**32 is a placeholder. Merge transition approach is in active R&D. -TARGET_SECONDS_TO_MERGE: 4294967296 -MIN_ANCHOR_POW_BLOCK_DIFFICULTY: 0 - +# Transition +# --------------------------------------------------------------- +# TBD, 2**256-1 is a placeholder +TERMINAL_TOTAL_DIFFICULTY: 115792089237316195423570985008687907853269984665640564039457584007913129639935 # Time parameters # --------------------------------------------------------------- diff --git a/ethereum/spec/src/test/resources/tech/pegasys/teku/spec/config/invalid/multifile_dupFields/config.yaml b/ethereum/spec/src/test/resources/tech/pegasys/teku/spec/config/invalid/multifile_dupFields/config.yaml index a9197d5736a..2ec9212c56e 100644 --- a/ethereum/spec/src/test/resources/tech/pegasys/teku/spec/config/invalid/multifile_dupFields/config.yaml +++ b/ethereum/spec/src/test/resources/tech/pegasys/teku/spec/config/invalid/multifile_dupFields/config.yaml @@ -34,10 +34,10 @@ MERGE_FORK_EPOCH: 18446744073709551615 SHARDING_FORK_VERSION: 0x03000000 SHARDING_FORK_EPOCH: 18446744073709551615 -# TBD, 2**32 is a placeholder. Merge transition approach is in active R&D. -TARGET_SECONDS_TO_MERGE: 4294967296 -MIN_ANCHOR_POW_BLOCK_DIFFICULTY: 0 - +# Transition +# --------------------------------------------------------------- +# TBD, 2**256-1 is a placeholder +TERMINAL_TOTAL_DIFFICULTY: 115792089237316195423570985008687907853269984665640564039457584007913129639935 # Time parameters # --------------------------------------------------------------- diff --git a/ethereum/spec/src/test/resources/tech/pegasys/teku/spec/config/standard/mainnet.yaml b/ethereum/spec/src/test/resources/tech/pegasys/teku/spec/config/standard/mainnet.yaml index 1c0decc136a..97649995448 100644 --- a/ethereum/spec/src/test/resources/tech/pegasys/teku/spec/config/standard/mainnet.yaml +++ b/ethereum/spec/src/test/resources/tech/pegasys/teku/spec/config/standard/mainnet.yaml @@ -31,10 +31,10 @@ MERGE_FORK_EPOCH: 18446744073709551615 SHARDING_FORK_VERSION: 0x03000000 SHARDING_FORK_EPOCH: 18446744073709551615 -# TBD, 2**32 is a placeholder. Merge transition approach is in active R&D. -TARGET_SECONDS_TO_MERGE: 4294967296 -MIN_ANCHOR_POW_BLOCK_DIFFICULTY: 0 - +# Transition +# --------------------------------------------------------------- +# TBD, 2**256-1 is a placeholder +TERMINAL_TOTAL_DIFFICULTY: 115792089237316195423570985008687907853269984665640564039457584007913129639935 # Time parameters # --------------------------------------------------------------- diff --git a/ethereum/spec/src/test/resources/tech/pegasys/teku/spec/config/standard/minimal.yaml b/ethereum/spec/src/test/resources/tech/pegasys/teku/spec/config/standard/minimal.yaml index ea6d5602c1e..7172fa3ede9 100644 --- a/ethereum/spec/src/test/resources/tech/pegasys/teku/spec/config/standard/minimal.yaml +++ b/ethereum/spec/src/test/resources/tech/pegasys/teku/spec/config/standard/minimal.yaml @@ -30,10 +30,10 @@ MERGE_FORK_EPOCH: 18446744073709551615 SHARDING_FORK_VERSION: 0x03000001 SHARDING_FORK_EPOCH: 18446744073709551615 -# TBD, 2**32 is a placeholder. Merge transition approach is in active R&D. -TARGET_SECONDS_TO_MERGE: 4294967296 -MIN_ANCHOR_POW_BLOCK_DIFFICULTY: 0 - +# Transition +# --------------------------------------------------------------- +# TBD, 2**256-1 is a placeholder +TERMINAL_TOTAL_DIFFICULTY: 115792089237316195423570985008687907853269984665640564039457584007913129639935 # Time parameters # --------------------------------------------------------------- diff --git a/teku/src/integration-test/resources/tech/pegasys/teku/cli/subcommand/test-spec.yaml b/teku/src/integration-test/resources/tech/pegasys/teku/cli/subcommand/test-spec.yaml index 754a9f6939f..d647762197e 100644 --- a/teku/src/integration-test/resources/tech/pegasys/teku/cli/subcommand/test-spec.yaml +++ b/teku/src/integration-test/resources/tech/pegasys/teku/cli/subcommand/test-spec.yaml @@ -33,8 +33,10 @@ MERGE_FORK_EPOCH: 18446744073709551615 SHARDING_FORK_VERSION: 0x03001020 SHARDING_FORK_EPOCH: 18446744073709551615 -TARGET_SECONDS_TO_MERGE: 4294967296 -MIN_ANCHOR_POW_BLOCK_DIFFICULTY: 0 +# Transition +# --------------------------------------------------------------- +# TBD, 2**256-1 is a placeholder +TERMINAL_TOTAL_DIFFICULTY: 115792089237316195423570985008687907853269984665640564039457584007913129639935 # Time parameters # --------------------------------------------------------------- diff --git a/util/src/main/java/tech/pegasys/teku/util/config/ConstantsReader.java b/util/src/main/java/tech/pegasys/teku/util/config/ConstantsReader.java index 922aa16d13c..d45828e0a9c 100644 --- a/util/src/main/java/tech/pegasys/teku/util/config/ConstantsReader.java +++ b/util/src/main/java/tech/pegasys/teku/util/config/ConstantsReader.java @@ -55,8 +55,7 @@ class ConstantsReader { "SHARDING_FORK_EPOCH", "TRANSITION_TOTAL_DIFFICULTY", "MIN_ANCHOR_POW_BLOCK_DIFFICULTY", - "TARGET_SECONDS_TO_MERGE", - "MIN_ANCHOR_POW_BLOCK_DIFFICULTY", + "TERMINAL_TOTAL_DIFFICULTY", // Phase0 constants which may exist in legacy config files, but should now be ignored "BLS_WITHDRAWAL_PREFIX", "TARGET_AGGREGATORS_PER_COMMITTEE", diff --git a/util/src/main/resources/tech/pegasys/teku/util/config/configs/mainnet.yaml b/util/src/main/resources/tech/pegasys/teku/util/config/configs/mainnet.yaml index 7162b2a14f4..39e3bc1f541 100644 --- a/util/src/main/resources/tech/pegasys/teku/util/config/configs/mainnet.yaml +++ b/util/src/main/resources/tech/pegasys/teku/util/config/configs/mainnet.yaml @@ -34,10 +34,10 @@ MERGE_FORK_EPOCH: 18446744073709551615 SHARDING_FORK_VERSION: 0x03000000 SHARDING_FORK_EPOCH: 18446744073709551615 -# TBD, 2**32 is a placeholder. Merge transition approach is in active R&D. -TARGET_SECONDS_TO_MERGE: 4294967296 -MIN_ANCHOR_POW_BLOCK_DIFFICULTY: 0 - +# Transition +# --------------------------------------------------------------- +# TBD, 2**256-1 is a placeholder +TERMINAL_TOTAL_DIFFICULTY: 115792089237316195423570985008687907853269984665640564039457584007913129639935 # Time parameters # --------------------------------------------------------------- diff --git a/util/src/main/resources/tech/pegasys/teku/util/config/configs/minimal.yaml b/util/src/main/resources/tech/pegasys/teku/util/config/configs/minimal.yaml index b5337dde1f4..72e6cb7a5c5 100644 --- a/util/src/main/resources/tech/pegasys/teku/util/config/configs/minimal.yaml +++ b/util/src/main/resources/tech/pegasys/teku/util/config/configs/minimal.yaml @@ -30,10 +30,10 @@ MERGE_FORK_EPOCH: 18446744073709551615 SHARDING_FORK_VERSION: 0x03000001 SHARDING_FORK_EPOCH: 18446744073709551615 -# TBD, 2**32 is a placeholder. Merge transition approach is in active R&D. -TARGET_SECONDS_TO_MERGE: 4294967296 -MIN_ANCHOR_POW_BLOCK_DIFFICULTY: 0 - +# Transition +# --------------------------------------------------------------- +# TBD, 2**256-1 is a placeholder +TERMINAL_TOTAL_DIFFICULTY: 115792089237316195423570985008687907853269984665640564039457584007913129639935 # Time parameters # --------------------------------------------------------------- diff --git a/util/src/main/resources/tech/pegasys/teku/util/config/configs/prater.yaml b/util/src/main/resources/tech/pegasys/teku/util/config/configs/prater.yaml index ed0c5d09ec3..324e515ee9b 100644 --- a/util/src/main/resources/tech/pegasys/teku/util/config/configs/prater.yaml +++ b/util/src/main/resources/tech/pegasys/teku/util/config/configs/prater.yaml @@ -33,10 +33,10 @@ MERGE_FORK_EPOCH: 18446744073709551615 SHARDING_FORK_VERSION: 0x03001020 SHARDING_FORK_EPOCH: 18446744073709551615 -# TBD, 2**32 is a placeholder. Merge transition approach is in active R&D. -TARGET_SECONDS_TO_MERGE: 4294967296 -MIN_ANCHOR_POW_BLOCK_DIFFICULTY: 0 - +# Transition +# --------------------------------------------------------------- +# TBD, 2**256-1 is a placeholder +TERMINAL_TOTAL_DIFFICULTY: 115792089237316195423570985008687907853269984665640564039457584007913129639935 # Time parameters # --------------------------------------------------------------- diff --git a/util/src/main/resources/tech/pegasys/teku/util/config/configs/pyrmont.yaml b/util/src/main/resources/tech/pegasys/teku/util/config/configs/pyrmont.yaml index 0cbac321b0f..550e0374da0 100644 --- a/util/src/main/resources/tech/pegasys/teku/util/config/configs/pyrmont.yaml +++ b/util/src/main/resources/tech/pegasys/teku/util/config/configs/pyrmont.yaml @@ -34,10 +34,10 @@ MERGE_FORK_EPOCH: 18446744073709551615 SHARDING_FORK_VERSION: 0x03002009 SHARDING_FORK_EPOCH: 18446744073709551615 -# TBD, 2**32 is a placeholder. Merge transition approach is in active R&D. -TARGET_SECONDS_TO_MERGE: 4294967296 -MIN_ANCHOR_POW_BLOCK_DIFFICULTY: 0 - +# Transition +# --------------------------------------------------------------- +# TBD, 2**256-1 is a placeholder +TERMINAL_TOTAL_DIFFICULTY: 115792089237316195423570985008687907853269984665640564039457584007913129639935 # Time parameters # --------------------------------------------------------------- diff --git a/util/src/test/resources/tech/pegasys/teku/util/config/invalid/invalidPresetType.yaml b/util/src/test/resources/tech/pegasys/teku/util/config/invalid/invalidPresetType.yaml index 852fc213e6f..8a498dc804b 100644 --- a/util/src/test/resources/tech/pegasys/teku/util/config/invalid/invalidPresetType.yaml +++ b/util/src/test/resources/tech/pegasys/teku/util/config/invalid/invalidPresetType.yaml @@ -30,10 +30,10 @@ MERGE_FORK_EPOCH: 18446744073709551615 SHARDING_FORK_VERSION: 0x03000001 SHARDING_FORK_EPOCH: 18446744073709551615 -# TBD, 2**32 is a placeholder. Merge transition approach is in active R&D. -TARGET_SECONDS_TO_MERGE: 4294967296 -MIN_ANCHOR_POW_BLOCK_DIFFICULTY: 0 - +# Transition +# --------------------------------------------------------------- +# TBD, 2**256-1 is a placeholder +TERMINAL_TOTAL_DIFFICULTY: 115792089237316195423570985008687907853269984665640564039457584007913129639935 # Time parameters # --------------------------------------------------------------- diff --git a/util/src/test/resources/tech/pegasys/teku/util/config/invalid/unknownPreset.yaml b/util/src/test/resources/tech/pegasys/teku/util/config/invalid/unknownPreset.yaml index d0cb500fe14..f5f4642037a 100644 --- a/util/src/test/resources/tech/pegasys/teku/util/config/invalid/unknownPreset.yaml +++ b/util/src/test/resources/tech/pegasys/teku/util/config/invalid/unknownPreset.yaml @@ -30,10 +30,10 @@ MERGE_FORK_EPOCH: 18446744073709551615 SHARDING_FORK_VERSION: 0x03000001 SHARDING_FORK_EPOCH: 18446744073709551615 -# TBD, 2**32 is a placeholder. Merge transition approach is in active R&D. -TARGET_SECONDS_TO_MERGE: 4294967296 -MIN_ANCHOR_POW_BLOCK_DIFFICULTY: 0 - +# Transition +# --------------------------------------------------------------- +# TBD, 2**256-1 is a placeholder +TERMINAL_TOTAL_DIFFICULTY: 115792089237316195423570985008687907853269984665640564039457584007913129639935 # Time parameters # --------------------------------------------------------------- diff --git a/validator/coordinator/src/main/java/tech/pegasys/teku/validator/coordinator/BlockFactory.java b/validator/coordinator/src/main/java/tech/pegasys/teku/validator/coordinator/BlockFactory.java index 1c99fbaba28..ae09c8a261e 100644 --- a/validator/coordinator/src/main/java/tech/pegasys/teku/validator/coordinator/BlockFactory.java +++ b/validator/coordinator/src/main/java/tech/pegasys/teku/validator/coordinator/BlockFactory.java @@ -15,6 +15,7 @@ import static com.google.common.base.Preconditions.checkArgument; +import com.google.common.base.Preconditions; import java.util.Optional; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -26,10 +27,10 @@ import tech.pegasys.teku.infrastructure.logging.ColorConsolePrinter.Color; import tech.pegasys.teku.infrastructure.unsigned.UInt64; import tech.pegasys.teku.spec.Spec; +import tech.pegasys.teku.spec.config.SpecConfigMerge; import tech.pegasys.teku.spec.datastructures.blocks.BeaconBlock; import tech.pegasys.teku.spec.datastructures.blocks.Eth1Data; import tech.pegasys.teku.spec.datastructures.execution.ExecutionPayload; -import tech.pegasys.teku.spec.datastructures.forkchoice.TransitionStore; import tech.pegasys.teku.spec.datastructures.operations.Attestation; import tech.pegasys.teku.spec.datastructures.operations.AttesterSlashing; import tech.pegasys.teku.spec.datastructures.operations.Deposit; @@ -69,7 +70,7 @@ public class BlockFactory { // we are going to store latest payloadId returned by preparePayload for a given slot // in this way validator doesn't need to know anything about payloadId - private final LRUCache slotToPayloadIdMap; + private final LRUCache> slotToPayloadIdMap; public BlockFactory( final AggregatingAttestationPool attestationPool, @@ -101,16 +102,20 @@ public BlockFactory( } public void prepareExecutionPayload(final Optional maybeCurrentSlotState) { - if (maybeCurrentSlotState.isEmpty()) { - LOG.error("prepareExecutionPayload - empty state!"); - return; - } - final Optional maybeCurrentMergeState = - maybeCurrentSlotState.get().toVersionMerge(); + maybeCurrentSlotState.ifPresent( + currentSlotState -> { + Optional maybeRef = prepareExecutionPayloadRef(currentSlotState); + slotToPayloadIdMap.invalidateWithNewValue(currentSlotState.getSlot(), maybeRef); + }); + } + + private Optional prepareExecutionPayloadRef( + final BeaconState currentSlotState) { + final Optional maybeCurrentMergeState = currentSlotState.toVersionMerge(); if (maybeCurrentMergeState.isEmpty()) { LOG.trace("prepareExecutionPayload - not yet in Merge state!"); - return; + return Optional.empty(); } final BeaconStateMerge currentMergeState = maybeCurrentMergeState.get(); @@ -122,19 +127,44 @@ public void prepareExecutionPayload(final Optional maybeCurrentSlot final MergeTransitionHelpers mergeTransitionHelpers = spec.atSlot(slot).getMergeTransitionHelpers().orElseThrow(); - final TransitionStore transitionStore = spec.atSlot(slot).getTransitionStore().orElseThrow(); - Bytes32 executionParentHash; + final Bytes32 executionParentHash; if (!mergeTransitionHelpers.isMergeComplete(currentMergeState)) { + SpecConfigMerge specConfig = spec.getSpecConfig(epoch).toVersionMerge().orElseThrow(); + UInt256 terminalTotalDifficulty = specConfig.getTerminalTotalDifficulty(); + PowBlock powHead = mergeTransitionHelpers.getPowChainHead(executionEngineChannel); - if (!mergeTransitionHelpers.isValidTerminalPowBlock(powHead, transitionStore)) { - LOG.trace("prepareExecutionPayload - terminal block not yet reached!"); - return; + Optional terminalPowBlock = + getPowBlockAtTotalDifficulty(terminalTotalDifficulty, powHead, mergeTransitionHelpers); + + if (terminalPowBlock.isEmpty()) { + LOG.info( + ColorConsolePrinter.print( + String.format( + "Produce pre-merge block: pow_block.total_difficulty(%d) < transition_total_difficulty(%d), PoW blocks left ~%d", + powHead.totalDifficulty.toBigInteger(), + specConfig.getTerminalTotalDifficulty().toBigInteger(), + specConfig + .getTerminalTotalDifficulty() + .subtract(powHead.totalDifficulty) + .divide(powHead.difficulty) + .add(UInt256.ONE) + .toBigInteger()), + Color.CYAN)); + return Optional.empty(); } + // terminal block - executionParentHash = powHead.blockHash; - LOG.trace("prepareExecutionPayload - terminal block reached!"); + executionParentHash = terminalPowBlock.get().blockHash; + + LOG.info( + ColorConsolePrinter.print( + String.format( + "Produce transition block: pow_block.total_difficulty(%d) >= transition_total_difficulty(%d)", + powHead.totalDifficulty.toBigInteger(), + specConfig.getTerminalTotalDifficulty().toBigInteger()), + Color.YELLOW)); } else { executionParentHash = currentMergeState.getLatest_execution_payload_header().getBlock_hash(); } @@ -151,7 +181,7 @@ public void prepareExecutionPayload(final Optional maybeCurrentSlot executionPayloadUtil.prepareExecutionPayload( executionEngineChannel, executionParentHash, timestamp, random, feeRecipient); - slotToPayloadIdMap.invalidateWithNewValue(slot, payloadId); + return Optional.of(new PreparePayloadReference(payloadId, executionParentHash)); } public BeaconBlock createUnsignedBlock( @@ -227,57 +257,35 @@ public BeaconBlock createUnsignedBlock( } private ExecutionPayload getExecutionPayload(BeaconState genericState) { - final BeaconStateMerge state = BeaconStateMerge.required(genericState); - final UInt64 slot = state.getSlot(); + UInt64 slot = genericState.getSlot(); final ExecutionPayloadUtil executionPayloadUtil = spec.atSlot(slot).getExecutionPayloadUtil().orElseThrow(); - final MergeTransitionHelpers mergeTransitionHelpers = - spec.atSlot(slot).getMergeTransitionHelpers().orElseThrow(); - final TransitionStore transitionStore = spec.atSlot(slot).getTransitionStore().orElseThrow(); - if (!mergeTransitionHelpers.isMergeComplete(state)) { - PowBlock powHead = mergeTransitionHelpers.getPowChainHead(executionEngineChannel); - if (!mergeTransitionHelpers.isValidTerminalPowBlock(powHead, transitionStore)) { - // Pre-merge, empty payload - LOG.info( - ColorConsolePrinter.print( - String.format( - "Produce pre-merge block: pow_block.total_difficulty(%d) < transition_total_difficulty(%d), PoW blocks left ~%d", - powHead.totalDifficulty.toBigInteger(), - transitionStore.getTransitionTotalDifficulty().toBigInteger(), - transitionStore - .getTransitionTotalDifficulty() - .subtract(powHead.totalDifficulty) - .divide(powHead.difficulty) - .add(UInt256.ONE) - .toBigInteger()), - Color.CYAN)); - return new ExecutionPayload(); - } else { - // Signify merge via producing on top of the last PoW block - LOG.info( - ColorConsolePrinter.print( - String.format( - "Produce transition block: pow_block.total_difficulty(%d) >= transition_total_difficulty(%d)", - powHead.totalDifficulty.toBigInteger(), - transitionStore.getTransitionTotalDifficulty().toBigInteger()), - Color.YELLOW)); + return getExecutionPayloadRefFromSlot(slot) + .map( + ref -> + validateExecutionPayload( + ref.getParentHash(), + executionPayloadUtil.getExecutionPayload( + executionEngineChannel, ref.getPreparePayloadId()))) + .orElseGet(ExecutionPayload::new); + } - return validateExecutionPayload( - powHead.blockHash, - executionPayloadUtil.getExecutionPayload( - executionEngineChannel, getExecutionPayloadIdFromSlot(slot))); - } - } + private Optional getPowBlockAtTotalDifficulty( + UInt256 totalDifficulty, PowBlock head, MergeTransitionHelpers mergeTransitionHelpers) { + Preconditions.checkArgument( + totalDifficulty.compareTo(UInt256.ZERO) > 0, "Expecting totalDifficulty > 0"); - // Post-merge, normal payload - return validateExecutionPayload( - state.getLatest_execution_payload_header().getBlock_hash(), - executionPayloadUtil.getExecutionPayload( - executionEngineChannel, getExecutionPayloadIdFromSlot(slot))); + PowBlock block = head; + Optional parent = Optional.empty(); + while (block.totalDifficulty.compareTo(totalDifficulty) >= 0) { + parent = Optional.of(block); + block = mergeTransitionHelpers.getPowBlock(executionEngineChannel, block.parentHash); + } + return parent; } - private UInt64 getExecutionPayloadIdFromSlot(UInt64 slot) { + private Optional getExecutionPayloadRefFromSlot(UInt64 slot) { return slotToPayloadIdMap .getCached(slot) .orElseThrow( @@ -296,4 +304,22 @@ private ExecutionPayload validateExecutionPayload( return executionPayload; } + + private static class PreparePayloadReference { + private final UInt64 preparePayloadId; + private final Bytes32 parentHash; + + public PreparePayloadReference(UInt64 preparePayloadId, Bytes32 parentHash) { + this.preparePayloadId = preparePayloadId; + this.parentHash = parentHash; + } + + public UInt64 getPreparePayloadId() { + return preparePayloadId; + } + + public Bytes32 getParentHash() { + return parentHash; + } + } }