Skip to content

Commit e9edb9b

Browse files
authored
Fork choice compliance test integration (Consensys#10031)
1 parent 5ff7d1c commit e9edb9b

File tree

1 file changed

+84
-5
lines changed

1 file changed

+84
-5
lines changed

eth-reference-tests/src/referenceTest/java/tech/pegasys/teku/reference/phase0/forkchoice/ForkChoiceTestExecutor.java

Lines changed: 84 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,14 @@
1717
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
1818
import static tech.pegasys.teku.infrastructure.async.SafeFutureAssert.safeJoin;
1919
import static tech.pegasys.teku.infrastructure.time.TimeUtilities.secondsToMillis;
20+
import static tech.pegasys.teku.reference.BlsSetting.IGNORED;
21+
import static tech.pegasys.teku.reference.TestDataUtils.loadYaml;
2022

23+
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
24+
import com.fasterxml.jackson.annotation.JsonProperty;
2125
import com.google.common.collect.ImmutableMap;
2226
import java.io.IOException;
27+
import java.nio.file.Path;
2328
import java.util.ArrayList;
2429
import java.util.Collections;
2530
import java.util.List;
@@ -40,6 +45,7 @@
4045
import tech.pegasys.teku.infrastructure.unsigned.UInt64;
4146
import tech.pegasys.teku.kzg.KZG;
4247
import tech.pegasys.teku.kzg.KZGProof;
48+
import tech.pegasys.teku.reference.BlsSetting;
4349
import tech.pegasys.teku.reference.KzgRetriever;
4450
import tech.pegasys.teku.reference.TestDataUtils;
4551
import tech.pegasys.teku.reference.TestExecutor;
@@ -53,12 +59,15 @@
5359
import tech.pegasys.teku.spec.datastructures.blocks.SignedBlockAndState;
5460
import tech.pegasys.teku.spec.datastructures.blocks.SlotAndBlockRoot;
5561
import tech.pegasys.teku.spec.datastructures.execution.PowBlock;
62+
import tech.pegasys.teku.spec.datastructures.forkchoice.ProtoNodeData;
63+
import tech.pegasys.teku.spec.datastructures.forkchoice.ReadOnlyForkChoiceStrategy;
5664
import tech.pegasys.teku.spec.datastructures.forkchoice.VoteUpdater;
5765
import tech.pegasys.teku.spec.datastructures.operations.Attestation;
5866
import tech.pegasys.teku.spec.datastructures.operations.AttesterSlashing;
5967
import tech.pegasys.teku.spec.datastructures.state.AnchorPoint;
6068
import tech.pegasys.teku.spec.datastructures.state.Checkpoint;
6169
import tech.pegasys.teku.spec.datastructures.state.beaconstate.BeaconState;
70+
import tech.pegasys.teku.spec.datastructures.util.AttestationProcessingResult;
6271
import tech.pegasys.teku.spec.executionlayer.ExecutionLayerChannelStub;
6372
import tech.pegasys.teku.spec.executionlayer.ExecutionPayloadStatus;
6473
import tech.pegasys.teku.spec.executionlayer.PayloadStatus;
@@ -97,6 +106,13 @@ public class ForkChoiceTestExecutor implements TestExecutor {
97106
.put("fork_choice/should_override_forkchoice_update", new ForkChoiceTestExecutor())
98107
.put("fork_choice/get_proposer_head", new ForkChoiceTestExecutor("basic_is_parent_root"))
99108
.put("fork_choice/deposit_with_reorg", new ForkChoiceTestExecutor())
109+
// Fork choice generated test types
110+
.put("fork_choice_compliance/block_weight_test", new ForkChoiceTestExecutor())
111+
.put("fork_choice_compliance/block_tree_test", new ForkChoiceTestExecutor())
112+
.put("fork_choice_compliance/attester_slashing_test", new ForkChoiceTestExecutor())
113+
.put("fork_choice_compliance/invalid_message_test", new ForkChoiceTestExecutor())
114+
.put("fork_choice_compliance/block_cover_test", new ForkChoiceTestExecutor())
115+
.put("fork_choice_compliance/shuffling_test", new ForkChoiceTestExecutor())
100116
.build();
101117

102118
private final List<?> testsToSkip;
@@ -112,9 +128,10 @@ public void runTest(final TestDefinition testDefinition) throws Throwable {
112128
"Test " + testDefinition.getDisplayName() + " has been ignored");
113129
}
114130

115-
// Note: The fork choice spec says there may be settings in a meta.yaml file but currently no
116-
// tests actually have one, so we currently don't bother trying to load it.
117-
final Spec spec = testDefinition.getSpec();
131+
// Load `meta.yaml` and read the BLS setting
132+
final ForkChoiceMetaData metaData = getMetaData(testDefinition);
133+
final boolean blsDisabled = metaData.getBlsSetting() == IGNORED;
134+
final Spec spec = testDefinition.getSpec(!blsDisabled);
118135
final BeaconState anchorState =
119136
TestDataUtils.loadStateFromSsz(testDefinition, "anchor_state" + SSZ_SNAPPY_EXTENSION);
120137
final SignedBeaconBlock anchorBlock = loadAnchorBlock(testDefinition);
@@ -300,14 +317,20 @@ private void applyAttestation(
300317
final ForkChoice forkChoice,
301318
final Map<String, Object> step) {
302319
final String attestationName = get(step, "attestation");
320+
final boolean valid = !step.containsKey("valid") || (boolean) step.get("valid");
303321
final Attestation attestation =
304322
TestDataUtils.loadSsz(
305323
testDefinition,
306324
attestationName + SSZ_SNAPPY_EXTENSION,
307325
testDefinition.getSpec().getGenesisSchemaDefinitions().getAttestationSchema());
308326
final Spec spec = testDefinition.getSpec();
309-
assertThat(forkChoice.onAttestation(ValidatableAttestation.from(spec, attestation)))
310-
.isCompleted();
327+
final SafeFuture<AttestationProcessingResult> result =
328+
forkChoice.onAttestation(ValidatableAttestation.from(spec, attestation));
329+
assertThat(result).isCompleted();
330+
AttestationProcessingResult processingResult = safeJoin(result);
331+
assertThat(processingResult.isSuccessful())
332+
.withFailMessage(processingResult.getInvalidReason())
333+
.isEqualTo(valid);
311334
}
312335

313336
private void applyAttesterSlashing(
@@ -530,6 +553,32 @@ private void applyChecks(
530553
assertThat(expectedValidatorIsConnected).isTrue();
531554
}
532555

556+
case "viable_for_head_roots_and_weights" -> {
557+
final List<Map<String, Object>> viableHeadRootsAndWeightsData = get(checks, checkType);
558+
final Map<Bytes32, UInt64> viableHeadRootsAndWeights =
559+
viableHeadRootsAndWeightsData.stream()
560+
.collect(
561+
Collectors.toMap(
562+
entry -> Bytes32.fromHexString((String) entry.get("root")),
563+
entry -> UInt64.valueOf(entry.get("weight").toString())));
564+
final Map<Bytes32, UInt64> chainHeadRootsAndWeights =
565+
recentChainData
566+
.getForkChoiceStrategy()
567+
.map(ReadOnlyForkChoiceStrategy::getChainHeads)
568+
.orElse(Collections.emptyList())
569+
.stream()
570+
.collect(Collectors.toMap(ProtoNodeData::getRoot, ProtoNodeData::getWeight));
571+
572+
assertThat(chainHeadRootsAndWeights.keySet())
573+
.containsAll(viableHeadRootsAndWeights.keySet());
574+
575+
for (Bytes32 root : viableHeadRootsAndWeights.keySet()) {
576+
UInt64 weight = viableHeadRootsAndWeights.get(root);
577+
UInt64 actualWeight = chainHeadRootsAndWeights.get(root);
578+
assertThat(actualWeight).describedAs("block %s's weight", root).isEqualTo(weight);
579+
}
580+
}
581+
533582
default ->
534583
throw new UnsupportedOperationException("Unsupported check type: " + checkType);
535584
}
@@ -581,4 +630,34 @@ private static Optional<Bytes32> getOptionallyBytes32(
581630
final Map<String, Object> yamlData, final String key) {
582631
return ForkChoiceTestExecutor.<String>getOptionally(yamlData, key).map(Bytes32::fromHexString);
583632
}
633+
634+
private static ForkChoiceMetaData getMetaData(final TestDefinition testDefinition)
635+
throws IOException {
636+
final ForkChoiceMetaData metaData;
637+
final Path metaPath = testDefinition.getTestDirectory().resolve("meta.yaml");
638+
if (metaPath.toFile().exists()) {
639+
metaData = loadYaml(testDefinition, "meta.yaml", ForkChoiceMetaData.class);
640+
} else {
641+
metaData = ForkChoiceMetaData.DEFAULT;
642+
}
643+
644+
return metaData;
645+
}
646+
647+
@JsonIgnoreProperties(ignoreUnknown = true)
648+
private static class ForkChoiceMetaData {
649+
static final ForkChoiceMetaData DEFAULT = new ForkChoiceMetaData(0);
650+
651+
private ForkChoiceMetaData(
652+
@JsonProperty(value = "bls_setting", required = false, defaultValue = "0")
653+
final int blsSetting) {
654+
this.blsSetting = blsSetting;
655+
}
656+
657+
private final int blsSetting;
658+
659+
public BlsSetting getBlsSetting() {
660+
return BlsSetting.forCode(blsSetting);
661+
}
662+
}
584663
}

0 commit comments

Comments
 (0)