Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ public void shouldReturnNetworkIdentity() throws Exception {
final MetadataMessage metadataMessage =
spec.getGenesisSchemaDefinitions()
.getMetadataMessageSchema()
.create(seqnr, List.of(1, 11, 15), Collections.emptyList());
.create(seqnr, List.of(1, 11, 15), Collections.emptyList(), Optional.empty());

when(eth2P2PNetwork.getMetadata()).thenReturn(metadataMessage);

Expand All @@ -73,7 +73,7 @@ public void shouldReturnNetworkIdentityAltair() throws Exception {
final MetadataMessage metadataMessage =
spec.getGenesisSchemaDefinitions()
.getMetadataMessageSchema()
.create(seqnr, List.of(1, 11, 15), List.of(0, 1, 2, 3));
.create(seqnr, List.of(1, 11, 15), List.of(0, 1, 2, 3), Optional.empty());

when(eth2P2PNetwork.getMetadata()).thenReturn(metadataMessage);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,18 @@ public abstract class Eth2ReferenceTestCase {
.putAll(MerkleProofTests.MERKLE_PROOF_TEST_TYPES)
.build();

private static final ImmutableMap<String, TestExecutor> FULU_TEST_TYPES =
ImmutableMap.<String, TestExecutor>builder()
.putAll(ForkUpgradeTestExecutor.FORK_UPGRADE_TEST_TYPES)
.putAll(RewardsTestExecutorBellatrix.REWARDS_TEST_TYPES)
.put("merkle_proof/single_merkle_proof", TestExecutor.IGNORE_TESTS)
// TODO-fulu enable merkle proof tests
// .putAll(MerkleProofTests.MERKLE_PROOF_TEST_TYPES)
// TODO-fulu networking test types (networking/compute_columns_for_custody_group)
.put("networking/get_custody_groups", TestExecutor.IGNORE_TESTS)
.put("networking/compute_columns_for_custody_group", TestExecutor.IGNORE_TESTS)
.build();

protected void runReferenceTest(final TestDefinition testDefinition) throws Throwable {
getExecutorFor(testDefinition).runTest(testDefinition);
}
Expand All @@ -112,6 +124,7 @@ private TestExecutor getExecutorFor(final TestDefinition testDefinition) {
case TestFork.CAPELLA -> CAPELLA_TEST_TYPES.get(testDefinition.getTestType());
case TestFork.DENEB -> DENEB_TEST_TYPES.get(testDefinition.getTestType());
case TestFork.ELECTRA -> ELECTRA_TEST_TYPES.get(testDefinition.getTestType());
case TestFork.FULU -> FULU_TEST_TYPES.get(testDefinition.getTestType());
default -> null;
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import tech.pegasys.teku.spec.datastructures.state.beaconstate.versions.bellatrix.BeaconStateSchemaBellatrix;
import tech.pegasys.teku.spec.datastructures.state.beaconstate.versions.capella.BeaconStateSchemaCapella;
import tech.pegasys.teku.spec.datastructures.state.beaconstate.versions.deneb.BeaconStateSchemaDeneb;
import tech.pegasys.teku.spec.datastructures.state.beaconstate.versions.electra.BeaconStateSchemaElectra;
import tech.pegasys.teku.spec.datastructures.state.beaconstate.versions.phase0.BeaconStateSchemaPhase0;
import tech.pegasys.teku.spec.logic.common.forktransition.StateUpgrade;

Expand Down Expand Up @@ -65,6 +66,10 @@ private void processUpgrade(final TestDefinition testDefinition, final SpecMiles
BeaconStateSchemaDeneb.create(
previousMilestoneSpecVersion.getConfig(),
previousMilestoneSpecVersion.getSchemaDefinitions().getSchemaRegistry());
case FULU ->
BeaconStateSchemaElectra.create(
previousMilestoneSpecVersion.getConfig(),
previousMilestoneSpecVersion.getSchemaDefinitions().getSchemaRegistry());
default ->
throw new IllegalStateException(
"Unhandled fork upgrade for test "
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/*
* 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.reference.phase0.kzg;

import static org.assertj.core.api.Assertions.assertThat;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.google.common.collect.Streams;
import java.util.List;
import org.apache.tuweni.bytes.Bytes;
import tech.pegasys.teku.ethtests.finder.TestDefinition;
import tech.pegasys.teku.kzg.KZG;
import tech.pegasys.teku.kzg.KZGCell;
import tech.pegasys.teku.kzg.KZGCellAndProof;
import tech.pegasys.teku.kzg.KZGProof;

public class KzgComputeCellsAndKzgProofsTestExecutor extends KzgTestExecutor {

@Override
@SuppressWarnings("deprecation")
public void runTest(final TestDefinition testDefinition, final KZG kzg) throws Throwable {
final Data data = loadDataFile(testDefinition, Data.class);
final List<KZGCellAndProof> expectedKzgCellsAndProofs = data.getOutput();
List<KZGCellAndProof> actualKzgCellsAndProofs;
try {
final Bytes blob = data.getInput().getBlob();
actualKzgCellsAndProofs = kzg.computeCellsAndProofs(blob);
} catch (final RuntimeException ex) {
actualKzgCellsAndProofs = null;
}
assertThat(actualKzgCellsAndProofs).isEqualTo(expectedKzgCellsAndProofs);
}

private static class Data {
@JsonProperty(value = "input", required = true)
private Input input;

@JsonProperty(value = "output", required = true)
private List<String>[] output;

public Input getInput() {
return input;
}

public List<KZGCellAndProof> getOutput() {
return output == null
? null
: Streams.zip(
output[0].stream()
.map(cellString -> new KZGCell(Bytes.fromHexString(cellString))),
output[1].stream().map(KZGProof::fromHexString),
KZGCellAndProof::new)
.toList();
}

private static class Input {
@JsonProperty(value = "blob", required = true)
private String blob;

public Bytes getBlob() {
return Bytes.fromHexString(blob);
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/*
* Copyright Consensys Software Inc., 2025
*
* 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.reference.phase0.kzg;

import static org.assertj.core.api.Assertions.assertThat;

import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.List;
import org.apache.tuweni.bytes.Bytes;
import tech.pegasys.teku.ethtests.finder.TestDefinition;
import tech.pegasys.teku.kzg.KZG;
import tech.pegasys.teku.kzg.KZGCell;

public class KzgComputeCellsTestExecutor extends KzgTestExecutor {

@Override
public void runTest(final TestDefinition testDefinition, final KZG kzg) throws Throwable {
final Data data = loadDataFile(testDefinition, Data.class);
final List<KZGCell> expectedKzgCells = data.getOutput();
List<KZGCell> actualKzgCells;
try {
final Bytes blob = data.getInput().getBlob();
actualKzgCells = kzg.computeCells(blob);
} catch (final RuntimeException ex) {
actualKzgCells = null;
}

if (expectedKzgCells == null) {
assertThat(actualKzgCells).isNull();
} else {
assertThat(actualKzgCells).isEqualTo(expectedKzgCells);
}
}

private static class Data {

@JsonProperty(value = "input", required = true)
private Input input;

@JsonProperty(value = "output", required = true)
private List<String> output;

public Input getInput() {
return input;
}

public List<KZGCell> getOutput() {
return output == null
? null
: output.stream()
.map(cellString -> new KZGCell(Bytes.fromHexString(cellString)))
.toList();
}

private static class Input {

@JsonProperty(value = "blob", required = true)
private String blob;

public Bytes getBlob() {
return Bytes.fromHexString(blob);
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
/*
* 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.reference.phase0.kzg;

import static org.assertj.core.api.Assertions.assertThat;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.google.common.collect.Streams;
import java.util.List;
import java.util.stream.IntStream;
import org.apache.tuweni.bytes.Bytes;
import org.apache.tuweni.bytes.Bytes48;
import tech.pegasys.teku.ethtests.finder.TestDefinition;
import tech.pegasys.teku.kzg.KZG;
import tech.pegasys.teku.kzg.KZGCell;
import tech.pegasys.teku.kzg.KZGCellAndProof;
import tech.pegasys.teku.kzg.KZGCellWithColumnId;
import tech.pegasys.teku.kzg.KZGProof;

public class KzgRecoverCellsAndKzgProofsTestExecutor extends KzgTestExecutor {

@Override
public void runTest(final TestDefinition testDefinition, final KZG kzg) throws Throwable {
final Data data = loadDataFile(testDefinition, Data.class);
final List<KZGCellAndProof> expectedKzgCells = data.getOutput();
List<KZGCellAndProof> actualKzgCells;
try {
final List<Integer> cellIds = data.getInput().getCellIndices();
final List<KZGCell> cells = data.getInput().getCells();
if (cells.size() != cellIds.size()) {
throw new RuntimeException("Cells doesn't match ids");
}
final List<KZGCellWithColumnId> cellWithIds =
Streams.zip(cells.stream(), cellIds.stream(), KZGCellWithColumnId::fromCellAndColumn)
.toList();
actualKzgCells = kzg.recoverCellsAndProofs(cellWithIds);
} catch (final RuntimeException ex) {
actualKzgCells = null;
}
assertThat(actualKzgCells).isEqualTo(expectedKzgCells);
}

private static class Data {
@JsonProperty(value = "input", required = true)
private Input input;

@JsonProperty(value = "output", required = true)
private List<List<String>> output;

public Input getInput() {
return input;
}

public List<KZGCellAndProof> getOutput() {
if (output == null) {
return null;
}
final List<String> cellStrings = output.get(0);
final List<String> proofStrings = output.get(1);
if (cellStrings.size() != proofStrings.size()) {
throw new RuntimeException("Number of cells and proofs should be the same");
}
return IntStream.range(0, cellStrings.size())
.mapToObj(
index ->
new KZGCellAndProof(
new KZGCell(Bytes.fromHexString(cellStrings.get(index))),
KZGProof.fromHexString(proofStrings.get(index))))
.toList();
}

private static class Input {
@JsonProperty(value = "cell_indices", required = true)
private List<Integer> cellIndices;

@JsonProperty(value = "cells", required = true)
private List<String> cells;

@JsonProperty(value = "proofs", required = true)
private List<String> proofs;

public List<Integer> getCellIndices() {
return cellIndices;
}

public List<KZGCell> getCells() {
return cells.stream()
.map(cellString -> new KZGCell(Bytes.fromHexString(cellString)))
.toList();
}

@SuppressWarnings("Unused")
public List<KZGProof> getProfos() {
return proofs.stream()
.map(proofString -> new KZGProof(Bytes48.fromHexString(proofString)))
.toList();
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,10 @@ public class KzgTests {
.put("kzg/verify_blob_kzg_proof_batch", new KzgVerifyBlobProofBatchTestExecutor())
// no KZG interface on CL side, EL responsibility
.put("kzg/verify_kzg_proof", TestExecutor.IGNORE_TESTS)
// DataColumnSidecar PeerDAS Fulu utils
.put("kzg/compute_cells", new KzgComputeCellsTestExecutor())
.put("kzg/compute_cells_and_kzg_proofs", new KzgComputeCellsAndKzgProofsTestExecutor())
.put("kzg/recover_cells_and_kzg_proofs", new KzgRecoverCellsAndKzgProofsTestExecutor())
.put("kzg/verify_cell_kzg_proof_batch", new KzgVerifyCellKzgProofBatchTestExecutor())
.build();
}
Loading