diff --git a/eth-reference-tests/src/referenceTest/java/tech/pegasys/teku/reference/Eth2ReferenceTestCase.java b/eth-reference-tests/src/referenceTest/java/tech/pegasys/teku/reference/Eth2ReferenceTestCase.java index 9e80ac11692..e01b094ae38 100644 --- a/eth-reference-tests/src/referenceTest/java/tech/pegasys/teku/reference/Eth2ReferenceTestCase.java +++ b/eth-reference-tests/src/referenceTest/java/tech/pegasys/teku/reference/Eth2ReferenceTestCase.java @@ -70,6 +70,14 @@ public abstract class Eth2ReferenceTestCase { .putAll(RewardsTestExecutorBellatrix.REWARDS_TEST_TYPES) .build(); + private static final ImmutableMap CAPELLA_TEST_TYPES = + ImmutableMap.builder() + .putAll(TransitionTestExecutor.TRANSITION_TEST_TYPES) + .putAll(ForkUpgradeTestExecutor.FORK_UPGRADE_TEST_TYPES) + .putAll(RewardsTestExecutorBellatrix.REWARDS_TEST_TYPES) + .putAll(OperationsTestExecutor.OPERATIONS_TEST_TYPES) + .build(); + protected void runReferenceTest(final TestDefinition testDefinition) throws Throwable { getExecutorFor(testDefinition).runTest(testDefinition); } @@ -78,12 +86,22 @@ private TestExecutor getExecutorFor(final TestDefinition testDefinition) { TestExecutor testExecutor = null; // Look for fork-specific tests first - if (testDefinition.getFork().equals(TestFork.PHASE0)) { - testExecutor = PHASE_0_TEST_TYPES.get(testDefinition.getTestType()); - } else if (testDefinition.getFork().equals(TestFork.ALTAIR)) { - testExecutor = ALTAIR_TEST_TYPES.get(testDefinition.getTestType()); - } else if (testDefinition.getFork().equals(TestFork.BELLATRIX)) { - testExecutor = BELLATRIX_TEST_TYPES.get(testDefinition.getTestType()); + switch (testDefinition.getFork()) { + case TestFork.PHASE0: + testExecutor = PHASE_0_TEST_TYPES.get(testDefinition.getTestType()); + break; + case TestFork.ALTAIR: + testExecutor = ALTAIR_TEST_TYPES.get(testDefinition.getTestType()); + break; + case TestFork.BELLATRIX: + testExecutor = BELLATRIX_TEST_TYPES.get(testDefinition.getTestType()); + break; + case TestFork.CAPELLA: + testExecutor = CAPELLA_TEST_TYPES.get(testDefinition.getTestType()); + break; + default: + throw new UnsupportedOperationException( + "Fork " + testDefinition.getFork() + " not implemented"); } // Look for a common test type if no specific override present diff --git a/eth-reference-tests/src/referenceTest/java/tech/pegasys/teku/reference/common/operations/DefaultOperationProcessor.java b/eth-reference-tests/src/referenceTest/java/tech/pegasys/teku/reference/common/operations/DefaultOperationProcessor.java index d6e9764d3a7..073928ebea2 100644 --- a/eth-reference-tests/src/referenceTest/java/tech/pegasys/teku/reference/common/operations/DefaultOperationProcessor.java +++ b/eth-reference-tests/src/referenceTest/java/tech/pegasys/teku/reference/common/operations/DefaultOperationProcessor.java @@ -25,6 +25,7 @@ import tech.pegasys.teku.spec.datastructures.operations.AttesterSlashing; import tech.pegasys.teku.spec.datastructures.operations.Deposit; import tech.pegasys.teku.spec.datastructures.operations.ProposerSlashing; +import tech.pegasys.teku.spec.datastructures.operations.SignedBlsToExecutionChange; import tech.pegasys.teku.spec.datastructures.operations.SignedVoluntaryExit; import tech.pegasys.teku.spec.datastructures.state.beaconstate.MutableBeaconState; import tech.pegasys.teku.spec.logic.common.statetransition.exceptions.BlockProcessingException; @@ -112,4 +113,12 @@ public void processExecutionPayload( spec.getBlockProcessor(state.getSlot()) .processExecutionPayload(state, executionPayloadHeader, executionPayload, payloadExecutor); } + + @Override + public void processBlsToExecutionChange( + final MutableBeaconState state, final SignedBlsToExecutionChange blsToExecutionChange) + throws BlockProcessingException { + spec.getBlockProcessor(state.getSlot()) + .processBlsToExecutionChange(state, blsToExecutionChange); + } } diff --git a/eth-reference-tests/src/referenceTest/java/tech/pegasys/teku/reference/common/operations/OperationProcessor.java b/eth-reference-tests/src/referenceTest/java/tech/pegasys/teku/reference/common/operations/OperationProcessor.java index 7cf0eb146ef..9ec0977fb36 100644 --- a/eth-reference-tests/src/referenceTest/java/tech/pegasys/teku/reference/common/operations/OperationProcessor.java +++ b/eth-reference-tests/src/referenceTest/java/tech/pegasys/teku/reference/common/operations/OperationProcessor.java @@ -22,6 +22,7 @@ import tech.pegasys.teku.spec.datastructures.operations.AttesterSlashing; import tech.pegasys.teku.spec.datastructures.operations.Deposit; import tech.pegasys.teku.spec.datastructures.operations.ProposerSlashing; +import tech.pegasys.teku.spec.datastructures.operations.SignedBlsToExecutionChange; import tech.pegasys.teku.spec.datastructures.operations.SignedVoluntaryExit; import tech.pegasys.teku.spec.datastructures.state.beaconstate.MutableBeaconState; import tech.pegasys.teku.spec.logic.common.statetransition.exceptions.BlockProcessingException; @@ -55,4 +56,9 @@ void processExecutionPayload( Optional payload, Optional payloadExecutor) throws BlockProcessingException; + + void processBlsToExecutionChange( + MutableBeaconState state, SignedBlsToExecutionChange blsToExecutionChange) + throws BlockProcessingException; + ; } diff --git a/eth-reference-tests/src/referenceTest/java/tech/pegasys/teku/reference/common/operations/OperationsTestExecutor.java b/eth-reference-tests/src/referenceTest/java/tech/pegasys/teku/reference/common/operations/OperationsTestExecutor.java index 39eebe3749d..cd1836069bd 100644 --- a/eth-reference-tests/src/referenceTest/java/tech/pegasys/teku/reference/common/operations/OperationsTestExecutor.java +++ b/eth-reference-tests/src/referenceTest/java/tech/pegasys/teku/reference/common/operations/OperationsTestExecutor.java @@ -37,6 +37,7 @@ import tech.pegasys.teku.spec.datastructures.operations.AttesterSlashing; import tech.pegasys.teku.spec.datastructures.operations.Deposit; import tech.pegasys.teku.spec.datastructures.operations.ProposerSlashing; +import tech.pegasys.teku.spec.datastructures.operations.SignedBlsToExecutionChange; import tech.pegasys.teku.spec.datastructures.operations.SignedVoluntaryExit; import tech.pegasys.teku.spec.datastructures.state.beaconstate.BeaconState; import tech.pegasys.teku.spec.datastructures.state.beaconstate.BeaconStateCache; @@ -47,6 +48,7 @@ import tech.pegasys.teku.spec.logic.common.statetransition.exceptions.EpochProcessingException; import tech.pegasys.teku.spec.logic.common.statetransition.exceptions.SlotProcessingException; import tech.pegasys.teku.spec.schemas.SchemaDefinitionsBellatrix; +import tech.pegasys.teku.spec.schemas.SchemaDefinitionsCapella; import tech.pegasys.teku.statetransition.validation.AttesterSlashingValidator; import tech.pegasys.teku.statetransition.validation.OperationValidator; import tech.pegasys.teku.statetransition.validation.ProposerSlashingValidator; @@ -64,7 +66,8 @@ private enum Operation { VOLUNTARY_EXIT, ATTESTATION, SYNC_AGGREGATE, - EXECUTION_PAYLOAD + EXECUTION_PAYLOAD, + BLS_TO_EXECUTION_CHANGE } public static final ImmutableMap OPERATIONS_TEST_TYPES = @@ -99,6 +102,10 @@ private enum Operation { "operations/execution_payload", new OperationsTestExecutor<>( "execution_payload.ssz_snappy", Operation.EXECUTION_PAYLOAD)) + .put( + "operations/bls_to_execution_change", + new OperationsTestExecutor<>( + "address_change.ssz_snappy", Operation.EXECUTION_PAYLOAD)) .build(); private final String dataFileName; @@ -289,6 +296,19 @@ private void processOperation( Optional.of( (latestExecutionPayloadHeader, payloadToExecute) -> executionMeta.executionValid)); break; + case BLS_TO_EXECUTION_CHANGE: + final SchemaDefinitionsCapella schemaDefinitionsCapella = + testDefinition.getSpec().getGenesisSchemaDefinitions().toVersionCapella().orElseThrow(); + final SignedBlsToExecutionChange blsToExecutionChange = + loadSsz( + testDefinition, + dataFileName, + schemaDefinitionsCapella.getSignedBlsToExecutionChangeSchema()); + processor.processBlsToExecutionChange(state, blsToExecutionChange); + break; + default: + throw new UnsupportedOperationException( + "Operation " + operation + " not implemented in OperationTestExecutor"); } } diff --git a/eth-tests/src/main/java/tech/pegasys/teku/ethtests/TestFork.java b/eth-tests/src/main/java/tech/pegasys/teku/ethtests/TestFork.java index d72f2f64066..d79528f18a6 100644 --- a/eth-tests/src/main/java/tech/pegasys/teku/ethtests/TestFork.java +++ b/eth-tests/src/main/java/tech/pegasys/teku/ethtests/TestFork.java @@ -17,4 +17,6 @@ public class TestFork { public static final String PHASE0 = "phase0"; public static final String ALTAIR = "altair"; public static final String BELLATRIX = "bellatrix"; + + public static final String CAPELLA = "capella"; } diff --git a/eth-tests/src/main/java/tech/pegasys/teku/ethtests/finder/ReferenceTestFinder.java b/eth-tests/src/main/java/tech/pegasys/teku/ethtests/finder/ReferenceTestFinder.java index 56bb9a1de63..5f8a8a1626e 100644 --- a/eth-tests/src/main/java/tech/pegasys/teku/ethtests/finder/ReferenceTestFinder.java +++ b/eth-tests/src/main/java/tech/pegasys/teku/ethtests/finder/ReferenceTestFinder.java @@ -29,7 +29,7 @@ public class ReferenceTestFinder { private static final Path TEST_PATH_FROM_MODULE = Path.of("src", "referenceTest", "resources", "eth2.0-spec-tests", "tests"); private static final List SUPPORTED_FORKS = - List.of(TestFork.PHASE0, TestFork.ALTAIR, TestFork.BELLATRIX); + List.of(TestFork.PHASE0, TestFork.ALTAIR, TestFork.BELLATRIX, TestFork.CAPELLA); @MustBeClosed public static Stream findReferenceTests() throws IOException { diff --git a/eth-tests/src/main/java/tech/pegasys/teku/ethtests/finder/TestDefinition.java b/eth-tests/src/main/java/tech/pegasys/teku/ethtests/finder/TestDefinition.java index b67c984d7fc..5ff403a70a1 100644 --- a/eth-tests/src/main/java/tech/pegasys/teku/ethtests/finder/TestDefinition.java +++ b/eth-tests/src/main/java/tech/pegasys/teku/ethtests/finder/TestDefinition.java @@ -83,6 +83,9 @@ private void createSpec() { case TestFork.BELLATRIX: highestSupportedMilestone = SpecMilestone.BELLATRIX; break; + case TestFork.CAPELLA: + highestSupportedMilestone = SpecMilestone.CAPELLA; + break; default: throw new IllegalArgumentException("Unknown fork: " + fork); } diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/common/block/BlockProcessor.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/common/block/BlockProcessor.java index 9d4c1346fd8..3922423be15 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/common/block/BlockProcessor.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/common/block/BlockProcessor.java @@ -31,6 +31,7 @@ import tech.pegasys.teku.spec.datastructures.operations.AttesterSlashing; import tech.pegasys.teku.spec.datastructures.operations.Deposit; import tech.pegasys.teku.spec.datastructures.operations.ProposerSlashing; +import tech.pegasys.teku.spec.datastructures.operations.SignedBlsToExecutionChange; import tech.pegasys.teku.spec.datastructures.operations.SignedVoluntaryExit; import tech.pegasys.teku.spec.datastructures.state.beaconstate.BeaconState; import tech.pegasys.teku.spec.datastructures.state.beaconstate.MutableBeaconState; @@ -135,4 +136,7 @@ void validateExecutionPayload( throws BlockProcessingException; boolean isOptimistic(); + + void processBlsToExecutionChange( + MutableBeaconState state, SignedBlsToExecutionChange blsToExecutionChange); } diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/altair/block/BlockProcessorAltair.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/altair/block/BlockProcessorAltair.java index 98f3acdfa73..e74a2dcc46c 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/altair/block/BlockProcessorAltair.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/altair/block/BlockProcessorAltair.java @@ -44,6 +44,7 @@ import tech.pegasys.teku.spec.datastructures.operations.Attestation; import tech.pegasys.teku.spec.datastructures.operations.AttestationData; import tech.pegasys.teku.spec.datastructures.operations.Deposit; +import tech.pegasys.teku.spec.datastructures.operations.SignedBlsToExecutionChange; import tech.pegasys.teku.spec.datastructures.state.beaconstate.BeaconState; import tech.pegasys.teku.spec.datastructures.state.beaconstate.BeaconStateCache; import tech.pegasys.teku.spec.datastructures.state.beaconstate.MutableBeaconState; @@ -292,6 +293,12 @@ public boolean isOptimistic() { return false; } + @Override + public void processBlsToExecutionChange( + final MutableBeaconState state, final SignedBlsToExecutionChange blsToExecutionChange) { + throw new UnsupportedOperationException("No BlsToExecutionChange in Altair."); + } + public static boolean eth2FastAggregateVerify( final BLSSignatureVerifier signatureVerifier, List pubkeys, diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/bellatrix/block/BlockProcessorBellatrix.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/bellatrix/block/BlockProcessorBellatrix.java index 77a56cc8334..57373323029 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/bellatrix/block/BlockProcessorBellatrix.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/bellatrix/block/BlockProcessorBellatrix.java @@ -23,6 +23,7 @@ import tech.pegasys.teku.spec.datastructures.blocks.blockbody.versions.bellatrix.BlindedBeaconBlockBodyBellatrix; import tech.pegasys.teku.spec.datastructures.execution.ExecutionPayload; import tech.pegasys.teku.spec.datastructures.execution.ExecutionPayloadHeader; +import tech.pegasys.teku.spec.datastructures.operations.SignedBlsToExecutionChange; import tech.pegasys.teku.spec.datastructures.state.beaconstate.BeaconState; import tech.pegasys.teku.spec.datastructures.state.beaconstate.MutableBeaconState; import tech.pegasys.teku.spec.datastructures.state.beaconstate.versions.bellatrix.BeaconStateBellatrix; @@ -177,4 +178,10 @@ public void validateExecutionPayload( public boolean isOptimistic() { return true; } + + @Override + public void processBlsToExecutionChange( + final MutableBeaconState state, final SignedBlsToExecutionChange blsToExecutionChange) { + throw new UnsupportedOperationException("No BlsToExecutionChange in Bellatrix."); + } } diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/phase0/block/BlockProcessorPhase0.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/phase0/block/BlockProcessorPhase0.java index 7e21fa2f54c..c67c7a0921a 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/phase0/block/BlockProcessorPhase0.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/phase0/block/BlockProcessorPhase0.java @@ -22,6 +22,7 @@ import tech.pegasys.teku.spec.datastructures.execution.ExecutionPayloadHeader; import tech.pegasys.teku.spec.datastructures.operations.Attestation; import tech.pegasys.teku.spec.datastructures.operations.AttestationData; +import tech.pegasys.teku.spec.datastructures.operations.SignedBlsToExecutionChange; import tech.pegasys.teku.spec.datastructures.state.PendingAttestation; import tech.pegasys.teku.spec.datastructures.state.beaconstate.BeaconState; import tech.pegasys.teku.spec.datastructures.state.beaconstate.MutableBeaconState; @@ -123,4 +124,10 @@ public void validateExecutionPayload( public boolean isOptimistic() { return false; } + + @Override + public void processBlsToExecutionChange( + final MutableBeaconState state, final SignedBlsToExecutionChange blsToExecutionChange) { + throw new UnsupportedOperationException("No BlsToExecutionChange in phase0"); + } }