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..11774e99faa 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 @@ -90,6 +90,12 @@ private static TekuNodeConfigBuilder createTekuNodeBuilderForMilestone( tekuNodeConfigBuilder.withDenebEpoch(UInt64.ZERO); tekuNodeConfigBuilder.withElectraEpoch(UInt64.ZERO); break; + case EIP7805: + tekuNodeConfigBuilder.withCapellaEpoch(UInt64.ZERO); + tekuNodeConfigBuilder.withDenebEpoch(UInt64.ZERO); + tekuNodeConfigBuilder.withElectraEpoch(UInt64.ZERO); + tekuNodeConfigBuilder.withEip(UInt64.ZERO); + break; default: // Test will reach this whenever a new milestone is added and isn't mapped on the switch. // This is a way to force us to always remember to validate that a new milestone can start 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..5ff5d533cfc 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 @@ -171,6 +171,18 @@ public TekuNodeConfigBuilder withElectraEpoch(final UInt64 electraForkEpoch) { return this; } + public TekuNodeConfigBuilder withEip7805Epoch(final UInt64 eip7805ForkEpoch) { + mustBe(NodeType.BEACON_NODE); + LOG.debug("Xnetwork-eip7805-fork-epoch={}", eip7805ForkEpoch); + configMap.put("Xnetwork-eip7805-fork-epoch", eip7805ForkEpoch.toString()); + specConfigModifier = + specConfigModifier.andThen( + specConfigBuilder -> + specConfigBuilder.eip7805Builder( + eip7805Builder -> eip7805Builder.eip7805ForkEpoch(eip7805ForkEpoch))); + return this; + } + public TekuNodeConfigBuilder withTrustedSetupFromClasspath(final String trustedSetup) throws Exception { mustBe(NodeType.BEACON_NODE); diff --git a/ethereum/networks/src/main/java/tech/pegasys/teku/networks/Eth2NetworkConfiguration.java b/ethereum/networks/src/main/java/tech/pegasys/teku/networks/Eth2NetworkConfiguration.java index 346dcb11ec5..89d179bd394 100644 --- a/ethereum/networks/src/main/java/tech/pegasys/teku/networks/Eth2NetworkConfiguration.java +++ b/ethereum/networks/src/main/java/tech/pegasys/teku/networks/Eth2NetworkConfiguration.java @@ -92,6 +92,7 @@ public class Eth2NetworkConfiguration { private final Optional capellaForkEpoch; private final Optional denebForkEpoch; private final Optional electraForkEpoch; + private final Optional eip7805ForkEpoch; private final Eth1Address eth1DepositContractAddress; private final Optional eth1DepositContractDeployBlock; private final Optional trustedSetup; @@ -122,6 +123,7 @@ private Eth2NetworkConfiguration( final Optional capellaForkEpoch, final Optional denebForkEpoch, final Optional electraForkEpoch, + final Optional eip7805ForkEpoch, final Optional terminalBlockHashOverride, final Optional totalTerminalDifficultyOverride, final Optional terminalBlockHashEpochOverride, @@ -144,6 +146,7 @@ private Eth2NetworkConfiguration( this.capellaForkEpoch = capellaForkEpoch; this.denebForkEpoch = denebForkEpoch; this.electraForkEpoch = electraForkEpoch; + this.eip7805ForkEpoch = eip7805ForkEpoch; this.eth1DepositContractAddress = eth1DepositContractAddress == null ? spec.getGenesisSpecConfig().getDepositContractAddress() @@ -231,6 +234,7 @@ public Optional getForkEpoch(final SpecMilestone specMilestone) { case CAPELLA -> capellaForkEpoch; case DENEB -> denebForkEpoch; case ELECTRA -> electraForkEpoch; + case EIP7805 -> eip7805ForkEpoch; default -> Optional.empty(); }; } @@ -311,6 +315,7 @@ public boolean equals(final Object o) { && Objects.equals(capellaForkEpoch, that.capellaForkEpoch) && Objects.equals(denebForkEpoch, that.denebForkEpoch) && Objects.equals(electraForkEpoch, that.electraForkEpoch) + && Objects.equals(eip7805ForkEpoch, that.eip7805ForkEpoch) && Objects.equals(eth1DepositContractAddress, that.eth1DepositContractAddress) && Objects.equals(eth1DepositContractDeployBlock, that.eth1DepositContractDeployBlock) && Objects.equals(trustedSetup, that.trustedSetup) @@ -335,6 +340,7 @@ public int hashCode() { capellaForkEpoch, denebForkEpoch, electraForkEpoch, + eip7805ForkEpoch, eth1DepositContractAddress, eth1DepositContractDeployBlock, trustedSetup, @@ -375,6 +381,7 @@ public static class Builder { private Optional capellaForkEpoch = Optional.empty(); private Optional denebForkEpoch = Optional.empty(); private Optional electraForkEpoch = Optional.empty(); + private Optional eip7805ForkEpoch = Optional.empty(); private Optional terminalBlockHashOverride = Optional.empty(); private Optional totalTerminalDifficultyOverride = Optional.empty(); private Optional terminalBlockHashEpochOverride = Optional.empty(); @@ -439,7 +446,7 @@ public Eth2NetworkConfiguration build() { electraForkEpoch.ifPresent(electraBuilder::electraForkEpoch)); builder.eip7805Builder( eip7805Builder -> - electraForkEpoch.ifPresent(eip7805Builder::eip7805ForkEpoch)); + eip7805ForkEpoch.ifPresent(eip7805Builder::eip7805ForkEpoch)); }); } if (spec.getForkSchedule().getSupportedMilestones().contains(SpecMilestone.DENEB) @@ -472,6 +479,7 @@ public Eth2NetworkConfiguration build() { capellaForkEpoch, denebForkEpoch, electraForkEpoch, + eip7805ForkEpoch, terminalBlockHashOverride, totalTerminalDifficultyOverride, terminalBlockHashEpochOverride, @@ -683,6 +691,11 @@ public Builder electraForkEpoch(final UInt64 electraForkEpoch) { return this; } + public Builder eip7805ForkEpoch(final UInt64 eip7805ForkEpoch) { + this.eip7805ForkEpoch = Optional.of(eip7805ForkEpoch); + return this; + } + public Builder safeSlotsToImportOptimistically(final int safeSlotsToImportOptimistically) { if (safeSlotsToImportOptimistically < 0) { throw new InvalidConfigurationException( diff --git a/ethereum/spec/src/testFixtures/java/tech/pegasys/teku/spec/TestSpecFactory.java b/ethereum/spec/src/testFixtures/java/tech/pegasys/teku/spec/TestSpecFactory.java index 3e9e8f15171..be17740f2f7 100644 --- a/ethereum/spec/src/testFixtures/java/tech/pegasys/teku/spec/TestSpecFactory.java +++ b/ethereum/spec/src/testFixtures/java/tech/pegasys/teku/spec/TestSpecFactory.java @@ -245,7 +245,7 @@ public static Spec createMainnetElectra() { public static Spec createMainnetEip7805() { final SpecConfigAndParent specConfig = getEip7805SpecConfig(Eth2Network.MAINNET); - return create(specConfig, SpecMilestone.ELECTRA); + return create(specConfig, SpecMilestone.EIP7805); } public static Spec createPhase0(final SpecConfigAndParent config) { diff --git a/teku/src/main/java/tech/pegasys/teku/cli/options/Eth2NetworkOptions.java b/teku/src/main/java/tech/pegasys/teku/cli/options/Eth2NetworkOptions.java index 01113b0212f..9b1c4240100 100644 --- a/teku/src/main/java/tech/pegasys/teku/cli/options/Eth2NetworkOptions.java +++ b/teku/src/main/java/tech/pegasys/teku/cli/options/Eth2NetworkOptions.java @@ -158,6 +158,14 @@ public class Eth2NetworkOptions { arity = "1") private UInt64 electraForkEpoch; + @Option( + names = {"--Xnetwork-eip7805-fork-epoch"}, + hidden = true, + paramLabel = "", + description = "Override the eip7805 fork activation epoch.", + arity = "1") + private UInt64 eip7805ForkEpoch; + @Option( names = {"--Xnetwork-total-terminal-difficulty-override"}, hidden = true, @@ -331,6 +339,9 @@ private void configureEth2Network(final Eth2NetworkConfiguration.Builder builder if (electraForkEpoch != null) { builder.electraForkEpoch(electraForkEpoch); } + if (eip7805ForkEpoch != null) { + builder.eip7805ForkEpoch(eip7805ForkEpoch); + } if (totalTerminalDifficultyOverride != null) { builder.totalTerminalDifficultyOverride(totalTerminalDifficultyOverride); }