diff --git a/acceptance-tests/src/acceptance-test/java/tech/pegasys/teku/test/acceptance/BellatrixMergeTransitionAcceptanceTest.java b/acceptance-tests/src/acceptance-test/java/tech/pegasys/teku/test/acceptance/BellatrixMergeTransitionAcceptanceTest.java deleted file mode 100644 index ffec88fff92..00000000000 --- a/acceptance-tests/src/acceptance-test/java/tech/pegasys/teku/test/acceptance/BellatrixMergeTransitionAcceptanceTest.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright Consensys Software Inc., 2022 - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -package tech.pegasys.teku.test.acceptance; - -import com.google.common.io.Resources; -import java.io.IOException; -import java.net.URL; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import tech.pegasys.teku.infrastructure.time.SystemTimeProvider; -import tech.pegasys.teku.infrastructure.unsigned.UInt64; -import tech.pegasys.teku.test.acceptance.dsl.AcceptanceTestBase; -import tech.pegasys.teku.test.acceptance.dsl.BesuNode; -import tech.pegasys.teku.test.acceptance.dsl.TekuBeaconNode; -import tech.pegasys.teku.test.acceptance.dsl.TekuNodeConfigBuilder; -import tech.pegasys.teku.test.acceptance.dsl.tools.deposits.ValidatorKeystores; - -public class BellatrixMergeTransitionAcceptanceTest extends AcceptanceTestBase { - - private static final String NETWORK_NAME = "swift"; - private static final URL JWT_FILE = Resources.getResource("auth/ee-jwt-secret.hex"); - - private final SystemTimeProvider timeProvider = new SystemTimeProvider(); - private BesuNode eth1Node; - private TekuBeaconNode tekuNode; - - @BeforeEach - void setup() throws Exception { - final int genesisTime = timeProvider.getTimeInSeconds().plus(10).intValue(); - eth1Node = - createBesuNode( - config -> - config - .withMiningEnabled(true) - .withMergeSupport() - .withGenesisFile("besu/preMergeGenesis.json") - .withJwtTokenAuthorization(JWT_FILE)); - eth1Node.start(); - - final int totalValidators = 4; - final ValidatorKeystores validatorKeystores = - createTekuDepositSender(NETWORK_NAME).sendValidatorDeposits(eth1Node, totalValidators); - tekuNode = - createTekuBeaconNode( - configureTekuNode(genesisTime) - .withDepositsFrom(eth1Node) - .withExecutionEngine(eth1Node) - .withStartupTargetPeerCount(0) - .withReadOnlyKeystorePath(validatorKeystores) - .withValidatorProposerDefaultFeeRecipient( - "0xFE3B557E8Fb62b89F4916B721be55cEb828dBd73") - .withJwtSecretFile(JWT_FILE) - .build()); - tekuNode.start(); - } - - @Test - void shouldHaveNonDefaultExecutionPayloadAndFinalizeAfterMergeTransition() { - tekuNode.waitForGenesis(); - tekuNode.waitForNonDefaultExecutionPayload(); - - tekuNode.waitForNewFinalization(); - } - - private TekuNodeConfigBuilder configureTekuNode(final int genesisTime) throws IOException { - return TekuNodeConfigBuilder.createBeaconNode() - .withBellatrixEpoch(UInt64.ONE) - .withTotalTerminalDifficulty(10001) - .withGenesisTime(genesisTime); - } -} diff --git a/acceptance-tests/src/acceptance-test/java/tech/pegasys/teku/test/acceptance/BlockProposalAcceptanceTest.java b/acceptance-tests/src/acceptance-test/java/tech/pegasys/teku/test/acceptance/BlockProposalAcceptanceTest.java index 762a10959b8..7cd5c20dfd6 100644 --- a/acceptance-tests/src/acceptance-test/java/tech/pegasys/teku/test/acceptance/BlockProposalAcceptanceTest.java +++ b/acceptance-tests/src/acceptance-test/java/tech/pegasys/teku/test/acceptance/BlockProposalAcceptanceTest.java @@ -48,7 +48,8 @@ void shouldHaveCorrectFeeRecipientAndGraffiti(final boolean useSszBlocks) throws .network(networkName) .withAltairEpoch(UInt64.ZERO) .withBellatrixEpoch(UInt64.ZERO) - .validatorKeys(validatorKeystores, validatorKeystores) + .withCapellaEpoch(UInt64.ZERO) + .validatorKeys(validatorKeystores) .generate(); final String defaultFeeRecipient = "0xFE3B557E8Fb62b89F4916B721be55cEb828dBd73"; @@ -62,6 +63,7 @@ void shouldHaveCorrectFeeRecipientAndGraffiti(final boolean useSszBlocks) throws .withInitialState(genesis) .withAltairEpoch(UInt64.ZERO) .withBellatrixEpoch(UInt64.ZERO) + .withCapellaEpoch(UInt64.ZERO) .withValidatorProposerDefaultFeeRecipient(defaultFeeRecipient) .build()); final TekuValidatorNode validatorClient = diff --git a/acceptance-tests/src/acceptance-test/java/tech/pegasys/teku/test/acceptance/BlsToExecutionChangeAcceptanceTest.java b/acceptance-tests/src/acceptance-test/java/tech/pegasys/teku/test/acceptance/BlsToExecutionChangeAcceptanceTest.java index 2d2915afd8d..1ded8eae99b 100644 --- a/acceptance-tests/src/acceptance-test/java/tech/pegasys/teku/test/acceptance/BlsToExecutionChangeAcceptanceTest.java +++ b/acceptance-tests/src/acceptance-test/java/tech/pegasys/teku/test/acceptance/BlsToExecutionChangeAcceptanceTest.java @@ -85,8 +85,7 @@ private static TekuNodeConfigBuilder beaconNodeWithMilestones(final UInt64 capel .withAltairEpoch(UInt64.ZERO) .withBellatrixEpoch(UInt64.ZERO) .withCapellaEpoch(capellaActivationEpoch) - .withTotalTerminalDifficulty(0) - .withStubExecutionEngine( - "0x14e88057b0b7538a8205cb07726a0de03dd69d9a70e88bcffae15ca3fc6b5215"); + .withTerminalBlockHash(DEFAULT_EL_GENESIS_HASH, 0) + .withStubExecutionEngine(DEFAULT_EL_GENESIS_HASH); } } diff --git a/acceptance-tests/src/acceptance-test/java/tech/pegasys/teku/test/acceptance/CapellaUpgradeAcceptanceTest.java b/acceptance-tests/src/acceptance-test/java/tech/pegasys/teku/test/acceptance/CapellaUpgradeAcceptanceTest.java index 0c0f9c2d00a..db6fd1f8680 100644 --- a/acceptance-tests/src/acceptance-test/java/tech/pegasys/teku/test/acceptance/CapellaUpgradeAcceptanceTest.java +++ b/acceptance-tests/src/acceptance-test/java/tech/pegasys/teku/test/acceptance/CapellaUpgradeAcceptanceTest.java @@ -94,7 +94,7 @@ private static TekuNodeConfigBuilder beaconNodeConfigWithForks( .withAltairEpoch(UInt64.ZERO) .withBellatrixEpoch(UInt64.ZERO) .withCapellaEpoch(UInt64.ONE) - .withTotalTerminalDifficulty(0) + .withTerminalBlockHash(DEFAULT_EL_GENESIS_HASH, 0) .withGenesisTime(genesisTime) .withExecutionEngine(besuNode) .withJwtSecretFile(JWT_FILE) diff --git a/acceptance-tests/src/acceptance-test/java/tech/pegasys/teku/test/acceptance/DenebUpgradeAcceptanceTest.java b/acceptance-tests/src/acceptance-test/java/tech/pegasys/teku/test/acceptance/DenebUpgradeAcceptanceTest.java index a9c0e1f80e8..f8ab754b89b 100644 --- a/acceptance-tests/src/acceptance-test/java/tech/pegasys/teku/test/acceptance/DenebUpgradeAcceptanceTest.java +++ b/acceptance-tests/src/acceptance-test/java/tech/pegasys/teku/test/acceptance/DenebUpgradeAcceptanceTest.java @@ -104,6 +104,6 @@ private static TekuNodeConfigBuilder beaconNodeWithTrustedSetup( .withRealNetwork() .withJwtSecretFile(JWT_FILE) .withDenebEpoch(UInt64.valueOf(2)) - .withTotalTerminalDifficulty(0); + .withTerminalBlockHash(DEFAULT_EL_GENESIS_HASH, 0); } } diff --git a/acceptance-tests/src/acceptance-test/java/tech/pegasys/teku/test/acceptance/DoppelgangerDetectorAcceptanceTest.java b/acceptance-tests/src/acceptance-test/java/tech/pegasys/teku/test/acceptance/DoppelgangerDetectorAcceptanceTest.java index 137d74f7530..b3566aca0b1 100644 --- a/acceptance-tests/src/acceptance-test/java/tech/pegasys/teku/test/acceptance/DoppelgangerDetectorAcceptanceTest.java +++ b/acceptance-tests/src/acceptance-test/java/tech/pegasys/teku/test/acceptance/DoppelgangerDetectorAcceptanceTest.java @@ -43,7 +43,6 @@ void setUp() { createBesuNode( config -> config - .withMiningEnabled(true) .withMergeSupport() .withGenesisFile("besu/preMergeGenesis.json") .withJwtTokenAuthorization(JWT_FILE)); @@ -54,7 +53,7 @@ void shouldDetectDoppelgangersViaKeyManagerAPI() throws Exception { eth1Node.start(); final ValidatorKeystores validatorKeystores = - createTekuDepositSender(networkName).sendValidatorDeposits(eth1Node, 2); + createTekuDepositSender(networkName).generateValidatorKeys(2); final GenesisGenerator.InitialStateData genesis = createGenesisGenerator().network(networkName).validatorKeys(validatorKeystores).generate(); @@ -66,7 +65,7 @@ void shouldDetectDoppelgangersViaKeyManagerAPI() throws Exception { .withValidatorLivenessTracking() .withJwtSecretFile(JWT_FILE) .withBellatrixEpoch(UInt64.ONE) - .withTotalTerminalDifficulty(10001) + .withTerminalBlockHash(DEFAULT_EL_GENESIS_HASH, 0) .withValidatorProposerDefaultFeeRecipient(defaultFeeRecipient) .withInitialState(genesis) .build()); diff --git a/acceptance-tests/src/acceptance-test/java/tech/pegasys/teku/test/acceptance/LocalValidatorKeysAcceptanceTest.java b/acceptance-tests/src/acceptance-test/java/tech/pegasys/teku/test/acceptance/LocalValidatorKeysAcceptanceTest.java index ab9fd540dde..c9e8cec85a5 100644 --- a/acceptance-tests/src/acceptance-test/java/tech/pegasys/teku/test/acceptance/LocalValidatorKeysAcceptanceTest.java +++ b/acceptance-tests/src/acceptance-test/java/tech/pegasys/teku/test/acceptance/LocalValidatorKeysAcceptanceTest.java @@ -58,6 +58,7 @@ void shouldMaintainValidatorsInMutableClient() throws Exception { .withInitialState(genesis) .withAltairEpoch(UInt64.ZERO) .withBellatrixEpoch(UInt64.ZERO) + .withTerminalBlockHash(DEFAULT_EL_GENESIS_HASH, 0) .withValidatorProposerDefaultFeeRecipient(defaultFeeRecipient) .build()); final TekuValidatorNode validatorClient = diff --git a/acceptance-tests/src/acceptance-test/java/tech/pegasys/teku/test/acceptance/MergedGenesisAcceptanceTest.java b/acceptance-tests/src/acceptance-test/java/tech/pegasys/teku/test/acceptance/MergedGenesisAcceptanceTest.java index 38380c7f1c6..291450424b3 100644 --- a/acceptance-tests/src/acceptance-test/java/tech/pegasys/teku/test/acceptance/MergedGenesisAcceptanceTest.java +++ b/acceptance-tests/src/acceptance-test/java/tech/pegasys/teku/test/acceptance/MergedGenesisAcceptanceTest.java @@ -64,7 +64,7 @@ void setup() throws Exception { .withNetwork(NETWORK_NAME) .withAltairEpoch(UInt64.ZERO) .withBellatrixEpoch(UInt64.ZERO) - .withTotalTerminalDifficulty(0) + .withTerminalBlockHash(DEFAULT_EL_GENESIS_HASH, 0) .withInitialState(initialStateData) .withStartupTargetPeerCount(0) .withReadOnlyKeystorePath(validatorKeys) diff --git a/acceptance-tests/src/acceptance-test/java/tech/pegasys/teku/test/acceptance/MergedGenesisInteropModeAcceptanceTest.java b/acceptance-tests/src/acceptance-test/java/tech/pegasys/teku/test/acceptance/MergedGenesisInteropModeAcceptanceTest.java index e03c37cc2ed..6501bd55015 100644 --- a/acceptance-tests/src/acceptance-test/java/tech/pegasys/teku/test/acceptance/MergedGenesisInteropModeAcceptanceTest.java +++ b/acceptance-tests/src/acceptance-test/java/tech/pegasys/teku/test/acceptance/MergedGenesisInteropModeAcceptanceTest.java @@ -34,7 +34,7 @@ public void startFromMergedStatePerMilestoneUsingTerminalBlockHash( final TekuNodeConfig config = createTekuNodeBuilderForMilestone(specMilestone) .withTerminalBlockHash( - "0x00000000000000000000000000000000000000000000000000000000000000aa") + "0x00000000000000000000000000000000000000000000000000000000000000aa", 0) .withStubExecutionEngine() .build(); @@ -70,7 +70,7 @@ private static TekuNodeConfigBuilder createTekuNodeBuilderForMilestone( .withNetwork("minimal") .withAltairEpoch(UInt64.ZERO) .withBellatrixEpoch(UInt64.ZERO) - .withTotalTerminalDifficulty(0) + .withTerminalBlockHash(DEFAULT_EL_GENESIS_HASH, 0) .withStartupTargetPeerCount(0) .withInteropNumberOfValidators(64) .withValidatorProposerDefaultFeeRecipient("0xFE3B557E8Fb62b89F4916B721be55cEb828dBd73"); diff --git a/acceptance-tests/src/acceptance-test/java/tech/pegasys/teku/test/acceptance/OptimisticSyncPostMergeAcceptanceTest.java b/acceptance-tests/src/acceptance-test/java/tech/pegasys/teku/test/acceptance/OptimisticSyncPostMergeAcceptanceTest.java index 426bb1b17d7..f3bfcfdaa9e 100644 --- a/acceptance-tests/src/acceptance-test/java/tech/pegasys/teku/test/acceptance/OptimisticSyncPostMergeAcceptanceTest.java +++ b/acceptance-tests/src/acceptance-test/java/tech/pegasys/teku/test/acceptance/OptimisticSyncPostMergeAcceptanceTest.java @@ -89,7 +89,7 @@ private TekuNodeConfigBuilder createBeaconNode( final BesuNode executionEngine, final int genesisTime) throws Exception { return TekuNodeConfigBuilder.createBeaconNode() .withBellatrixEpoch(UInt64.ZERO) - .withTotalTerminalDifficulty(10001) + .withTerminalBlockHash(DEFAULT_EL_GENESIS_HASH, 1) .withGenesisTime(genesisTime) .withRealNetwork() .withStartupTargetPeerCount(0) diff --git a/acceptance-tests/src/acceptance-test/java/tech/pegasys/teku/test/acceptance/OptimisticSyncSafeSlotsAcceptanceTest.java b/acceptance-tests/src/acceptance-test/java/tech/pegasys/teku/test/acceptance/OptimisticSyncSafeSlotsAcceptanceTest.java deleted file mode 100644 index c07fff3d627..00000000000 --- a/acceptance-tests/src/acceptance-test/java/tech/pegasys/teku/test/acceptance/OptimisticSyncSafeSlotsAcceptanceTest.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright Consensys Software Inc., 2022 - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -package tech.pegasys.teku.test.acceptance; - -import com.google.common.io.Resources; -import java.net.URL; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import tech.pegasys.teku.infrastructure.time.SystemTimeProvider; -import tech.pegasys.teku.infrastructure.unsigned.UInt64; -import tech.pegasys.teku.test.acceptance.dsl.AcceptanceTestBase; -import tech.pegasys.teku.test.acceptance.dsl.BesuNode; -import tech.pegasys.teku.test.acceptance.dsl.TekuBeaconNode; -import tech.pegasys.teku.test.acceptance.dsl.TekuNodeConfigBuilder; - -public class OptimisticSyncSafeSlotsAcceptanceTest extends AcceptanceTestBase { - private static final String NETWORK_NAME = "swift"; - private static final Integer SAFE_SLOTS_TO_IMPORT_OPTIMISTICALLY = 8; - private static final URL JWT_FILE = Resources.getResource("auth/ee-jwt-secret.hex"); - private static final int VALIDATORS = 64; - - private final SystemTimeProvider timeProvider = new SystemTimeProvider(); - private BesuNode executionNode1; - private BesuNode executionNode2; - private TekuBeaconNode tekuNode1; - private TekuBeaconNode tekuNode2; - - @BeforeEach - void setup() throws Exception { - final int genesisTime = timeProvider.getTimeInSeconds().plus(10).intValue(); - executionNode1 = - createBesuNode( - config -> - config - .withMiningEnabled(true) - .withMergeSupport() - .withP2pEnabled(true) - .withGenesisFile("besu/preMergeGenesis.json") - .withJwtTokenAuthorization(JWT_FILE)); - executionNode1.start(); - executionNode2 = - createBesuNode( - config -> - config - .withMergeSupport() - .withP2pEnabled(true) - .withGenesisFile("besu/preMergeGenesis.json") - .withJwtTokenAuthorization(JWT_FILE)); - executionNode2.start(); - - tekuNode1 = - createTekuBeaconNode( - configureTekuNode(executionNode1, genesisTime) - .withInteropValidators(0, VALIDATORS) - .build()); - tekuNode1.start(); - tekuNode2 = - createTekuBeaconNode( - configureTekuNode(executionNode2, genesisTime) - .withInteropValidators(0, 0) - .withPeers(tekuNode1) - .withSafeSlotsToImportOptimistically(SAFE_SLOTS_TO_IMPORT_OPTIMISTICALLY) - .build()); - tekuNode2.start(); - } - - @Test - void shouldPassMergeOptimisticallyAndBeginFinalizationAfterSafeSlotsToImport() throws Exception { - tekuNode2.waitForNonDefaultExecutionPayload(); - tekuNode2.waitForOptimisticBlock(); - - // Now make execution node sync and clarify switch from optimistic sync back to the normal - executionNode2.addPeer(executionNode1); - tekuNode2.waitForNonOptimisticBlock(); - } - - private TekuNodeConfigBuilder configureTekuNode( - final BesuNode executionEngine, final int genesisTime) throws Exception { - return TekuNodeConfigBuilder.createBeaconNode() - .withNetwork(NETWORK_NAME) - .withBellatrixEpoch(UInt64.ZERO) - .withTotalTerminalDifficulty(10001) - .withGenesisTime(genesisTime) - .withRealNetwork() - .withStartupTargetPeerCount(0) - .withExecutionEngine(executionEngine) - .withJwtSecretFile(JWT_FILE); - } -} diff --git a/acceptance-tests/src/acceptance-test/java/tech/pegasys/teku/test/acceptance/SyncingStatusAcceptanceTest.java b/acceptance-tests/src/acceptance-test/java/tech/pegasys/teku/test/acceptance/SyncingStatusAcceptanceTest.java index 3d595d9d82f..8e50c2bf066 100644 --- a/acceptance-tests/src/acceptance-test/java/tech/pegasys/teku/test/acceptance/SyncingStatusAcceptanceTest.java +++ b/acceptance-tests/src/acceptance-test/java/tech/pegasys/teku/test/acceptance/SyncingStatusAcceptanceTest.java @@ -35,14 +35,13 @@ void shouldRespondSyncingWhenExecutionLayerIsDown() throws Exception { createBesuNode( config -> config - .withMiningEnabled(true) .withMergeSupport() .withGenesisFile("besu/preMergeGenesis.json") .withJwtTokenAuthorization(JWT_FILE)); eth1Node.start(); final ValidatorKeystores validatorKeystores = - createTekuDepositSender(networkName).sendValidatorDeposits(eth1Node, 8); + createTekuDepositSender(networkName).generateValidatorKeys(8); final GenesisGenerator.InitialStateData genesis = createGenesisGenerator().network(networkName).validatorKeys(validatorKeystores).generate(); @@ -55,7 +54,7 @@ void shouldRespondSyncingWhenExecutionLayerIsDown() throws Exception { .withNetwork(networkName) .withDepositsFrom(eth1Node) .withBellatrixEpoch(UInt64.ONE) - .withTotalTerminalDifficulty(10001) + .withTerminalBlockHash(DEFAULT_EL_GENESIS_HASH, 0) .withValidatorProposerDefaultFeeRecipient(defaultFeeRecipient) .withExecutionEngine(eth1Node) .withInitialState(genesis) diff --git a/acceptance-tests/src/acceptance-test/java/tech/pegasys/teku/test/acceptance/WebsocketsMergeTransitionAcceptanceTest.java b/acceptance-tests/src/acceptance-test/java/tech/pegasys/teku/test/acceptance/WebsocketsMergeTransitionAcceptanceTest.java index 128b9bd6a10..2f52536adf6 100644 --- a/acceptance-tests/src/acceptance-test/java/tech/pegasys/teku/test/acceptance/WebsocketsMergeTransitionAcceptanceTest.java +++ b/acceptance-tests/src/acceptance-test/java/tech/pegasys/teku/test/acceptance/WebsocketsMergeTransitionAcceptanceTest.java @@ -22,6 +22,7 @@ import tech.pegasys.teku.infrastructure.unsigned.UInt64; import tech.pegasys.teku.test.acceptance.dsl.AcceptanceTestBase; import tech.pegasys.teku.test.acceptance.dsl.BesuNode; +import tech.pegasys.teku.test.acceptance.dsl.GenesisGenerator; import tech.pegasys.teku.test.acceptance.dsl.TekuBeaconNode; import tech.pegasys.teku.test.acceptance.dsl.TekuNodeConfigBuilder; import tech.pegasys.teku.test.acceptance.dsl.tools.deposits.ValidatorKeystores; @@ -41,7 +42,6 @@ void setup() throws Exception { createBesuNode( config -> config - .withMiningEnabled(true) .withMergeSupport() .withGenesisFile("besu/preMergeGenesis.json") .withJwtTokenAuthorization(jwtFile)); @@ -49,7 +49,14 @@ void setup() throws Exception { final int totalValidators = 4; final ValidatorKeystores validatorKeystores = - createTekuDepositSender(NETWORK_NAME).sendValidatorDeposits(eth1Node, totalValidators); + createTekuDepositSender(NETWORK_NAME).generateValidatorKeys(totalValidators); + final GenesisGenerator.InitialStateData genesis = + createGenesisGenerator() + .network(NETWORK_NAME) + .withAltairEpoch(UInt64.ZERO) + .withBellatrixEpoch(UInt64.ONE) + .validatorKeys(validatorKeystores) + .generate(); tekuNode = createTekuBeaconNode( configureTekuNode(genesisTime) @@ -57,8 +64,9 @@ void setup() throws Exception { .withStartupTargetPeerCount(0) .withValidatorProposerDefaultFeeRecipient( "0xFE3B557E8Fb62b89F4916B721be55cEb828dBd73") - .withExecutionEngine(eth1Node) + .withExecutionEngineEndpoint(eth1Node.getInternalEngineWebsocketsRpcUrl()) .withJwtSecretFile(jwtFile) + .withInitialState(genesis) .withReadOnlyKeystorePath(validatorKeystores) .build()); tekuNode.start(); @@ -74,7 +82,7 @@ void shouldPassMergeTransitionUsingWebsocketsEngine() { private TekuNodeConfigBuilder configureTekuNode(final int genesisTime) throws IOException { return TekuNodeConfigBuilder.createBeaconNode() - .withTotalTerminalDifficulty(10001) + .withTerminalBlockHash(DEFAULT_EL_GENESIS_HASH, 1) .withBellatrixEpoch(UInt64.ONE) .withGenesisTime(genesisTime); } diff --git a/acceptance-tests/src/testFixtures/java/tech/pegasys/teku/test/acceptance/dsl/AcceptanceTestBase.java b/acceptance-tests/src/testFixtures/java/tech/pegasys/teku/test/acceptance/dsl/AcceptanceTestBase.java index 222f8036ac5..eba54a3a292 100644 --- a/acceptance-tests/src/testFixtures/java/tech/pegasys/teku/test/acceptance/dsl/AcceptanceTestBase.java +++ b/acceptance-tests/src/testFixtures/java/tech/pegasys/teku/test/acceptance/dsl/AcceptanceTestBase.java @@ -38,6 +38,9 @@ public class AcceptanceTestBase { System.setProperty("org.apache.tuweni.crypto.useSodium", "false"); } + public static final String DEFAULT_EL_GENESIS_HASH = + "0x14e88057b0b7538a8205cb07726a0de03dd69d9a70e88bcffae15ca3fc6b5215"; + private final List nodes = new ArrayList<>(); private final Network network = Network.newNetwork(); diff --git a/acceptance-tests/src/testFixtures/java/tech/pegasys/teku/test/acceptance/dsl/BesuNode.java b/acceptance-tests/src/testFixtures/java/tech/pegasys/teku/test/acceptance/dsl/BesuNode.java index 702d155fa58..3513d5f2492 100644 --- a/acceptance-tests/src/testFixtures/java/tech/pegasys/teku/test/acceptance/dsl/BesuNode.java +++ b/acceptance-tests/src/testFixtures/java/tech/pegasys/teku/test/acceptance/dsl/BesuNode.java @@ -152,6 +152,10 @@ public String getInternalEngineJsonRpcUrl() { return "http://" + nodeAlias + ":" + ENGINE_JSON_RPC_PORT; } + public String getInternalEngineWebsocketsRpcUrl() { + return "ws://" + nodeAlias + ":" + ENGINE_JSON_RPC_PORT; + } + private String getInternalP2pUrl(final String nodeId) { return "enode://" + nodeId + "@" + getInternalIpAddress() + ":" + P2P_PORT; } diff --git a/acceptance-tests/src/testFixtures/java/tech/pegasys/teku/test/acceptance/dsl/TekuNodeConfigBuilder.java b/acceptance-tests/src/testFixtures/java/tech/pegasys/teku/test/acceptance/dsl/TekuNodeConfigBuilder.java index 77a645e8799..31e0ad31bd7 100644 --- a/acceptance-tests/src/testFixtures/java/tech/pegasys/teku/test/acceptance/dsl/TekuNodeConfigBuilder.java +++ b/acceptance-tests/src/testFixtures/java/tech/pegasys/teku/test/acceptance/dsl/TekuNodeConfigBuilder.java @@ -184,8 +184,12 @@ public TekuNodeConfigBuilder withTrustedSetupFromClasspath(final String trustedS public TekuNodeConfigBuilder withExecutionEngine(final BesuNode node) { mustBe(NodeType.BEACON_NODE); - LOG.debug("ee-endpoint={}", node.getInternalEngineJsonRpcUrl()); - configMap.put("ee-endpoint", node.getInternalEngineJsonRpcUrl()); + return withExecutionEngineEndpoint(node.getInternalEngineJsonRpcUrl()); + } + + public TekuNodeConfigBuilder withExecutionEngineEndpoint(final String engineEndpointUrl) { + LOG.debug("ee-endpoint={}", engineEndpointUrl); + configMap.put("ee-endpoint", engineEndpointUrl); return this; } @@ -197,19 +201,24 @@ public TekuNodeConfigBuilder withJwtSecretFile(final URL jwtFile) throws Excepti return this; } - public TekuNodeConfigBuilder withTerminalBlockHash(final String terminalBlockHash) { + public TekuNodeConfigBuilder withTerminalBlockHash( + final String terminalBlockHash, final long terminalBlockHashEpoch) { mustBe(NodeType.BEACON_NODE); LOG.debug("Xnetwork-terminal-block-hash-override={}", terminalBlockHash); + LOG.debug("Xnetwork-terminal-block-hash-epoch-override={}", terminalBlockHashEpoch); configMap.put("Xnetwork-terminal-block-hash-override", terminalBlockHash); + configMap.put("Xnetwork-terminal-block-hash-epoch-override", terminalBlockHashEpoch); specConfigModifier = specConfigModifier.andThen( specConfigBuilder -> specConfigBuilder.bellatrixBuilder( bellatrixBuilder -> - bellatrixBuilder.terminalBlockHash( - Bytes32.fromHexString(terminalBlockHash)))); + bellatrixBuilder + .terminalBlockHash(Bytes32.fromHexString(terminalBlockHash)) + .terminalBlockHashActivationEpoch( + UInt64.valueOf(terminalBlockHashEpoch)))); return this; } diff --git a/acceptance-tests/src/testFixtures/resources/besu/mergedGenesis.json b/acceptance-tests/src/testFixtures/resources/besu/mergedGenesis.json index d63088f7038..2ee4b3e9877 100644 --- a/acceptance-tests/src/testFixtures/resources/besu/mergedGenesis.json +++ b/acceptance-tests/src/testFixtures/resources/besu/mergedGenesis.json @@ -13,6 +13,7 @@ "londonBlock": 0, "parisBlock": 0, "terminalTotalDifficulty": 0, + "terminalTotalDifficultyPassed": true, "contractSizeLimit": 2147483647, "ethash": { "fixeddifficulty": 100 diff --git a/acceptance-tests/src/testFixtures/resources/besu/preMergeGenesis.json b/acceptance-tests/src/testFixtures/resources/besu/preMergeGenesis.json index e4d2bc28a5f..081f14516f5 100644 --- a/acceptance-tests/src/testFixtures/resources/besu/preMergeGenesis.json +++ b/acceptance-tests/src/testFixtures/resources/besu/preMergeGenesis.json @@ -12,7 +12,7 @@ "berlinBlock": 0, "londonBlock": 0, "preMergeForkBlock": 0, - "terminalTotalDifficulty": 10001, + "terminalTotalDifficulty": 0, "contractSizeLimit": 2147483647, "ethash": { "fixeddifficulty": 100 diff --git a/beacon/sync/src/testFixtures/java/tech/pegasys/teku/beacon/sync/SyncingNodeManager.java b/beacon/sync/src/testFixtures/java/tech/pegasys/teku/beacon/sync/SyncingNodeManager.java index 5256e4a6e7a..0c9e13a92f2 100644 --- a/beacon/sync/src/testFixtures/java/tech/pegasys/teku/beacon/sync/SyncingNodeManager.java +++ b/beacon/sync/src/testFixtures/java/tech/pegasys/teku/beacon/sync/SyncingNodeManager.java @@ -52,7 +52,6 @@ import tech.pegasys.teku.spec.TestSpecFactory; import tech.pegasys.teku.spec.datastructures.attestation.ValidatableAttestation; import tech.pegasys.teku.spec.datastructures.blocks.SignedBeaconBlock; -import tech.pegasys.teku.spec.executionlayer.ExecutionLayerChannel; import tech.pegasys.teku.spec.executionlayer.ExecutionLayerChannelStub; import tech.pegasys.teku.spec.logic.common.statetransition.results.BlockImportResult; import tech.pegasys.teku.statetransition.BeaconChainUtil; @@ -115,7 +114,7 @@ public static SyncingNodeManager create( chainUtil.initializeStorage(); final MergeTransitionBlockValidator transitionBlockValidator = - new MergeTransitionBlockValidator(spec, recentChainData, ExecutionLayerChannel.NOOP); + new MergeTransitionBlockValidator(spec, recentChainData); final ForkChoice forkChoice = new ForkChoice( diff --git a/data/beaconrestapi/src/integration-test/java/tech/pegasys/teku/beaconrestapi/AbstractDataBackedRestAPIIntegrationTest.java b/data/beaconrestapi/src/integration-test/java/tech/pegasys/teku/beaconrestapi/AbstractDataBackedRestAPIIntegrationTest.java index ed9f5d3a216..84d7396268f 100644 --- a/data/beaconrestapi/src/integration-test/java/tech/pegasys/teku/beaconrestapi/AbstractDataBackedRestAPIIntegrationTest.java +++ b/data/beaconrestapi/src/integration-test/java/tech/pegasys/teku/beaconrestapi/AbstractDataBackedRestAPIIntegrationTest.java @@ -67,7 +67,6 @@ import tech.pegasys.teku.spec.datastructures.operations.SignedBlsToExecutionChange; import tech.pegasys.teku.spec.datastructures.operations.SignedVoluntaryExit; import tech.pegasys.teku.spec.executionlayer.ExecutionLayerBlockProductionManager; -import tech.pegasys.teku.spec.executionlayer.ExecutionLayerChannel; import tech.pegasys.teku.spec.generator.ChainBuilder; import tech.pegasys.teku.statetransition.MappedOperationPool; import tech.pegasys.teku.statetransition.OperationPool; @@ -200,8 +199,7 @@ private void setupStorage( recentChainData, BlobSidecarManager.NOOP, new NoopForkChoiceNotifier(), - new MergeTransitionBlockValidator( - spec, recentChainData, ExecutionLayerChannel.NOOP), + new MergeTransitionBlockValidator(spec, recentChainData), storageSystem.getMetricsSystem()); final Function> beaconBlockSchemaSupplier = slot -> spec.atSlot(slot).getSchemaDefinitions().getBeaconBlockBodySchema(); diff --git a/eth-benchmark-tests/src/jmh/java/tech/pegasys/teku/benchmarks/EpochTransitionBenchmark.java b/eth-benchmark-tests/src/jmh/java/tech/pegasys/teku/benchmarks/EpochTransitionBenchmark.java index 6caeac08de4..364455e8132 100644 --- a/eth-benchmark-tests/src/jmh/java/tech/pegasys/teku/benchmarks/EpochTransitionBenchmark.java +++ b/eth-benchmark-tests/src/jmh/java/tech/pegasys/teku/benchmarks/EpochTransitionBenchmark.java @@ -120,7 +120,7 @@ public void init() throws Exception { recentChainData = MemoryOnlyRecentChainData.create(spec); final MergeTransitionBlockValidator transitionBlockValidator = - new MergeTransitionBlockValidator(spec, recentChainData, ExecutionLayerChannel.NOOP); + new MergeTransitionBlockValidator(spec, recentChainData); ForkChoice forkChoice = new ForkChoice( spec, diff --git a/eth-benchmark-tests/src/jmh/java/tech/pegasys/teku/benchmarks/ProfilingRun.java b/eth-benchmark-tests/src/jmh/java/tech/pegasys/teku/benchmarks/ProfilingRun.java index 4e2d92dde26..86fe524abce 100644 --- a/eth-benchmark-tests/src/jmh/java/tech/pegasys/teku/benchmarks/ProfilingRun.java +++ b/eth-benchmark-tests/src/jmh/java/tech/pegasys/teku/benchmarks/ProfilingRun.java @@ -100,7 +100,7 @@ public void importBlocks() throws Exception { RecentChainData recentChainData = MemoryOnlyRecentChainData.create(spec); recentChainData.initializeFromGenesis(initialState, UInt64.ZERO); final MergeTransitionBlockValidator transitionBlockValidator = - new MergeTransitionBlockValidator(spec, recentChainData, ExecutionLayerChannel.NOOP); + new MergeTransitionBlockValidator(spec, recentChainData); ForkChoice forkChoice = new ForkChoice( spec, @@ -195,7 +195,7 @@ public void importBlocksMemProfiling() throws Exception { recentChainData.initializeFromGenesis(initialState, UInt64.ZERO); initialState = null; final MergeTransitionBlockValidator transitionBlockValidator = - new MergeTransitionBlockValidator(spec, recentChainData, ExecutionLayerChannel.NOOP); + new MergeTransitionBlockValidator(spec, recentChainData); ForkChoice forkChoice = new ForkChoice( spec, diff --git a/eth-benchmark-tests/src/jmh/java/tech/pegasys/teku/benchmarks/TransitionBenchmark.java b/eth-benchmark-tests/src/jmh/java/tech/pegasys/teku/benchmarks/TransitionBenchmark.java index 295b2062c8b..637831235e8 100644 --- a/eth-benchmark-tests/src/jmh/java/tech/pegasys/teku/benchmarks/TransitionBenchmark.java +++ b/eth-benchmark-tests/src/jmh/java/tech/pegasys/teku/benchmarks/TransitionBenchmark.java @@ -97,7 +97,7 @@ public void init() throws Exception { wsValidator = WeakSubjectivityFactory.lenientValidator(); recentChainData = MemoryOnlyRecentChainData.create(spec); final MergeTransitionBlockValidator transitionBlockValidator = - new MergeTransitionBlockValidator(spec, recentChainData, ExecutionLayerChannel.NOOP); + new MergeTransitionBlockValidator(spec, recentChainData); ForkChoice forkChoice = new ForkChoice( spec, diff --git a/eth-reference-tests/src/referenceTest/java/tech/pegasys/teku/reference/phase0/forkchoice/ForkChoiceTestExecutor.java b/eth-reference-tests/src/referenceTest/java/tech/pegasys/teku/reference/phase0/forkchoice/ForkChoiceTestExecutor.java index 0b0f9570da4..1452fd972b2 100644 --- a/eth-reference-tests/src/referenceTest/java/tech/pegasys/teku/reference/phase0/forkchoice/ForkChoiceTestExecutor.java +++ b/eth-reference-tests/src/referenceTest/java/tech/pegasys/teku/reference/phase0/forkchoice/ForkChoiceTestExecutor.java @@ -20,7 +20,6 @@ import com.google.common.collect.ImmutableMap; import java.io.IOException; -import java.nio.ByteOrder; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -32,7 +31,6 @@ import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.bytes.Bytes32; import org.apache.tuweni.ssz.SSZ; -import org.apache.tuweni.units.bigints.UInt256; import org.assertj.core.api.Condition; import org.opentest4j.TestAbortedException; import tech.pegasys.teku.bls.BLSSignature; @@ -59,7 +57,6 @@ import tech.pegasys.teku.spec.datastructures.state.AnchorPoint; import tech.pegasys.teku.spec.datastructures.state.Checkpoint; import tech.pegasys.teku.spec.datastructures.state.beaconstate.BeaconState; -import tech.pegasys.teku.spec.executionlayer.ExecutionLayerChannel; import tech.pegasys.teku.spec.executionlayer.ExecutionLayerChannelStub; import tech.pegasys.teku.spec.executionlayer.ExecutionPayloadStatus; import tech.pegasys.teku.spec.executionlayer.PayloadStatus; @@ -87,7 +84,7 @@ public class ForkChoiceTestExecutor implements TestExecutor { .put("fork_choice/ex_ante", new ForkChoiceTestExecutor()) .put("fork_choice/reorg", new ForkChoiceTestExecutor()) .put("fork_choice/on_block", new ForkChoiceTestExecutor()) - .put("fork_choice/on_merge_block", new ForkChoiceTestExecutor()) + .put("fork_choice/on_merge_block", IGNORE_TESTS) // TTD Logic is deprecated .put("fork_choice/withholding", new ForkChoiceTestExecutor()) .put("sync/optimistic", new ForkChoiceTestExecutor()) .put("fork_choice/should_override_forkchoice_update", new ForkChoiceTestExecutor()) @@ -123,7 +120,7 @@ spec, new SignedBlockAndState(anchorBlock, anchorState)), spec.getSlotStartTime(anchorBlock.getSlot(), anchorState.getGenesisTime())); final MergeTransitionBlockValidator transitionBlockValidator = - new MergeTransitionBlockValidator(spec, recentChainData, ExecutionLayerChannel.NOOP); + new MergeTransitionBlockValidator(spec, recentChainData); final InlineEventThread eventThread = new InlineEventThread(); final KZG kzg = KzgRetriever.getKzgWithLoadedTrustedSetup(spec, testDefinition.getConfigName()); final StubBlobSidecarManager blobSidecarManager = new StubBlobSidecarManager(kzg); @@ -244,14 +241,9 @@ private PowBlock parsePowBlock(final Bytes data) { reader -> { final Bytes32 blockHash = Bytes32.wrap(reader.readFixedBytes(Bytes32.SIZE)); final Bytes32 parentHash = Bytes32.wrap(reader.readFixedBytes(Bytes32.SIZE)); - final UInt256 totalDifficulty = - UInt256.valueOf( - reader - .readFixedBytes(Bytes32.SIZE) - .toUnsignedBigInteger(ByteOrder.LITTLE_ENDIAN)); // We don't get a timestamp but as long as it's in the past that's fine final UInt64 timestamp = UInt64.ZERO; - return new PowBlock(blockHash, parentHash, totalDifficulty, timestamp); + return new PowBlock(blockHash, parentHash, timestamp); }); } diff --git a/ethereum/executionclient/src/main/java/tech/pegasys/teku/ethereum/executionclient/web3j/Web3JExecutionEngineClient.java b/ethereum/executionclient/src/main/java/tech/pegasys/teku/ethereum/executionclient/web3j/Web3JExecutionEngineClient.java index 6eed83dd565..0f8f693c58c 100644 --- a/ethereum/executionclient/src/main/java/tech/pegasys/teku/ethereum/executionclient/web3j/Web3JExecutionEngineClient.java +++ b/ethereum/executionclient/src/main/java/tech/pegasys/teku/ethereum/executionclient/web3j/Web3JExecutionEngineClient.java @@ -23,7 +23,6 @@ import java.util.Optional; import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.bytes.Bytes32; -import org.apache.tuweni.units.bigints.UInt256; import org.web3j.protocol.core.DefaultBlockParameterName; import org.web3j.protocol.core.Request; import org.web3j.protocol.core.methods.response.EthBlock; @@ -87,7 +86,6 @@ private static PowBlock eth1BlockToPowBlock(final EthBlock.Block eth1Block) { : new PowBlock( Bytes32.fromHexStringStrict(eth1Block.getHash()), Bytes32.fromHexStringStrict(eth1Block.getParentHash()), - UInt256.valueOf(eth1Block.getTotalDifficulty()), UInt64.valueOf(eth1Block.getTimestamp())); } diff --git a/ethereum/executionlayer/src/test/java/tech/pegasys/teku/ethereum/executionlayer/ExecutionHandlerClientTest.java b/ethereum/executionlayer/src/test/java/tech/pegasys/teku/ethereum/executionlayer/ExecutionHandlerClientTest.java index efa5cd76940..e92a3123c49 100644 --- a/ethereum/executionlayer/src/test/java/tech/pegasys/teku/ethereum/executionlayer/ExecutionHandlerClientTest.java +++ b/ethereum/executionlayer/src/test/java/tech/pegasys/teku/ethereum/executionlayer/ExecutionHandlerClientTest.java @@ -52,10 +52,7 @@ void eth1GetPowBlock_shouldCallExecutionClient() { private PowBlock createPowBlock(final Bytes32 blockHash) { return new PowBlock( - blockHash, - dataStructureUtil.randomBytes32(), - dataStructureUtil.randomUInt256(), - dataStructureUtil.randomUInt64()); + blockHash, dataStructureUtil.randomBytes32(), dataStructureUtil.randomUInt64()); } @SuppressWarnings("FutureReturnValueIgnored") diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/execution/PowBlock.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/execution/PowBlock.java index cdeebd85868..d5ab6624d55 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/execution/PowBlock.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/execution/PowBlock.java @@ -15,24 +15,17 @@ import com.google.common.base.MoreObjects; import org.apache.tuweni.bytes.Bytes32; -import org.apache.tuweni.units.bigints.UInt256; import tech.pegasys.teku.infrastructure.unsigned.UInt64; public class PowBlock { private final Bytes32 blockHash; private final Bytes32 parentHash; - private final UInt256 totalDifficulty; private final UInt64 blockTimestamp; - public PowBlock( - final Bytes32 blockHash, - final Bytes32 parentHash, - final UInt256 totalDifficulty, - final UInt64 blockTimestamp) { + public PowBlock(final Bytes32 blockHash, final Bytes32 parentHash, final UInt64 blockTimestamp) { this.blockHash = blockHash; this.parentHash = parentHash; - this.totalDifficulty = totalDifficulty; this.blockTimestamp = blockTimestamp; } @@ -44,10 +37,6 @@ public Bytes32 getParentHash() { return parentHash; } - public UInt256 getTotalDifficulty() { - return totalDifficulty; - } - public UInt64 getBlockTimestamp() { return blockTimestamp; } @@ -57,7 +46,6 @@ public String toString() { return MoreObjects.toStringHelper(this) .add("blockHash", blockHash) .add("parentHash", parentHash) - .add("totalDifficulty", totalDifficulty) .add("blockTimestamp", blockTimestamp) .toString(); } diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/executionlayer/ExecutionLayerChannelStub.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/executionlayer/ExecutionLayerChannelStub.java index 62932ca4235..5ff539161d7 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/executionlayer/ExecutionLayerChannelStub.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/executionlayer/ExecutionLayerChannelStub.java @@ -298,7 +298,6 @@ public SafeFuture engineGetPayload( new PowBlock( executionPayload.getBlockHash(), executionPayload.getParentHash(), - UInt256.ZERO, payloadAttributes.getTimestamp())); headAndAttrs.currentExecutionPayload = Optional.of(executionPayload); @@ -586,11 +585,8 @@ private void prepareTransitionBlocks(final UInt64 bellatrixActivationTime) { terminalBlockHash = configTerminalBlockHash; } - terminalBlockParent = - new PowBlock(TERMINAL_BLOCK_PARENT_HASH, Bytes32.ZERO, UInt256.ZERO, UInt64.ZERO); - terminalBlock = - new PowBlock( - terminalBlockHash, TERMINAL_BLOCK_PARENT_HASH, terminalTotalDifficulty, transitionTime); + terminalBlockParent = new PowBlock(TERMINAL_BLOCK_PARENT_HASH, Bytes32.ZERO, UInt64.ZERO); + terminalBlock = new PowBlock(terminalBlockHash, TERMINAL_BLOCK_PARENT_HASH, transitionTime); } private HeadAndAttributes getCachedHeadAndAttributes( diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/bellatrix/helpers/BellatrixTransitionHelpers.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/bellatrix/helpers/BellatrixTransitionHelpers.java index 81ab65b1d84..21c545494e6 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/bellatrix/helpers/BellatrixTransitionHelpers.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/bellatrix/helpers/BellatrixTransitionHelpers.java @@ -16,13 +16,10 @@ import static tech.pegasys.teku.infrastructure.async.SafeFuture.completedFuture; import java.util.Optional; -import org.apache.tuweni.bytes.Bytes32; import tech.pegasys.teku.infrastructure.async.SafeFuture; import tech.pegasys.teku.infrastructure.unsigned.UInt64; import tech.pegasys.teku.spec.config.SpecConfigBellatrix; import tech.pegasys.teku.spec.datastructures.execution.ExecutionPayloadSummary; -import tech.pegasys.teku.spec.datastructures.execution.PowBlock; -import tech.pegasys.teku.spec.executionlayer.ExecutionLayerChannel; import tech.pegasys.teku.spec.executionlayer.PayloadStatus; public class BellatrixTransitionHelpers { @@ -46,21 +43,19 @@ public BellatrixTransitionHelpers( *

That is, the PoW chain stops as soon as one block has exceeded TTD and from that point on * merges into the beacon chain. * - * @param executionLayer the execution layer to use for verification * @param executionPayloadSummary the first non-empty payload on the beacon chain * @param blockSlot the slot of the block the executionPayload is from * @return a future containing the validation result for the execution payload */ public SafeFuture validateMergeBlock( - final ExecutionLayerChannel executionLayer, - final ExecutionPayloadSummary executionPayloadSummary, - final UInt64 blockSlot) { + final ExecutionPayloadSummary executionPayloadSummary, final UInt64 blockSlot) { if (!specConfig.getTerminalBlockHash().isZero()) { return validateWithTerminalBlockHash(executionPayloadSummary, blockSlot); } - return executionLayer - .eth1GetPowBlock(executionPayloadSummary.getParentHash()) - .thenCompose(maybePowBlock -> validatePowBlock(executionLayer, maybePowBlock)); + + return SafeFuture.completedFuture( + PayloadStatus.invalid( + Optional.empty(), Optional.of("Total difficulty check is no more supported"))); } private SafeFuture validateWithTerminalBlockHash( @@ -76,44 +71,7 @@ private SafeFuture validateWithTerminalBlockHash( return SafeFuture.completedFuture(PayloadStatus.VALID); } - private SafeFuture validatePowBlock( - final ExecutionLayerChannel executionLayer, final Optional maybePowBlock) { - if (maybePowBlock.isEmpty()) { - return completedFuture(PayloadStatus.SYNCING); - } - final PowBlock powBlock = maybePowBlock.get(); - if (isBelowTotalDifficulty(powBlock)) { - return invalid("PowBlock has not reached terminal total difficulty"); - } - return validateParentPowBlock(executionLayer, powBlock.getParentHash()); - } - private static SafeFuture invalid(final String message) { return completedFuture(PayloadStatus.invalid(Optional.empty(), Optional.of(message))); } - - private SafeFuture validateParentPowBlock( - final ExecutionLayerChannel executionLayer, final Bytes32 parentBlockHash) { - // fast check for genesis - if (parentBlockHash.isZero()) { - return completedFuture(PayloadStatus.VALID); - } - return executionLayer - .eth1GetPowBlock(parentBlockHash) - .thenCompose( - maybeParentPowBlock -> { - if (maybeParentPowBlock.isEmpty()) { - return completedFuture(PayloadStatus.SYNCING); - } - final PowBlock parentPowBlock = maybeParentPowBlock.get(); - if (!isBelowTotalDifficulty(parentPowBlock)) { - return invalid("Parent PowBlock exceeds terminal total difficulty"); - } - return completedFuture(PayloadStatus.VALID); - }); - } - - private boolean isBelowTotalDifficulty(final PowBlock powBlock) { - return powBlock.getTotalDifficulty().lessThan(specConfig.getTerminalTotalDifficulty()); - } } diff --git a/ethereum/spec/src/test/java/tech/pegasys/teku/spec/logic/versions/bellatrix/helpers/BellatrixTransitionHelpersTest.java b/ethereum/spec/src/test/java/tech/pegasys/teku/spec/logic/versions/bellatrix/helpers/BellatrixTransitionHelpersTest.java index f4139234907..ddbaaa42537 100644 --- a/ethereum/spec/src/test/java/tech/pegasys/teku/spec/logic/versions/bellatrix/helpers/BellatrixTransitionHelpersTest.java +++ b/ethereum/spec/src/test/java/tech/pegasys/teku/spec/logic/versions/bellatrix/helpers/BellatrixTransitionHelpersTest.java @@ -14,24 +14,15 @@ package tech.pegasys.teku.spec.logic.versions.bellatrix.helpers; import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verifyNoMoreInteractions; -import static org.mockito.Mockito.when; -import static tech.pegasys.teku.infrastructure.async.SafeFuture.completedFuture; import java.util.Optional; import org.apache.tuweni.bytes.Bytes32; -import org.apache.tuweni.units.bigints.UInt256; -import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import tech.pegasys.teku.infrastructure.async.SafeFuture; import tech.pegasys.teku.infrastructure.unsigned.UInt64; import tech.pegasys.teku.spec.Spec; import tech.pegasys.teku.spec.TestSpecFactory; import tech.pegasys.teku.spec.datastructures.execution.ExecutionPayload; -import tech.pegasys.teku.spec.datastructures.execution.PowBlock; -import tech.pegasys.teku.spec.executionlayer.ExecutionLayerChannel; import tech.pegasys.teku.spec.executionlayer.ExecutionPayloadStatus; import tech.pegasys.teku.spec.executionlayer.PayloadStatus; import tech.pegasys.teku.spec.util.DataStructureUtil; @@ -40,52 +31,15 @@ class BellatrixTransitionHelpersTest { private final Spec spec = TestSpecFactory.createMinimalBellatrix(); private final DataStructureUtil dataStructureUtil = new DataStructureUtil(spec); - private final ExecutionLayerChannel executionLayer = mock(ExecutionLayerChannel.class); - private final UInt256 terminalDifficulty = - spec.getGenesisSpecConfig().toVersionBellatrix().orElseThrow().getTerminalTotalDifficulty(); - private final UInt64 slot = dataStructureUtil.randomUInt64(); - private final ExecutionPayload payload = dataStructureUtil.randomExecutionPayload(); - @BeforeEach - void setUp() { - when(executionLayer.eth1GetPowBlock(any())).thenReturn(completedFuture(Optional.empty())); - } - - @Test - void shouldBeSyncingIfPowBlockIsNotAvailable() { - assertPayloadResultStatus(ExecutionPayloadStatus.SYNCING); - } - - @Test - void shouldBeSyncingIfPowParentIsNotAvailable() { - withPowBlock(payload.getParentHash(), terminalDifficulty); - - assertPayloadResultStatus(ExecutionPayloadStatus.SYNCING); - } - - @Test - void shouldBeInvalidIfTotalDifficultyNotReached() { - withPowBlock(payload.getParentHash(), terminalDifficulty.subtract(1)); - - assertPayloadResultStatus(ExecutionPayloadStatus.INVALID); - } - - @Test - void shouldBeInvalidIfParentTotalDifficultyIsReached() { - final PowBlock powBlock = withPowBlock(payload.getParentHash(), terminalDifficulty.plus(1)); - withPowBlock(powBlock.getParentHash(), terminalDifficulty); - - assertPayloadResultStatus(ExecutionPayloadStatus.INVALID); - } - @Test - void shouldBeValidIfTerminalDifficultyConditionsMet() { - final PowBlock powBlock = withPowBlock(payload.getParentHash(), terminalDifficulty.plus(1)); - withPowBlock(powBlock.getParentHash(), terminalDifficulty.subtract(1)); - - assertThat(validateMergeBlock()).isCompletedWithValue(PayloadStatus.VALID); + void shouldBeInvalidForTTDNotSupported() { + assertThat(validateMergeBlock()) + .isCompletedWithValue( + PayloadStatus.invalid( + Optional.empty(), Optional.of("Total difficulty check is no more supported"))); } @Test @@ -97,9 +51,7 @@ void shouldBeValidWhenTerminalBlockHashMatchesInActivationEpoch() { spec.getGenesisSpec() .getBellatrixTransitionHelpers() .orElseThrow() - .validateMergeBlock(executionLayer, payload, blockSlot); - // Verify EL is never called if hash is configured and matches - verifyNoMoreInteractions(executionLayer); + .validateMergeBlock(payload, blockSlot); assertPayloadResultStatus(result, ExecutionPayloadStatus.VALID); } @@ -112,7 +64,7 @@ void shouldBeValidWhenTerminalBlockHashMatchesAfterActivationEpoch() { spec.getGenesisSpec() .getBellatrixTransitionHelpers() .orElseThrow() - .validateMergeBlock(executionLayer, payload, blockSlot); + .validateMergeBlock(payload, blockSlot); assertPayloadResultStatus(result, ExecutionPayloadStatus.VALID); } @@ -125,7 +77,7 @@ void shouldBeInvalidWhenTerminalBlockHashDoesNotMatch() { spec.getGenesisSpec() .getBellatrixTransitionHelpers() .orElseThrow() - .validateMergeBlock(executionLayer, payload, blockSlot); + .validateMergeBlock(payload, blockSlot); assertPayloadResultStatus(result, ExecutionPayloadStatus.INVALID); } @@ -138,7 +90,7 @@ void shouldBeInvalidWhenBeforeActivationEpoch() { spec.getGenesisSpec() .getBellatrixTransitionHelpers() .orElseThrow() - .validateMergeBlock(executionLayer, payload, blockSlot); + .validateMergeBlock(payload, blockSlot); assertPayloadResultStatus(result, ExecutionPayloadStatus.INVALID); } @@ -152,23 +104,11 @@ private Spec createSpec( .terminalBlockHashActivationEpoch(terminalBlockHashActivationEpoch))); } - private PowBlock withPowBlock(final Bytes32 hash, final UInt256 totalDifficulty) { - final PowBlock powBlock = - new PowBlock(hash, dataStructureUtil.randomBytes32(), totalDifficulty, UInt64.ZERO); - when(executionLayer.eth1GetPowBlock(powBlock.getBlockHash())) - .thenReturn(completedFuture(Optional.of(powBlock))); - return powBlock; - } - - private void assertPayloadResultStatus(final ExecutionPayloadStatus expectedStatus) { - assertPayloadResultStatus(validateMergeBlock(), expectedStatus); - } - private SafeFuture validateMergeBlock() { return spec.getGenesisSpec() .getBellatrixTransitionHelpers() .orElseThrow() - .validateMergeBlock(executionLayer, payload, slot); + .validateMergeBlock(payload, slot); } private void assertPayloadResultStatus( diff --git a/ethereum/statetransition/src/integration-test/java/tech/pegasys/teku/statetransition/attestation/AttestationManagerIntegrationTest.java b/ethereum/statetransition/src/integration-test/java/tech/pegasys/teku/statetransition/attestation/AttestationManagerIntegrationTest.java index dddd5fc0d34..c9a5fe42db7 100644 --- a/ethereum/statetransition/src/integration-test/java/tech/pegasys/teku/statetransition/attestation/AttestationManagerIntegrationTest.java +++ b/ethereum/statetransition/src/integration-test/java/tech/pegasys/teku/statetransition/attestation/AttestationManagerIntegrationTest.java @@ -40,7 +40,6 @@ import tech.pegasys.teku.spec.datastructures.operations.SignedAggregateAndProof; import tech.pegasys.teku.spec.datastructures.state.Fork; import tech.pegasys.teku.spec.datastructures.state.ForkInfo; -import tech.pegasys.teku.spec.executionlayer.ExecutionLayerChannel; import tech.pegasys.teku.spec.generator.AggregateGenerator; import tech.pegasys.teku.statetransition.blobs.BlobSidecarManager; import tech.pegasys.teku.statetransition.forkchoice.ForkChoice; @@ -77,7 +76,7 @@ class AttestationManagerIntegrationTest { new AggregatingAttestationPool( spec, recentChainData, new NoOpMetricsSystem(), DEFAULT_MAXIMUM_ATTESTATION_COUNT); private final MergeTransitionBlockValidator transitionBlockValidator = - new MergeTransitionBlockValidator(spec, recentChainData, ExecutionLayerChannel.NOOP); + new MergeTransitionBlockValidator(spec, recentChainData); private final ForkChoice forkChoice = new ForkChoice( spec, diff --git a/ethereum/statetransition/src/main/java/tech/pegasys/teku/statetransition/forkchoice/ForkChoicePayloadExecutor.java b/ethereum/statetransition/src/main/java/tech/pegasys/teku/statetransition/forkchoice/ForkChoicePayloadExecutor.java index 0aef2b68f04..d29ed28164a 100644 --- a/ethereum/statetransition/src/main/java/tech/pegasys/teku/statetransition/forkchoice/ForkChoicePayloadExecutor.java +++ b/ethereum/statetransition/src/main/java/tech/pegasys/teku/statetransition/forkchoice/ForkChoicePayloadExecutor.java @@ -50,9 +50,7 @@ public static ForkChoicePayloadExecutor create( final SignedBeaconBlock block, final ExecutionLayerChannel executionLayer) { return new ForkChoicePayloadExecutor( - block, - executionLayer, - new MergeTransitionBlockValidator(spec, recentChainData, executionLayer)); + block, executionLayer, new MergeTransitionBlockValidator(spec, recentChainData)); } public SafeFuture getExecutionResult() { diff --git a/ethereum/statetransition/src/main/java/tech/pegasys/teku/statetransition/forkchoice/MergeTransitionBlockValidator.java b/ethereum/statetransition/src/main/java/tech/pegasys/teku/statetransition/forkchoice/MergeTransitionBlockValidator.java index 03d3280d761..c4c69ec5650 100644 --- a/ethereum/statetransition/src/main/java/tech/pegasys/teku/statetransition/forkchoice/MergeTransitionBlockValidator.java +++ b/ethereum/statetransition/src/main/java/tech/pegasys/teku/statetransition/forkchoice/MergeTransitionBlockValidator.java @@ -30,7 +30,6 @@ import tech.pegasys.teku.spec.datastructures.execution.ExecutionPayloadSummary; import tech.pegasys.teku.spec.datastructures.execution.SlotAndExecutionPayloadSummary; import tech.pegasys.teku.spec.datastructures.state.beaconstate.BeaconState; -import tech.pegasys.teku.spec.executionlayer.ExecutionLayerChannel; import tech.pegasys.teku.spec.executionlayer.PayloadStatus; import tech.pegasys.teku.spec.logic.versions.bellatrix.helpers.BellatrixTransitionHelpers; import tech.pegasys.teku.storage.client.RecentChainData; @@ -42,15 +41,10 @@ public class MergeTransitionBlockValidator { private final Spec spec; private final RecentChainData recentChainData; - private final ExecutionLayerChannel executionLayer; - public MergeTransitionBlockValidator( - final Spec spec, - final RecentChainData recentChainData, - final ExecutionLayerChannel executionLayer) { + public MergeTransitionBlockValidator(final Spec spec, final RecentChainData recentChainData) { this.spec = spec; this.recentChainData = recentChainData; - this.executionLayer = executionLayer; } public SafeFuture verifyTransitionBlock( @@ -151,7 +145,7 @@ private SafeFuture verifyTransitionPayload( new IllegalStateException( "Attempting to validate a bellatrix block when spec does not have bellatrix transition helpers")); return bellatrixTransitionHelpers - .validateMergeBlock(executionLayer, executionPayload, slot) + .validateMergeBlock(executionPayload, slot) .exceptionally( error -> { LOG.error("Error while validating merge block", error); diff --git a/ethereum/statetransition/src/main/java/tech/pegasys/teku/statetransition/forkchoice/TerminalPowBlockMonitor.java b/ethereum/statetransition/src/main/java/tech/pegasys/teku/statetransition/forkchoice/TerminalPowBlockMonitor.java index 952a1362cc5..c799e6c2292 100644 --- a/ethereum/statetransition/src/main/java/tech/pegasys/teku/statetransition/forkchoice/TerminalPowBlockMonitor.java +++ b/ethereum/statetransition/src/main/java/tech/pegasys/teku/statetransition/forkchoice/TerminalPowBlockMonitor.java @@ -14,18 +14,14 @@ package tech.pegasys.teku.statetransition.forkchoice; import java.time.Duration; -import java.time.Instant; -import java.util.ArrayDeque; import java.util.Optional; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.apache.tuweni.bytes.Bytes32; -import org.apache.tuweni.units.bigints.UInt256; import tech.pegasys.teku.infrastructure.async.AsyncRunner; import tech.pegasys.teku.infrastructure.async.Cancellable; -import tech.pegasys.teku.infrastructure.async.SafeFuture; +import tech.pegasys.teku.infrastructure.exceptions.InvalidConfigurationException; import tech.pegasys.teku.infrastructure.logging.EventLogger; -import tech.pegasys.teku.infrastructure.time.TimeProvider; import tech.pegasys.teku.infrastructure.unsigned.UInt64; import tech.pegasys.teku.spec.Spec; import tech.pegasys.teku.spec.SpecMilestone; @@ -38,15 +34,8 @@ public class TerminalPowBlockMonitor { private static final Logger LOG = LogManager.getLogger(); - // number of samples to average out totalDifficulty - private static final int TD_SAMPLES = 40; - // minimum collected samples required for an accurate estimation - static final int TD_MIN_SAMPLES = 15; - // how many times we produce the event, based on polling period (secondsPerEth1Block) - private static final int ETA_EVENT_FREQUENCY_IN_POLLING_PERIODS = 5; private final EventLogger eventLogger; - private final TimeProvider timeProvider; private final ExecutionLayerChannel executionLayer; private final AsyncRunner asyncRunner; private Optional timer = Optional.empty(); @@ -55,31 +44,26 @@ public class TerminalPowBlockMonitor { private final ForkChoiceNotifier forkChoiceNotifier; private Duration pollingPeriod; - private int pollingCounter = 0; - private Optional maybeBlockHashTracking = Optional.empty(); + private Optional blockHashTracking = Optional.empty(); private Optional foundTerminalBlockHash = Optional.empty(); private SpecConfigBellatrix specConfigBellatrix; private boolean isBellatrixActive = false; private boolean inSync = true; - private final ArrayDeque lastPowBlocks = new ArrayDeque<>(); - public TerminalPowBlockMonitor( final ExecutionLayerChannel executionLayer, final Spec spec, final RecentChainData recentChainData, final ForkChoiceNotifier forkChoiceNotifier, final AsyncRunner asyncRunner, - final EventLogger eventLogger, - final TimeProvider timeProvider) { + final EventLogger eventLogger) { this.executionLayer = executionLayer; this.asyncRunner = asyncRunner; this.spec = spec; this.recentChainData = recentChainData; this.forkChoiceNotifier = forkChoiceNotifier; this.eventLogger = eventLogger; - this.timeProvider = timeProvider; } public synchronized void start() { @@ -95,6 +79,15 @@ public synchronized void start() { } specConfigBellatrix = maybeSpecConfigBellatrix.get(); + final boolean isMergeTransitionComplete = + isMergeTransitionComplete(recentChainData.getChainHead()); + if (!isMergeTransitionComplete + && spec.isMilestoneSupported(SpecMilestone.BELLATRIX) + && specConfigBellatrix.getTerminalBlockHash().isZero()) { + throw new InvalidConfigurationException( + "Bellatrix transition by terminal total difficulty is no more supported"); + } + pollingPeriod = Duration.ofSeconds(spec.getGenesisSpec().getConfig().getSecondsPerEth1Block()); timer = Optional.of( @@ -120,9 +113,6 @@ public synchronized boolean isRunning() { } public synchronized void onNodeSyncStateChanged(final boolean inSync) { - if (!this.inSync && inSync) { - lastPowBlocks.clear(); - } this.inSync = inSync; } @@ -135,8 +125,6 @@ private synchronized void monitor() { } } - pollingCounter++; - if (isMergeTransitionComplete(recentChainData.getChainHead())) { LOG.debug("MERGE is completed."); stop(); @@ -148,8 +136,7 @@ private synchronized void monitor() { return; } - maybeBlockHashTracking.ifPresentOrElse( - this::checkTerminalBlockByBlockHash, this::checkTerminalBlockByTTD); + checkTerminalBlockByBlockHash(blockHashTracking.orElseThrow()); } private Boolean isMergeTransitionComplete(final Optional chainHead) { @@ -179,18 +166,11 @@ private void initMergeState() { return; } - if (specConfigBellatrix.getTerminalBlockHash().isZero()) { - maybeBlockHashTracking = Optional.empty(); - LOG.debug( - "Enabling tracking by Block Total Difficulty {}", - specConfigBellatrix.getTerminalTotalDifficulty()); - } else { - maybeBlockHashTracking = Optional.of(specConfigBellatrix.getTerminalBlockHash()); - LOG.debug( - "Enabling tracking by Block Hash {} and Activation Epoch {}", - specConfigBellatrix.getTerminalBlockHash(), - specConfigBellatrix.getTerminalBlockHashActivationEpoch()); - } + blockHashTracking = Optional.of(specConfigBellatrix.getTerminalBlockHash()); + LOG.debug( + "Enabling tracking by Block Hash {} and Activation Epoch {}", + specConfigBellatrix.getTerminalBlockHash(), + specConfigBellatrix.getTerminalBlockHashActivationEpoch()); isBellatrixActive = true; } @@ -230,132 +210,6 @@ private void checkTerminalBlockByBlockHash(final Bytes32 blockHashTracking) { } } - private void checkTerminalBlockByTTD() { - executionLayer - .eth1GetPowChainHead() - .thenCompose( - powBlock -> { - if (powBlock == null) { - LOG.debug("checkTerminalBlockByTTD: Not checking - Latest pow block is null"); - return SafeFuture.COMPLETE; - } - final UInt256 totalDifficulty = powBlock.getTotalDifficulty(); - if (totalDifficulty.compareTo(specConfigBellatrix.getTerminalTotalDifficulty()) < 0) { - LOG.trace("checkTerminalBlockByTTD: Total Terminal Difficulty not reached."); - try { - checkTtdEta(powBlock); - } catch (Exception ex) { - LOG.debug("TTD ETA calculation exception", ex); - } - - return SafeFuture.COMPLETE; - } - if (powBlock.getBlockTimestamp().isGreaterThan(timeProvider.getTimeInSeconds())) { - LOG.trace("checkTerminalBlockByTTD: Chain head is in the future, ignoring for now"); - return SafeFuture.COMPLETE; - } - - // TTD is reached - if (notYetFound(powBlock.getBlockHash())) { - LOG.trace("checkTerminalBlockByTTD: Terminal Block found!"); - return validateTerminalBlockParentByTTD(powBlock) - .thenAccept( - valid -> { - if (valid) { - LOG.trace( - "Total Difficulty of Terminal Block parent has been validated."); - onTerminalPowBlockFound(powBlock.getBlockHash()); - } else { - LOG.warn( - "A candidate Terminal Block has been found but its parent has a Total Difficulty greater than terminal total difficulty. " - + "It is likely the Terminal Block has been already chosen by the network and The Merge will complete shortly."); - } - }); - } - return SafeFuture.COMPLETE; - }) - .finish(error -> LOG.error("Unexpected error while checking TTD", error)); - } - - private SafeFuture validateTerminalBlockParentByTTD(final PowBlock terminalBlock) { - // if it's genesis validate fast way - if (terminalBlock.getParentHash().isZero()) { - return SafeFuture.completedFuture(true); - } - return executionLayer - .eth1GetPowBlock(terminalBlock.getParentHash()) - .thenApply( - powBlock -> { - UInt256 parentTotalDifficulty = - powBlock - .orElseThrow( - () -> new IllegalStateException("Terminal Block Parent not found!")) - .getTotalDifficulty(); - return parentTotalDifficulty.lessThan( - specConfigBellatrix.getTerminalTotalDifficulty()); - }); - } - - private synchronized void checkTtdEta(final PowBlock currentHead) { - lastPowBlocks.addFirst(currentHead); - if (lastPowBlocks.size() > TD_SAMPLES) { - lastPowBlocks.removeLast(); - } - - if (!inSync - || lastPowBlocks.size() < TD_MIN_SAMPLES - || pollingCounter % ETA_EVENT_FREQUENCY_IN_POLLING_PERIODS != 0) { - return; - } - - final PowBlock latestBlock = lastPowBlocks.getFirst(); - final PowBlock oldestBlock = lastPowBlocks.getLast(); - - final UInt256 timeFrameInSeconds = - UInt256.valueOf( - latestBlock.getBlockTimestamp().minus(oldestBlock.getBlockTimestamp()).longValue()); - // Make sure we don't just have the same block multiple times. - if (timeFrameInSeconds.isZero()) { - return; - } - final UInt256 averageTdPerSeconds = - lastPowBlocks - .getFirst() - .getTotalDifficulty() - .subtract(lastPowBlocks.getLast().getTotalDifficulty()) - .divide(timeFrameInSeconds); - - if (averageTdPerSeconds.isZero()) { - return; - } - - final long now = timeProvider.getTimeInSeconds().longValue(); - - final UInt256 secondsToTTD = - specConfigBellatrix - .getTerminalTotalDifficulty() - .subtract(latestBlock.getTotalDifficulty()) - .divide(averageTdPerSeconds); - - // avoid negative time diff due to time discrepancy with EL - final UInt256 timeDiff = - UInt256.valueOf(Math.max(0, now - latestBlock.getBlockTimestamp().longValue())); - - final long secondsToTTDAdjusted; - // by subtracting timeDiff we could go after the merge and get negative result, - // let's avoid that. - if (secondsToTTD.greaterThan(timeDiff)) { - secondsToTTDAdjusted = secondsToTTD.subtract(timeDiff).toLong(); - } else { - secondsToTTDAdjusted = 0L; - } - - final Duration eta = Duration.ofSeconds(secondsToTTDAdjusted); - final Instant etaInstant = Instant.ofEpochSecond(now + secondsToTTDAdjusted); - - eventLogger.terminalPowBlockTtdEta(latestBlock.getTotalDifficulty(), eta, etaInstant); - } - private void onTerminalPowBlockFound(final Bytes32 blockHash) { foundTerminalBlockHash = Optional.of(blockHash); forkChoiceNotifier.onTerminalBlockReached(blockHash); diff --git a/ethereum/statetransition/src/test/java/tech/pegasys/teku/statetransition/block/BlockImporterTest.java b/ethereum/statetransition/src/test/java/tech/pegasys/teku/statetransition/block/BlockImporterTest.java index cc6e36ca465..b081353324b 100644 --- a/ethereum/statetransition/src/test/java/tech/pegasys/teku/statetransition/block/BlockImporterTest.java +++ b/ethereum/statetransition/src/test/java/tech/pegasys/teku/statetransition/block/BlockImporterTest.java @@ -96,7 +96,7 @@ public class BlockImporterTest { mock(WeakSubjectivityValidator.class); private final ForkChoiceNotifier forkChoiceNotifier = new NoopForkChoiceNotifier(); private final MergeTransitionBlockValidator transitionBlockValidator = - new MergeTransitionBlockValidator(spec, recentChainData, ExecutionLayerChannel.NOOP); + new MergeTransitionBlockValidator(spec, recentChainData); private final MetricsSystem metricsSystem = new StubMetricsSystem(); private final ForkChoice forkChoice = diff --git a/ethereum/statetransition/src/test/java/tech/pegasys/teku/statetransition/block/BlockManagerTest.java b/ethereum/statetransition/src/test/java/tech/pegasys/teku/statetransition/block/BlockManagerTest.java index daf13b3633f..caa47ce700c 100644 --- a/ethereum/statetransition/src/test/java/tech/pegasys/teku/statetransition/block/BlockManagerTest.java +++ b/ethereum/statetransition/src/test/java/tech/pegasys/teku/statetransition/block/BlockManagerTest.java @@ -79,7 +79,6 @@ import tech.pegasys.teku.spec.datastructures.blocks.SignedBlockAndState; import tech.pegasys.teku.spec.datastructures.blocks.SlotAndBlockRoot; import tech.pegasys.teku.spec.datastructures.validator.BroadcastValidationLevel; -import tech.pegasys.teku.spec.executionlayer.ExecutionLayerChannel; import tech.pegasys.teku.spec.executionlayer.ExecutionLayerChannelStub; import tech.pegasys.teku.spec.executionlayer.PayloadStatus; import tech.pegasys.teku.spec.generator.ChainBuilder.BlockOptions; @@ -182,8 +181,7 @@ private void setupWithSpec(final Spec spec) { spec, historicalBlockTolerance, futureBlockTolerance, maxPendingBlocks); this.localChain = InMemoryStorageSystemBuilder.buildDefault(spec); this.localRecentChainData = localChain.recentChainData(); - this.transitionBlockValidator = - new MergeTransitionBlockValidator(spec, localRecentChainData, ExecutionLayerChannel.NOOP); + this.transitionBlockValidator = new MergeTransitionBlockValidator(spec, localRecentChainData); this.forkChoice = new ForkChoice( spec, diff --git a/ethereum/statetransition/src/test/java/tech/pegasys/teku/statetransition/forkchoice/ForkChoiceTest.java b/ethereum/statetransition/src/test/java/tech/pegasys/teku/statetransition/forkchoice/ForkChoiceTest.java index 589b3b0e151..9f4503de388 100644 --- a/ethereum/statetransition/src/test/java/tech/pegasys/teku/statetransition/forkchoice/ForkChoiceTest.java +++ b/ethereum/statetransition/src/test/java/tech/pegasys/teku/statetransition/forkchoice/ForkChoiceTest.java @@ -41,7 +41,6 @@ import java.util.stream.Collectors; import java.util.stream.Stream; import org.apache.tuweni.bytes.Bytes32; -import org.apache.tuweni.units.bigints.UInt256; import org.hyperledger.besu.plugin.services.MetricsSystem; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -1224,19 +1223,11 @@ private void doMerge(final boolean optimistic) { } private SignedBlockAndState generateMergeBlock() { - final UInt256 terminalTotalDifficulty = - spec.getGenesisSpecConfig().toVersionBellatrix().orElseThrow().getTerminalTotalDifficulty(); final Bytes32 terminalBlockHash = dataStructureUtil.randomBytes32(); final Bytes32 terminalBlockParentHash = dataStructureUtil.randomBytes32(); - final PowBlock terminalBlock = - new PowBlock( - terminalBlockHash, terminalBlockParentHash, terminalTotalDifficulty.plus(1), ZERO); + final PowBlock terminalBlock = new PowBlock(terminalBlockHash, terminalBlockParentHash, ZERO); final PowBlock terminalParentBlock = - new PowBlock( - terminalBlockParentHash, - dataStructureUtil.randomBytes32(), - terminalTotalDifficulty.subtract(1), - ZERO); + new PowBlock(terminalBlockParentHash, dataStructureUtil.randomBytes32(), ZERO); executionLayer.addPowBlock(terminalBlock); executionLayer.addPowBlock(terminalParentBlock); return chainBuilder.generateBlockAtSlot( diff --git a/ethereum/statetransition/src/test/java/tech/pegasys/teku/statetransition/forkchoice/MergeTransitionBlockValidatorTest.java b/ethereum/statetransition/src/test/java/tech/pegasys/teku/statetransition/forkchoice/MergeTransitionBlockValidatorTest.java index f90a7af5e3b..1762ba3447a 100644 --- a/ethereum/statetransition/src/test/java/tech/pegasys/teku/statetransition/forkchoice/MergeTransitionBlockValidatorTest.java +++ b/ethereum/statetransition/src/test/java/tech/pegasys/teku/statetransition/forkchoice/MergeTransitionBlockValidatorTest.java @@ -19,7 +19,6 @@ import java.util.Optional; import org.apache.tuweni.bytes.Bytes32; -import org.apache.tuweni.units.bigints.UInt256; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; @@ -31,8 +30,6 @@ import tech.pegasys.teku.spec.Spec; import tech.pegasys.teku.spec.TestSpecFactory; import tech.pegasys.teku.spec.datastructures.blocks.SignedBlockAndState; -import tech.pegasys.teku.spec.datastructures.execution.ExecutionPayload; -import tech.pegasys.teku.spec.datastructures.execution.PowBlock; import tech.pegasys.teku.spec.datastructures.state.beaconstate.versions.bellatrix.BeaconStateBellatrix; import tech.pegasys.teku.spec.executionlayer.ExecutionLayerChannel; import tech.pegasys.teku.spec.executionlayer.ExecutionLayerChannelStub; @@ -46,7 +43,15 @@ class MergeTransitionBlockValidatorTest { - private final Spec spec = TestSpecFactory.createMinimalBellatrix(); + private final Bytes32 terminalBlockHash = Bytes32.random(); + private final UInt64 terminalEpoch = UInt64.ZERO; + private final Spec spec = + TestSpecFactory.createMinimalBellatrix( + b -> + b.bellatrixBuilder( + bb -> + bb.terminalBlockHash(terminalBlockHash) + .terminalBlockHashActivationEpoch(terminalEpoch))); private final DataStructureUtil dataStructureUtil = new DataStructureUtil(spec); private final ExecutionLayerChannelStub executionLayer = new ExecutionLayerChannelStub(spec, false, Optional.empty()); @@ -79,7 +84,7 @@ void setUp() { @Test void shouldReturnValidImmediatelyWhenThereIsTransitionBlockFullyVerified() { - final SignedBlockAndState chainHead = generateNonfinalizedTransition(); + final SignedBlockAndState chainHead = generateNonFinalizedTransition(true); storageSystem.chainUpdater().saveBlock(chainHead); final SignedBlockAndState blockToVerify = storageSystem.chainBuilder().generateNextBlock(); @@ -109,10 +114,9 @@ void shouldReturnValidImmediatelyWhenThereIsTransitionBlockFullyVerified() { @Test void shouldVerifyNonFinalizedAncestorTransitionBlock() { - final SignedBlockAndState transitionBlock = generateNonfinalizedTransition(); + final SignedBlockAndState transitionBlock = generateNonFinalizedTransition(true); final SignedBlockAndState chainHead = storageSystem.chainBuilder().getLatestBlockAndState(); final SignedBlockAndState blockToVerify = storageSystem.chainBuilder().generateNextBlock(); - withValidTransitionBlock(transitionBlock); final MergeTransitionBlockValidator transitionVerifier = createTransitionValidator(); @@ -133,8 +137,6 @@ void shouldVerifyNonFinalizedAncestorTransitionBlock() { .getLatestExecutionPayloadHeader(), blockToVerify.getBlock()); - assertThat(executionLayer.getRequestedPowBlocks()) - .contains(getExecutionPayload(transitionBlock).getParentHash()); assertThat(result) .isCompletedWithValue( new PayloadValidationResult(transitionBlock.getRoot(), PayloadStatus.VALID)); @@ -142,10 +144,9 @@ void shouldVerifyNonFinalizedAncestorTransitionBlock() { @Test void shouldReportRootForInvalidNonFinalizedAncestorTransitionBlock() { - final SignedBlockAndState transitionBlock = generateNonfinalizedTransition(); + final SignedBlockAndState transitionBlock = generateNonFinalizedTransition(false); final SignedBlockAndState chainHead = storageSystem.chainBuilder().getLatestBlockAndState(); final SignedBlockAndState blockToVerify = storageSystem.chainBuilder().generateNextBlock(); - withInvalidTransitionBlock(transitionBlock); final MergeTransitionBlockValidator transitionVerifier = createTransitionValidator(); @@ -166,8 +167,6 @@ void shouldReportRootForInvalidNonFinalizedAncestorTransitionBlock() { .getLatestExecutionPayloadHeader(), blockToVerify.getBlock()); - assertThat(executionLayer.getRequestedPowBlocks()) - .contains(getExecutionPayload(transitionBlock).getParentHash()); assertThat(result).isCompleted(); final PayloadValidationResult validationResult = safeJoin(result); assertThat(validationResult.getInvalidTransitionBlockRoot()) @@ -177,7 +176,7 @@ void shouldReportRootForInvalidNonFinalizedAncestorTransitionBlock() { @Test void shouldVerifyFinalizedAncestorTransitionBlock() { - final SignedBlockAndState transitionBlock = generateFinalizedTransition(); + generateFinalizedTransition(true); final BeaconStateBellatrix chainHeadState = storageSystem .chainBuilder() @@ -185,7 +184,6 @@ void shouldVerifyFinalizedAncestorTransitionBlock() { .getState() .toVersionBellatrix() .orElseThrow(); - withValidTransitionBlock(transitionBlock); final SignedBlockAndState blockToVerify = storageSystem.chainBuilder().generateNextBlock(); @@ -198,8 +196,6 @@ void shouldVerifyFinalizedAncestorTransitionBlock() { transitionVerifier.verifyTransitionBlock( chainHeadState.getLatestExecutionPayloadHeader(), blockToVerify.getBlock()); - assertThat(executionLayer.getRequestedPowBlocks()) - .contains(getExecutionPayload(transitionBlock).getParentHash()); assertThat(result).isCompletedWithValue(new PayloadValidationResult(PayloadStatus.VALID)); } @@ -210,7 +206,7 @@ void shouldVerifyFinalizedAncestorTransitionBlock() { */ @Test void shouldFailWithFatalServiceFailuresExceptionWhenFinalizedAncestorTransitionBlockIsInvalid() { - final SignedBlockAndState transitionBlock = generateFinalizedTransition(); + generateFinalizedTransition(false); final BeaconStateBellatrix chainHeadState = storageSystem .chainBuilder() @@ -218,7 +214,6 @@ void shouldFailWithFatalServiceFailuresExceptionWhenFinalizedAncestorTransitionB .getState() .toVersionBellatrix() .orElseThrow(); - withInvalidTransitionBlock(transitionBlock); final SignedBlockAndState blockToVerify = storageSystem.chainBuilder().generateNextBlock(); @@ -234,51 +229,19 @@ void shouldFailWithFatalServiceFailuresExceptionWhenFinalizedAncestorTransitionB assertThatSafeFuture(result).isCompletedExceptionallyWith(FatalServiceFailureException.class); } - private void withValidTransitionBlock(final SignedBlockAndState transitionBlock) { - final UInt256 ttd = - spec.getGenesisSpecConfig().toVersionBellatrix().orElseThrow().getTerminalTotalDifficulty(); - final UInt256 terminalBlockDifficulty = ttd.plus(1); - final UInt256 ttdBlockParentDifficulty = ttd.subtract(1); - withPowBlockDifficulties(transitionBlock, terminalBlockDifficulty, ttdBlockParentDifficulty); - } - - private void withInvalidTransitionBlock(final SignedBlockAndState transitionBlock) { - final UInt256 ttd = - spec.getGenesisSpecConfig().toVersionBellatrix().orElseThrow().getTerminalTotalDifficulty(); - final UInt256 terminalBlockDifficulty = ttd.subtract(1); - final UInt256 ttdBlockParentDifficulty = ttd.subtract(2); - withPowBlockDifficulties(transitionBlock, terminalBlockDifficulty, ttdBlockParentDifficulty); - } - - private void withPowBlockDifficulties( - final SignedBlockAndState transitionBlock, - final UInt256 terminalBlockDifficulty, - final UInt256 ttdBlockParentDifficulty) { - final Bytes32 terminalBlockParentHash = dataStructureUtil.randomBytes32(); - executionLayer.addPowBlock( - new PowBlock( - getExecutionPayload(transitionBlock).getParentHash(), - terminalBlockParentHash, - terminalBlockDifficulty, - UInt64.ZERO)); - executionLayer.addPowBlock( - new PowBlock( - terminalBlockParentHash, - dataStructureUtil.randomBytes32(), - ttdBlockParentDifficulty, - UInt64.ZERO)); - } - - private SignedBlockAndState generateNonfinalizedTransition() { + private SignedBlockAndState generateNonFinalizedTransition(final boolean isValid) { storageSystem .chainBuilder() .generateBlocksUpToSlot(5) .forEach(storageSystem.chainUpdater()::saveOptimisticBlock); - final Bytes32 terminalBlockHash = dataStructureUtil.randomBytes32(); final SignedBlockAndState transitionBlock = storageSystem .chainBuilder() - .generateBlockAtSlot(6, BlockOptions.create().setTerminalBlockHash(terminalBlockHash)); + .generateBlockAtSlot( + 6, + BlockOptions.create() + .setTerminalBlockHash( + isValid ? terminalBlockHash : dataStructureUtil.randomBytes32())); storageSystem.chainUpdater().saveOptimisticBlock(transitionBlock); storageSystem @@ -290,24 +253,14 @@ private SignedBlockAndState generateNonfinalizedTransition() { return transitionBlock; } - private SignedBlockAndState generateFinalizedTransition() { - final SignedBlockAndState transitionBlock = generateNonfinalizedTransition(); + private void generateFinalizedTransition(final boolean isValid) { + generateNonFinalizedTransition(isValid); // Finalize between transition block and chain head storageSystem.chainUpdater().finalizeEpoch(1); - return transitionBlock; - } - - private ExecutionPayload getExecutionPayload(final SignedBlockAndState blockToVerify) { - return blockToVerify - .getBlock() - .getMessage() - .getBody() - .getOptionalExecutionPayload() - .orElseThrow(); } private MergeTransitionBlockValidator createTransitionValidator() { - return new MergeTransitionBlockValidator(spec, storageSystem.recentChainData(), executionLayer); + return new MergeTransitionBlockValidator(spec, storageSystem.recentChainData()); } } diff --git a/ethereum/statetransition/src/test/java/tech/pegasys/teku/statetransition/forkchoice/TerminalPowBlockMonitorTest.java b/ethereum/statetransition/src/test/java/tech/pegasys/teku/statetransition/forkchoice/TerminalPowBlockMonitorTest.java index 08f55709b27..c0123384e91 100644 --- a/ethereum/statetransition/src/test/java/tech/pegasys/teku/statetransition/forkchoice/TerminalPowBlockMonitorTest.java +++ b/ethereum/statetransition/src/test/java/tech/pegasys/teku/statetransition/forkchoice/TerminalPowBlockMonitorTest.java @@ -14,18 +14,15 @@ package tech.pegasys.teku.statetransition.forkchoice; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; import static tech.pegasys.teku.infrastructure.async.SafeFuture.completedFuture; -import static tech.pegasys.teku.statetransition.forkchoice.TerminalPowBlockMonitor.TD_MIN_SAMPLES; -import java.time.Duration; -import java.time.Instant; import java.util.Optional; import java.util.function.Consumer; import org.apache.tuweni.bytes.Bytes32; @@ -37,6 +34,7 @@ import tech.pegasys.infrastructure.logging.LogCaptor; import tech.pegasys.teku.bls.BLSSignatureVerifier; import tech.pegasys.teku.infrastructure.async.StubAsyncRunner; +import tech.pegasys.teku.infrastructure.exceptions.InvalidConfigurationException; import tech.pegasys.teku.infrastructure.logging.EventLogger; import tech.pegasys.teku.infrastructure.time.StubTimeProvider; import tech.pegasys.teku.infrastructure.unsigned.UInt64; @@ -115,13 +113,7 @@ private void setUpCommon(final Consumer bellatrixBuilder) { terminalPowBlockMonitor = new TerminalPowBlockMonitor( - executionLayer, - spec, - recentChainData, - forkChoiceNotifier, - asyncRunner, - eventLogger, - timeProvider); + executionLayer, spec, recentChainData, forkChoiceNotifier, asyncRunner, eventLogger); terminalPowBlockMonitor.onNodeSyncStateChanged(true); } @@ -145,196 +137,19 @@ private void doMerge(final Bytes32 terminalBlockHash) { } @Test - void shouldNotFailWhenCurrentSlotInBellatrixMilestoneButHeadStateIsFromEarlierMilestone() { + public void shouldThrowIfTTDOnlyConfigured() { setUpTTDConfig(); - // Current epoch is in bellatrix, but state is still genesis from phase0. - storageSystem - .chainUpdater() - .setCurrentSlot(spec.computeStartSlotAtEpoch(BELLATRIX_FORK_EPOCH).plus(1)); - - // Terminal block has been reached - final Bytes32 headBlockHash = dataStructureUtil.randomBytes32(); - final Bytes32 headBlockParentHash = dataStructureUtil.randomBytes32(); - when(executionLayer.eth1GetPowChainHead()) - .thenReturn( - completedFuture(new PowBlock(headBlockHash, headBlockParentHash, TTD, TIME_IN_PAST))); - when(executionLayer.eth1GetPowBlock(headBlockParentHash)) - .thenReturn( - completedFuture( - Optional.of( - new PowBlock( - headBlockParentHash, - dataStructureUtil.randomBytes32(), - TTD.subtract(10), - TIME_IN_PAST)))); - - terminalPowBlockMonitor.start(); - - asyncRunner.executeQueuedActions(); - verify(forkChoiceNotifier).onTerminalBlockReached(headBlockHash); - } - - @Test - public void shouldPerformTerminalBlockDetectionByTTD() { - Bytes32 headBlockHash; - Bytes32 headBlockParentHash; - - setUpTTDConfig(); - - terminalPowBlockMonitor.start(); - - // NOT YET BELLATRIX FORK - should not notify - goToSlot(UInt64.ONE); - - assertThat(terminalPowBlockMonitor.isRunning()).isTrue(); - assertThat(asyncRunner.hasDelayedActions()).isTrue(); - - asyncRunner.executeQueuedActions(); - - verify(executionLayer, times(0)).eth1GetPowChainHead(); - verify(forkChoiceNotifier, times(0)).onTerminalBlockReached(any()); - - // AT BELLATRIX FORK, TTD not reached - should not send - headBlockHash = dataStructureUtil.randomBytes32(); - - goToSlot(BELLATRIX_FORK_EPOCH.times(spec.getGenesisSpecConfig().getSlotsPerEpoch())); - - when(executionLayer.eth1GetPowChainHead()) - .thenReturn( - completedFuture( - new PowBlock( - headBlockHash, - dataStructureUtil.randomBytes32(), - TTD.subtract(10), - TIME_IN_PAST))); - - asyncRunner.executeQueuedActions(); - - verify(executionLayer, times(1)).eth1GetPowChainHead(); - verify(forkChoiceNotifier, times(0)).onTerminalBlockReached(any()); - - // AT BELLATRIX FORK, TTD reached - should notify - headBlockHash = dataStructureUtil.randomBytes32(); - headBlockParentHash = dataStructureUtil.randomBytes32(); - when(executionLayer.eth1GetPowChainHead()) - .thenReturn( - completedFuture(new PowBlock(headBlockHash, headBlockParentHash, TTD, TIME_IN_PAST))); - when(executionLayer.eth1GetPowBlock(headBlockParentHash)) - .thenReturn( - completedFuture( - Optional.of( - new PowBlock( - headBlockParentHash, - dataStructureUtil.randomBytes32(), - TTD.subtract(10), - TIME_IN_PAST)))); - - asyncRunner.executeQueuedActions(); - - verify(eventLogger).terminalPowBlockDetected(headBlockHash); - verify(executionLayer, times(1)).eth1GetPowBlock(headBlockParentHash); - verify(executionLayer, times(2)).eth1GetPowChainHead(); - verify(forkChoiceNotifier, times(1)).onTerminalBlockReached(headBlockHash); - - // Terminal Block - should not notify - asyncRunner.executeQueuedActions(); - - verify(executionLayer, times(3)).eth1GetPowChainHead(); - verifyNoMoreInteractions(executionLayer); - - // new different Terminal Block with wrong parent TTD - should not notify - headBlockHash = dataStructureUtil.randomBytes32(); - headBlockParentHash = dataStructureUtil.randomBytes32(); - when(executionLayer.eth1GetPowChainHead()) - .thenReturn( - completedFuture( - new PowBlock(headBlockHash, headBlockParentHash, TTD.add(10), TIME_IN_PAST))); - when(executionLayer.eth1GetPowBlock(headBlockParentHash)) - .thenReturn( - completedFuture( - Optional.of( - new PowBlock( - headBlockParentHash, - dataStructureUtil.randomBytes32(), - TTD, - TIME_IN_PAST)))); - - asyncRunner.executeQueuedActions(); - - verify(executionLayer, times(1)).eth1GetPowBlock(headBlockParentHash); - verify(executionLayer, times(4)).eth1GetPowChainHead(); - verify(forkChoiceNotifier, times(0)).onTerminalBlockReached(headBlockHash); - - // new different Terminal Block with correct parent TTD - should notify - headBlockHash = dataStructureUtil.randomBytes32(); - headBlockParentHash = dataStructureUtil.randomBytes32(); - when(executionLayer.eth1GetPowChainHead()) - .thenReturn( - completedFuture( - new PowBlock(headBlockHash, headBlockParentHash, TTD.add(10), TIME_IN_PAST))); - when(executionLayer.eth1GetPowBlock(headBlockParentHash)) - .thenReturn( - completedFuture( - Optional.of( - new PowBlock( - headBlockParentHash, - dataStructureUtil.randomBytes32(), - TTD.subtract(10), - TIME_IN_PAST)))); - - asyncRunner.executeQueuedActions(); - - verify(eventLogger).terminalPowBlockDetected(headBlockHash); - verify(executionLayer, times(1)).eth1GetPowBlock(headBlockParentHash); - verify(executionLayer, times(5)).eth1GetPowChainHead(); - verify(forkChoiceNotifier, times(1)).onTerminalBlockReached(headBlockHash); - - // MERGE Completed - should stop - doMerge(headBlockHash); - - asyncRunner.executeQueuedActions(); - - assertThat(terminalPowBlockMonitor.isRunning()).isFalse(); - - // final check + assertThatThrownBy(() -> terminalPowBlockMonitor.start()) + .isInstanceOf(InvalidConfigurationException.class) + .hasMessageContaining( + "Bellatrix transition by terminal total difficulty is no more supported"); verifyNoMoreInteractions(executionLayer); - verifyNoMoreInteractions(eventLogger); - } - - @Test - public void shouldNotSelectTTDBlockWithTimestampInFuture() { - setUpTTDConfig(); - - terminalPowBlockMonitor.start(); - - // AT BELLATRIX FORK, TTD reached but block in future - should not notify - goToSlot(BELLATRIX_FORK_EPOCH.times(spec.getGenesisSpecConfig().getSlotsPerEpoch())); - Bytes32 headBlockHash = dataStructureUtil.randomBytes32(); - Bytes32 headBlockParentHash = dataStructureUtil.randomBytes32(); - final UInt64 timeInFuture = timeProvider.getTimeInSeconds().plus(1); - when(executionLayer.eth1GetPowChainHead()) - .thenReturn( - completedFuture(new PowBlock(headBlockHash, headBlockParentHash, TTD, timeInFuture))); - when(executionLayer.eth1GetPowBlock(headBlockParentHash)) - .thenReturn( - completedFuture( - Optional.of( - new PowBlock( - headBlockParentHash, - dataStructureUtil.randomBytes32(), - TTD.subtract(10), - TIME_IN_PAST)))); - - asyncRunner.executeQueuedActions(); - - verify(eventLogger, never()).terminalPowBlockDetected(headBlockHash); - verify(forkChoiceNotifier, never()).onTerminalBlockReached(headBlockHash); } @Test public void shouldHandleLatestPowBlockBeingNull() { - setUpTTDConfig(); + setUpTerminalBlockHashConfig(); terminalPowBlockMonitor.start(); try (LogCaptor logCaptor = LogCaptor.forClass(TerminalPowBlockMonitor.class)) { @@ -388,10 +203,7 @@ void shouldPerformTerminalBlockDetectionByTerminalBlockHash() { completedFuture( Optional.of( new PowBlock( - TERMINAL_BLOCK_HASH, - dataStructureUtil.randomBytes32(), - UInt256.ONE, - TIME_IN_PAST)))); + TERMINAL_BLOCK_HASH, dataStructureUtil.randomBytes32(), TIME_IN_PAST)))); asyncRunner.executeQueuedActions(); @@ -424,7 +236,7 @@ void shouldImmediatelyStopWhenMergeCompleted() { @Test void shouldNotPerformCheckIfSyncing() { - setUpTTDConfig(); + setUpTerminalBlockHashConfig(); terminalPowBlockMonitor.start(); @@ -436,61 +248,4 @@ void shouldNotPerformCheckIfSyncing() { verifyNoMoreInteractions(executionLayer); } - - @Test - void shouldCalculateTtdEta() { - - setUpTTDConfig(); - - final UInt256 tdDiff = TTD.divide(TD_MIN_SAMPLES * 2); - - terminalPowBlockMonitor.start(); - - goToSlot(BELLATRIX_FORK_EPOCH.times(spec.getGenesisSpecConfig().getSlotsPerEpoch())); - - UInt256 lastTD = UInt256.ZERO; - UInt64 lastTime = UInt64.ZERO; - - for (int cnt = TD_MIN_SAMPLES; cnt > 0; cnt--) { - lastTD = lastTD.plus(tdDiff); - lastTime = timeProvider.getTimeInSeconds(); - pollTtd(lastTD, lastTime); - timeProvider.advanceTimeBySeconds(spec.getGenesisSpecConfig().getSecondsPerEth1Block()); - } - - final long eta = (long) spec.getGenesisSpecConfig().getSecondsPerEth1Block() * TD_MIN_SAMPLES; - final Duration expectedETA = Duration.ofSeconds(eta); - final Instant expectedInstant = Instant.ofEpochSecond(eta + lastTime.longValue()); - - verify(eventLogger).terminalPowBlockTtdEta(lastTD, expectedETA, expectedInstant); - - // check that if current time goes beyond the ETA we get an event with NOW values - timeProvider.advanceTimeBySeconds(eta + 100); - - pollTtd(lastTD, lastTime); - pollTtd(lastTD, lastTime); - pollTtd(lastTD, lastTime); - pollTtd(lastTD, lastTime); - pollTtd(lastTD, lastTime); - - verify(eventLogger) - .terminalPowBlockTtdEta( - lastTD, - Duration.ZERO, - Instant.ofEpochSecond(timeProvider.getTimeInSeconds().longValue())); - - verifyNoMoreInteractions(eventLogger); - } - - private void pollTtd(final UInt256 ttd, final UInt64 time) { - when(executionLayer.eth1GetPowChainHead()) - .thenReturn( - completedFuture( - new PowBlock( - dataStructureUtil.randomBytes32(), - dataStructureUtil.randomBytes32(), - ttd, - time))); - asyncRunner.executeQueuedActions(); - } } diff --git a/ethereum/statetransition/src/testFixtures/java/tech/pegasys/teku/statetransition/BeaconChainUtil.java b/ethereum/statetransition/src/testFixtures/java/tech/pegasys/teku/statetransition/BeaconChainUtil.java index 55cc8d459cc..b29344ffe1d 100644 --- a/ethereum/statetransition/src/testFixtures/java/tech/pegasys/teku/statetransition/BeaconChainUtil.java +++ b/ethereum/statetransition/src/testFixtures/java/tech/pegasys/teku/statetransition/BeaconChainUtil.java @@ -40,7 +40,6 @@ import tech.pegasys.teku.spec.datastructures.operations.Deposit; import tech.pegasys.teku.spec.datastructures.operations.SignedVoluntaryExit; import tech.pegasys.teku.spec.datastructures.state.beaconstate.BeaconState; -import tech.pegasys.teku.spec.executionlayer.ExecutionLayerChannel; import tech.pegasys.teku.spec.executionlayer.ExecutionLayerChannelStub; import tech.pegasys.teku.spec.generator.BlockProposalTestUtil; import tech.pegasys.teku.spec.logic.common.statetransition.results.BlockImportResult; @@ -108,7 +107,7 @@ public static BeaconChainUtil create( storageClient, BlobSidecarManager.NOOP, new NoopForkChoiceNotifier(), - new MergeTransitionBlockValidator(spec, storageClient, ExecutionLayerChannel.NOOP), + new MergeTransitionBlockValidator(spec, storageClient), new StubMetricsSystem()), true); } @@ -128,7 +127,7 @@ public static BeaconChainUtil create( storageClient, BlobSidecarManager.NOOP, new NoopForkChoiceNotifier(), - new MergeTransitionBlockValidator(spec, storageClient, ExecutionLayerChannel.NOOP), + new MergeTransitionBlockValidator(spec, storageClient), new StubMetricsSystem()), signDeposits); } @@ -324,8 +323,7 @@ public BeaconChainUtil build() { recentChainData, BlobSidecarManager.NOOP, new NoopForkChoiceNotifier(), - new MergeTransitionBlockValidator( - spec, recentChainData, ExecutionLayerChannel.NOOP), + new MergeTransitionBlockValidator(spec, recentChainData), new StubMetricsSystem()); } if (validatorKeys == null) { diff --git a/fork-choice-tests/src/integration-test/java/tech/pegasys/teku/forkChoiceTests/ForkChoiceIntegrationTest.java b/fork-choice-tests/src/integration-test/java/tech/pegasys/teku/forkChoiceTests/ForkChoiceIntegrationTest.java index ec9cb09f9ce..16270f33f6c 100644 --- a/fork-choice-tests/src/integration-test/java/tech/pegasys/teku/forkChoiceTests/ForkChoiceIntegrationTest.java +++ b/fork-choice-tests/src/integration-test/java/tech/pegasys/teku/forkChoiceTests/ForkChoiceIntegrationTest.java @@ -48,7 +48,6 @@ import tech.pegasys.teku.spec.datastructures.state.beaconstate.BeaconState; import tech.pegasys.teku.spec.datastructures.state.beaconstate.BeaconStateSchema; import tech.pegasys.teku.spec.datastructures.util.AttestationProcessingResult; -import tech.pegasys.teku.spec.executionlayer.ExecutionLayerChannel; import tech.pegasys.teku.spec.executionlayer.ExecutionLayerChannelStub; import tech.pegasys.teku.spec.logic.common.statetransition.results.BlockImportResult; import tech.pegasys.teku.spec.schemas.SchemaDefinitions; @@ -183,7 +182,7 @@ void runForkChoiceTests( final InlineEventThread forkChoiceExecutor = new InlineEventThread(); final MergeTransitionBlockValidator transitionBlockValidator = - new MergeTransitionBlockValidator(SPEC, storageClient, ExecutionLayerChannel.NOOP); + new MergeTransitionBlockValidator(SPEC, storageClient); ForkChoice forkChoice = new ForkChoice( SPEC, 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 90508b0303b..6de4dfd31b6 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 @@ -611,8 +611,7 @@ protected void initMergeMonitors() { recentChainData, forkChoiceNotifier, beaconAsyncRunner, - EVENT_LOG, - timeProvider)); + EVENT_LOG)); } } @@ -822,7 +821,7 @@ protected void initForkChoice() { forkChoiceNotifier, forkChoiceStateProvider, new TickProcessor(spec, recentChainData), - new MergeTransitionBlockValidator(spec, recentChainData, executionLayer), + new MergeTransitionBlockValidator(spec, recentChainData), beaconConfig.eth2NetworkConfig().isForkChoiceLateBlockReorgEnabled(), debugDataDumper, metricsSystem); diff --git a/validator/client/src/test/java/tech/pegasys/teku/validator/client/ValidatorIndexProviderTest.java b/validator/client/src/test/java/tech/pegasys/teku/validator/client/ValidatorIndexProviderTest.java index 6730447fd6f..710126564cf 100644 --- a/validator/client/src/test/java/tech/pegasys/teku/validator/client/ValidatorIndexProviderTest.java +++ b/validator/client/src/test/java/tech/pegasys/teku/validator/client/ValidatorIndexProviderTest.java @@ -61,7 +61,8 @@ void shouldLoadValidatorKeys() { when(validatorApiChannel.getValidatorIndices(validators.getPublicKeys())) .thenReturn(SafeFuture.completedFuture(Map.of(key1, 1, key2, 20, key3, 300))); provider.lookupValidators(); - assertThat(provider.getValidatorIndices()).isCompletedWithValue(IntArrayList.of(1, 20, 300)); + final IntCollection actual = provider.getValidatorIndices().getImmediately(); + assertThat(actual).containsExactlyInAnyOrderElementsOf(IntArrayList.of(1, 20, 300)); } @Test @@ -99,7 +100,8 @@ void shouldLookupValidatorKeysThatWerePreviouslyUnknown() { when(validatorApiChannel.getValidatorIndices(Set.of(key1, key3))) .thenReturn(SafeFuture.completedFuture(Map.of(key1, 1, key3, 300))); provider.lookupValidators(); - assertThat(provider.getValidatorIndices()).isCompletedWithValue(IntArrayList.of(1, 20, 300)); + final IntCollection actual = provider.getValidatorIndices().getImmediately(); + assertThat(actual).containsExactlyInAnyOrderElementsOf(IntArrayList.of(1, 20, 300)); } @Test