Skip to content

Commit

Permalink
Reference tests for EIP-7594 + utils implementation (Consensys#36)
Browse files Browse the repository at this point in the history
* eference tests 1.5.0.alpha.1 with EIP-7594 coverage activated
* computeCustodyColumnIndexes implemented
* verifyCellProofBatch implemented, it fails badly on some tests, so it's disabled. jc-kzg update should help I think
  • Loading branch information
zilm13 authored May 7, 2024
1 parent 3ac6cc5 commit 3c38ebc
Show file tree
Hide file tree
Showing 26 changed files with 771 additions and 62 deletions.
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@ allprojects {
}
}

def refTestVersion = 'v1.4.0' // Arbitrary change to refresh cache number: 1
def refTestVersion = 'v1.5.0-alpha.1' // Arbitrary change to refresh cache number: 1
def blsRefTestVersion = 'v0.1.2'
def refTestBaseUrl = 'https://github.com/ethereum/consensus-spec-tests/releases/download'
def blsRefTestBaseUrl = 'https://github.com/ethereum/bls12-381-tests/releases/download'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import tech.pegasys.teku.reference.common.epoch_processing.EpochProcessingTestExecutor;
import tech.pegasys.teku.reference.common.operations.OperationsTestExecutor;
import tech.pegasys.teku.reference.deneb.merkle_proof.MerkleProofTests;
import tech.pegasys.teku.reference.eip7594.networking.NetworkingTests;
import tech.pegasys.teku.reference.phase0.bls.BlsTests;
import tech.pegasys.teku.reference.phase0.forkchoice.ForkChoiceTestExecutor;
import tech.pegasys.teku.reference.phase0.genesis.GenesisTests;
Expand Down Expand Up @@ -87,6 +88,12 @@ public abstract class Eth2ReferenceTestCase {
.putAll(MerkleProofTests.MERKLE_PROOF_TEST_TYPES)
.build();

private static final ImmutableMap<String, TestExecutor> EIP7594_TEST_TYPES =
ImmutableMap.<String, TestExecutor>builder()
.putAll(MerkleProofTests.MERKLE_PROOF_TEST_TYPES)
.putAll(NetworkingTests.NETWORKING_TEST_TYPES)
.build();

protected void runReferenceTest(final TestDefinition testDefinition) throws Throwable {
getExecutorFor(testDefinition).runTest(testDefinition);
}
Expand All @@ -100,6 +107,7 @@ private TestExecutor getExecutorFor(final TestDefinition testDefinition) {
case TestFork.BELLATRIX -> BELLATRIX_TEST_TYPES.get(testDefinition.getTestType());
case TestFork.CAPELLA -> CAPELLA_TEST_TYPES.get(testDefinition.getTestType());
case TestFork.DENEB -> DENEB_TEST_TYPES.get(testDefinition.getTestType());
case TestFork.EIP7594 -> EIP7594_TEST_TYPES.get(testDefinition.getTestType());
default -> null;
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,11 @@ public class KzgRetriever {
private static final Map<String, String> TRUSTED_SETUP_FILES_BY_NETWORK = Maps.newHashMap();

public static KZG getKzgWithLoadedTrustedSetup(final Spec spec, final String network) {
if (!spec.isMilestoneSupported(SpecMilestone.DENEB)) {
return KZG.NOOP;
if (spec.isMilestoneSupported(SpecMilestone.DENEB)
|| spec.isMilestoneSupported(SpecMilestone.EIP7594)) {
return getKzgWithLoadedTrustedSetup(network);
}
return getKzgWithLoadedTrustedSetup(network);
return KZG.NOOP;
}

public static KZG getKzgWithLoadedTrustedSetup(final String network) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,7 @@ private enum Operation {
SYNC_AGGREGATE,
EXECUTION_PAYLOAD,
BLS_TO_EXECUTION_CHANGE,
WITHDRAWAL,
DEPOSIT_RECEIPT,
EXECUTION_LAYER_EXIT
WITHDRAWAL
}

public static final ImmutableMap<String, TestExecutor> OPERATIONS_TEST_TYPES =
Expand Down Expand Up @@ -114,13 +112,6 @@ private enum Operation {
.put(
"operations/withdrawals",
new OperationsTestExecutor<>("execution_payload.ssz_snappy", Operation.WITHDRAWAL))
.put(
"operations/deposit_receipt",
new OperationsTestExecutor<>("deposit_receipt.ssz_snappy", Operation.DEPOSIT_RECEIPT))
.put(
"operations/execution_layer_exit",
new OperationsTestExecutor<>(
"execution_layer_exit.ssz_snappy", Operation.EXECUTION_LAYER_EXIT))
.build();

private final String dataFileName;
Expand Down Expand Up @@ -396,9 +387,7 @@ public void checkBlockInclusionValidation(
ATTESTATION,
SYNC_AGGREGATE,
EXECUTION_PAYLOAD,
WITHDRAWAL,
DEPOSIT_RECEIPT,
EXECUTION_LAYER_EXIT -> {}
WITHDRAWAL -> {}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,12 @@
import tech.pegasys.teku.reference.TestDataUtils;
import tech.pegasys.teku.reference.TestExecutor;
import tech.pegasys.teku.spec.config.SpecConfigDeneb;
import tech.pegasys.teku.spec.config.SpecConfigEip7594;
import tech.pegasys.teku.spec.datastructures.blocks.blockbody.BeaconBlockBody;
import tech.pegasys.teku.spec.datastructures.type.SszKZGCommitment;
import tech.pegasys.teku.spec.logic.common.helpers.Predicates;
import tech.pegasys.teku.spec.logic.versions.deneb.helpers.MiscHelpersDeneb;
import tech.pegasys.teku.spec.logic.versions.eip7594.helpers.MiscHelpersEip7594;

public class SingleMerkleProofTestExecutor implements TestExecutor {
private static final Pattern TEST_NAME_PATTERN = Pattern.compile("(.+)/(.+)");
Expand Down Expand Up @@ -88,9 +90,12 @@ void runBeaconBlockBodyTest(
testDefinition,
OBJECT_SSZ_FILE,
testDefinition.getSpec().getGenesisSchemaDefinitions().getBeaconBlockBodySchema());

// Deneb
if (proofType.startsWith("blob_kzg_commitment_merkle_proof")) {
runBlobKzgCommitmentMerkleProofTest(testDefinition, data, beaconBlockBody);
// EIP-7594
} else if (proofType.startsWith("blob_kzg_commitments_merkle_proof")) {
runBlobKzgCommitmentsMerkleProofTest(testDefinition, data, beaconBlockBody);
} else {
throw new RuntimeException("Unknown proof type " + proofType);
}
Expand Down Expand Up @@ -135,6 +140,30 @@ private void runBlobKzgCommitmentMerkleProofTest(
.isEqualTo(data.branch.stream().map(Bytes32::fromHexString).toList());
}

private void runBlobKzgCommitmentsMerkleProofTest(
final TestDefinition testDefinition, final Data data, final BeaconBlockBody beaconBlockBody) {
final Predicates predicates = new Predicates(testDefinition.getSpec().getGenesisSpecConfig());
final Bytes32 kzgCommitmentsHash = Bytes32.fromHexString(data.leaf);

// Forward check
assertThat(
predicates.isValidMerkleBranch(
kzgCommitmentsHash,
createKzgCommitmentsMerkleProofBranchFromData(testDefinition, data.branch),
getKzgCommitmentsInclusionProofDepth(testDefinition),
data.leafIndex,
beaconBlockBody.hashTreeRoot()))
.isTrue();

// Verify 2 MiscHelpersEip7594 helpers
final MiscHelpersEip7594 miscHelpersEip7594 =
MiscHelpersEip7594.required(testDefinition.getSpec().getGenesisSpec().miscHelpers());
assertThat(miscHelpersEip7594.getBlockBodyKzgCommitmentsGeneralizedIndex())
.isEqualTo(data.leafIndex);
assertThat(miscHelpersEip7594.computeDataColumnKzgCommitmentsInclusionProof(beaconBlockBody))
.isEqualTo(data.branch.stream().map(Bytes32::fromHexString).toList());
}

private SszBytes32Vector createKzgCommitmentMerkleProofBranchFromData(
final TestDefinition testDefinition, final List<String> branch) {
final SszBytes32VectorSchema<?> kzgCommitmentInclusionProofSchema =
Expand All @@ -153,4 +182,24 @@ private int getKzgCommitmentInclusionProofDepth(final TestDefinition testDefinit
return SpecConfigDeneb.required(testDefinition.getSpec().getGenesisSpecConfig())
.getKzgCommitmentInclusionProofDepth();
}

private SszBytes32Vector createKzgCommitmentsMerkleProofBranchFromData(
final TestDefinition testDefinition, final List<String> branch) {
final SszBytes32VectorSchema<?> kzgCommitmentsInclusionProofSchema =
testDefinition
.getSpec()
.getGenesisSchemaDefinitions()
.toVersionEip7594()
.orElseThrow()
.getDataColumnSidecarSchema()
.getKzgCommitmentsInclusionProofSchema();
return kzgCommitmentsInclusionProofSchema.createFromElements(
branch.stream().map(Bytes32::fromHexString).map(SszBytes32::of).toList());
}

private int getKzgCommitmentsInclusionProofDepth(final TestDefinition testDefinition) {
return SpecConfigEip7594.required(testDefinition.getSpec().getGenesisSpecConfig())
.getKzgCommitmentsInclusionProofDepth()
.intValue();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/*
* 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.eip7594.networking;

import static org.assertj.core.api.Assertions.assertThat;
import static tech.pegasys.teku.reference.TestDataUtils.loadYaml;

import com.fasterxml.jackson.annotation.JsonProperty;
import java.math.BigInteger;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import org.apache.tuweni.units.bigints.UInt256;
import tech.pegasys.teku.ethtests.finder.TestDefinition;
import tech.pegasys.teku.infrastructure.unsigned.UInt64;
import tech.pegasys.teku.reference.TestExecutor;
import tech.pegasys.teku.spec.SpecVersion;
import tech.pegasys.teku.spec.logic.versions.eip7594.helpers.MiscHelpersEip7594;

public class GetCustodyColumnsTestExecutor implements TestExecutor {

@Override
public void runTest(final TestDefinition testDefinition) throws Exception {
final GetCustodyColumnsMetaData metaData =
loadYaml(testDefinition, "meta.yaml", GetCustodyColumnsMetaData.class);
final SpecVersion spec = testDefinition.getSpec().getGenesisSpec();
final Set<UInt64> actualResult =
MiscHelpersEip7594.required(spec.miscHelpers())
.computeCustodyColumnIndexes(metaData.getNodeId(), metaData.getCustodySubnetCount());
assertThat(actualResult).isEqualTo(metaData.getResult());
}

private static class GetCustodyColumnsMetaData {

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

@JsonProperty(value = "custody_subnet_count", required = true)
private int custodySubnetCount;

@JsonProperty(value = "result", required = true)
private List<Integer> result;

public UInt256 getNodeId() {
return UInt256.valueOf(new BigInteger(nodeId));
}

public int getCustodySubnetCount() {
return custodySubnetCount;
}

public Set<UInt64> getResult() {
return result.stream().map(UInt64::valueOf).collect(Collectors.toUnmodifiableSet());
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
* Copyright Consensys Software Inc., 2023
*
* 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.eip7594.networking;

import com.google.common.collect.ImmutableMap;
import tech.pegasys.teku.reference.TestExecutor;

public class NetworkingTests {
public static final ImmutableMap<String, TestExecutor> NETWORKING_TEST_TYPES =
ImmutableMap.<String, TestExecutor>builder()
.put("networking/get_custody_columns", new GetCustodyColumnsTestExecutor())
.build();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/*
* 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
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);
}
}
}
}
Loading

0 comments on commit 3c38ebc

Please sign in to comment.