From 00bb3ff2b8b86dde12108b45bcc600c823140cc6 Mon Sep 17 00:00:00 2001 From: Bastin <43618253+Inspector-Butters@users.noreply.github.com> Date: Tue, 20 May 2025 18:08:41 +0200 Subject: [PATCH] Add Light Client Minimal Spec Tests Part 1 (#15297) * single merkle proof - altair * single merkle proof - bellatrix - mainnet * single merkle proof - capella - mainnet * single merkle proof - deneb - mainnet * single merkle proof - electra - mainnet * changelog entry * typo * merge all into common * update ranking * single merkle proof * changelog entry * update exclusions.txt --- changelog/bastin_add-lc-spec-test-minimal.md | 3 + testing/spectest/exclusions.txt | 14 +-- .../minimal/altair/light_client/BUILD.bazel | 22 ++++ .../light_client/single_merkle_proof_test.go | 12 ++ .../light_client/update_ranking_test.go | 12 ++ .../bellatrix/light_client/BUILD.bazel | 22 ++++ .../light_client/single_merkle_proof_test.go | 12 ++ .../light_client/update_ranking_test.go | 12 ++ .../minimal/capella/light_client/BUILD.bazel | 22 ++++ .../light_client/single_merkle_proof_test.go | 12 ++ .../light_client/update_ranking_test.go | 12 ++ .../minimal/deneb/light_client/BUILD.bazel | 22 ++++ .../light_client/single_merkle_proof_test.go | 12 ++ .../deneb/light_client/update_ranking_test.go | 12 ++ .../minimal/electra/light_client/BUILD.bazel | 22 ++++ .../light_client/single_merkle_proof_test.go | 12 ++ .../light_client/update_ranking_test.go | 12 ++ .../shared/common/light_client/BUILD.bazel | 8 +- .../common/light_client/update_ranking.go | 105 ++++++++++++++++++ 19 files changed, 351 insertions(+), 9 deletions(-) create mode 100644 changelog/bastin_add-lc-spec-test-minimal.md create mode 100644 testing/spectest/minimal/altair/light_client/BUILD.bazel create mode 100644 testing/spectest/minimal/altair/light_client/single_merkle_proof_test.go create mode 100644 testing/spectest/minimal/altair/light_client/update_ranking_test.go create mode 100644 testing/spectest/minimal/bellatrix/light_client/BUILD.bazel create mode 100644 testing/spectest/minimal/bellatrix/light_client/single_merkle_proof_test.go create mode 100644 testing/spectest/minimal/bellatrix/light_client/update_ranking_test.go create mode 100644 testing/spectest/minimal/capella/light_client/BUILD.bazel create mode 100644 testing/spectest/minimal/capella/light_client/single_merkle_proof_test.go create mode 100644 testing/spectest/minimal/capella/light_client/update_ranking_test.go create mode 100644 testing/spectest/minimal/deneb/light_client/BUILD.bazel create mode 100644 testing/spectest/minimal/deneb/light_client/single_merkle_proof_test.go create mode 100644 testing/spectest/minimal/deneb/light_client/update_ranking_test.go create mode 100644 testing/spectest/minimal/electra/light_client/BUILD.bazel create mode 100644 testing/spectest/minimal/electra/light_client/single_merkle_proof_test.go create mode 100644 testing/spectest/minimal/electra/light_client/update_ranking_test.go create mode 100644 testing/spectest/shared/common/light_client/update_ranking.go diff --git a/changelog/bastin_add-lc-spec-test-minimal.md b/changelog/bastin_add-lc-spec-test-minimal.md new file mode 100644 index 0000000000..06eefd3201 --- /dev/null +++ b/changelog/bastin_add-lc-spec-test-minimal.md @@ -0,0 +1,3 @@ +### Added + +- Add light client minimal spec test support for `update_ranking` tests. \ No newline at end of file diff --git a/testing/spectest/exclusions.txt b/testing/spectest/exclusions.txt index 902f17dbdf..670325bffc 100644 --- a/testing/spectest/exclusions.txt +++ b/testing/spectest/exclusions.txt @@ -1,16 +1,14 @@ # LightClient -tests/minimal/altair/light_client/single_merkle_proof tests/minimal/altair/light_client/sync -tests/minimal/altair/light_client/update_ranking -tests/minimal/bellatrix/light_client/single_merkle_proof tests/minimal/bellatrix/light_client/sync -tests/minimal/bellatrix/light_client/update_ranking -tests/minimal/capella/light_client/single_merkle_proof tests/minimal/capella/light_client/sync -tests/minimal/capella/light_client/update_ranking -tests/minimal/deneb/light_client/single_merkle_proof tests/minimal/deneb/light_client/sync -tests/minimal/deneb/light_client/update_ranking +tests/minimal/electra/light_client/sync +tests/minimal/altair/light_client/data_collection +tests/minimal/bellatrix/light_client/data_collection +tests/minimal/capella/light_client/data_collection +tests/minimal/deneb/light_client/data_collection +tests/minimal/electra/light_client/data_collection # SSZ Generic tests/general/phase0/ssz_generic/basic_vector diff --git a/testing/spectest/minimal/altair/light_client/BUILD.bazel b/testing/spectest/minimal/altair/light_client/BUILD.bazel new file mode 100644 index 0000000000..1a5e4f0941 --- /dev/null +++ b/testing/spectest/minimal/altair/light_client/BUILD.bazel @@ -0,0 +1,22 @@ +load("@prysm//tools/go:def.bzl", "go_test") + +go_test( + name = "go_default_test", + size = "small", + srcs = [ + "single_merkle_proof_test.go", + "update_ranking_test.go", + ], + data = glob(["*.yaml"]) + [ + "@consensus_spec_tests_minimal//:test_data", + ], + eth_network = "minimal", + tags = [ + "minimal", + "spectest", + ], + deps = [ + "//runtime/version:go_default_library", + "//testing/spectest/shared/common/light_client:go_default_library", + ], +) diff --git a/testing/spectest/minimal/altair/light_client/single_merkle_proof_test.go b/testing/spectest/minimal/altair/light_client/single_merkle_proof_test.go new file mode 100644 index 0000000000..1e11497029 --- /dev/null +++ b/testing/spectest/minimal/altair/light_client/single_merkle_proof_test.go @@ -0,0 +1,12 @@ +package light_client + +import ( + "testing" + + "github.com/OffchainLabs/prysm/v6/runtime/version" + "github.com/OffchainLabs/prysm/v6/testing/spectest/shared/common/light_client" +) + +func TestMainnet_Altair_LightClient_SingleMerkleProof(t *testing.T) { + light_client.RunLightClientSingleMerkleProofTests(t, "minimal", version.Altair) +} diff --git a/testing/spectest/minimal/altair/light_client/update_ranking_test.go b/testing/spectest/minimal/altair/light_client/update_ranking_test.go new file mode 100644 index 0000000000..6faa095961 --- /dev/null +++ b/testing/spectest/minimal/altair/light_client/update_ranking_test.go @@ -0,0 +1,12 @@ +package light_client + +import ( + "testing" + + "github.com/OffchainLabs/prysm/v6/runtime/version" + "github.com/OffchainLabs/prysm/v6/testing/spectest/shared/common/light_client" +) + +func TestMainnet_Altair_LightClient_UpdateRanking(t *testing.T) { + light_client.RunLightClientUpdateRankingTests(t, "minimal", version.Altair) +} diff --git a/testing/spectest/minimal/bellatrix/light_client/BUILD.bazel b/testing/spectest/minimal/bellatrix/light_client/BUILD.bazel new file mode 100644 index 0000000000..1a5e4f0941 --- /dev/null +++ b/testing/spectest/minimal/bellatrix/light_client/BUILD.bazel @@ -0,0 +1,22 @@ +load("@prysm//tools/go:def.bzl", "go_test") + +go_test( + name = "go_default_test", + size = "small", + srcs = [ + "single_merkle_proof_test.go", + "update_ranking_test.go", + ], + data = glob(["*.yaml"]) + [ + "@consensus_spec_tests_minimal//:test_data", + ], + eth_network = "minimal", + tags = [ + "minimal", + "spectest", + ], + deps = [ + "//runtime/version:go_default_library", + "//testing/spectest/shared/common/light_client:go_default_library", + ], +) diff --git a/testing/spectest/minimal/bellatrix/light_client/single_merkle_proof_test.go b/testing/spectest/minimal/bellatrix/light_client/single_merkle_proof_test.go new file mode 100644 index 0000000000..ee32d80655 --- /dev/null +++ b/testing/spectest/minimal/bellatrix/light_client/single_merkle_proof_test.go @@ -0,0 +1,12 @@ +package light_client + +import ( + "testing" + + "github.com/OffchainLabs/prysm/v6/runtime/version" + "github.com/OffchainLabs/prysm/v6/testing/spectest/shared/common/light_client" +) + +func TestMainnet_Bellatrix_LightClient_SingleMerkleProof(t *testing.T) { + light_client.RunLightClientSingleMerkleProofTests(t, "minimal", version.Bellatrix) +} diff --git a/testing/spectest/minimal/bellatrix/light_client/update_ranking_test.go b/testing/spectest/minimal/bellatrix/light_client/update_ranking_test.go new file mode 100644 index 0000000000..11e056ef38 --- /dev/null +++ b/testing/spectest/minimal/bellatrix/light_client/update_ranking_test.go @@ -0,0 +1,12 @@ +package light_client + +import ( + "testing" + + "github.com/OffchainLabs/prysm/v6/runtime/version" + "github.com/OffchainLabs/prysm/v6/testing/spectest/shared/common/light_client" +) + +func TestMainnet_Bellatrix_LightClient_UpdateRanking(t *testing.T) { + light_client.RunLightClientUpdateRankingTests(t, "minimal", version.Bellatrix) +} diff --git a/testing/spectest/minimal/capella/light_client/BUILD.bazel b/testing/spectest/minimal/capella/light_client/BUILD.bazel new file mode 100644 index 0000000000..1a5e4f0941 --- /dev/null +++ b/testing/spectest/minimal/capella/light_client/BUILD.bazel @@ -0,0 +1,22 @@ +load("@prysm//tools/go:def.bzl", "go_test") + +go_test( + name = "go_default_test", + size = "small", + srcs = [ + "single_merkle_proof_test.go", + "update_ranking_test.go", + ], + data = glob(["*.yaml"]) + [ + "@consensus_spec_tests_minimal//:test_data", + ], + eth_network = "minimal", + tags = [ + "minimal", + "spectest", + ], + deps = [ + "//runtime/version:go_default_library", + "//testing/spectest/shared/common/light_client:go_default_library", + ], +) diff --git a/testing/spectest/minimal/capella/light_client/single_merkle_proof_test.go b/testing/spectest/minimal/capella/light_client/single_merkle_proof_test.go new file mode 100644 index 0000000000..a13c0306e1 --- /dev/null +++ b/testing/spectest/minimal/capella/light_client/single_merkle_proof_test.go @@ -0,0 +1,12 @@ +package light_client + +import ( + "testing" + + "github.com/OffchainLabs/prysm/v6/runtime/version" + "github.com/OffchainLabs/prysm/v6/testing/spectest/shared/common/light_client" +) + +func TestMainnet_Capella_LightClient_SingleMerkleProof(t *testing.T) { + light_client.RunLightClientSingleMerkleProofTests(t, "minimal", version.Capella) +} diff --git a/testing/spectest/minimal/capella/light_client/update_ranking_test.go b/testing/spectest/minimal/capella/light_client/update_ranking_test.go new file mode 100644 index 0000000000..83e3373a5e --- /dev/null +++ b/testing/spectest/minimal/capella/light_client/update_ranking_test.go @@ -0,0 +1,12 @@ +package light_client + +import ( + "testing" + + "github.com/OffchainLabs/prysm/v6/runtime/version" + "github.com/OffchainLabs/prysm/v6/testing/spectest/shared/common/light_client" +) + +func TestMainnet_Capella_LightClient_UpdateRanking(t *testing.T) { + light_client.RunLightClientUpdateRankingTests(t, "minimal", version.Capella) +} diff --git a/testing/spectest/minimal/deneb/light_client/BUILD.bazel b/testing/spectest/minimal/deneb/light_client/BUILD.bazel new file mode 100644 index 0000000000..1a5e4f0941 --- /dev/null +++ b/testing/spectest/minimal/deneb/light_client/BUILD.bazel @@ -0,0 +1,22 @@ +load("@prysm//tools/go:def.bzl", "go_test") + +go_test( + name = "go_default_test", + size = "small", + srcs = [ + "single_merkle_proof_test.go", + "update_ranking_test.go", + ], + data = glob(["*.yaml"]) + [ + "@consensus_spec_tests_minimal//:test_data", + ], + eth_network = "minimal", + tags = [ + "minimal", + "spectest", + ], + deps = [ + "//runtime/version:go_default_library", + "//testing/spectest/shared/common/light_client:go_default_library", + ], +) diff --git a/testing/spectest/minimal/deneb/light_client/single_merkle_proof_test.go b/testing/spectest/minimal/deneb/light_client/single_merkle_proof_test.go new file mode 100644 index 0000000000..1339990244 --- /dev/null +++ b/testing/spectest/minimal/deneb/light_client/single_merkle_proof_test.go @@ -0,0 +1,12 @@ +package light_client + +import ( + "testing" + + "github.com/OffchainLabs/prysm/v6/runtime/version" + "github.com/OffchainLabs/prysm/v6/testing/spectest/shared/common/light_client" +) + +func TestMainnet_Deneb_LightClient_SingleMerkleProof(t *testing.T) { + light_client.RunLightClientSingleMerkleProofTests(t, "minimal", version.Deneb) +} diff --git a/testing/spectest/minimal/deneb/light_client/update_ranking_test.go b/testing/spectest/minimal/deneb/light_client/update_ranking_test.go new file mode 100644 index 0000000000..606f4da41c --- /dev/null +++ b/testing/spectest/minimal/deneb/light_client/update_ranking_test.go @@ -0,0 +1,12 @@ +package light_client + +import ( + "testing" + + "github.com/OffchainLabs/prysm/v6/runtime/version" + "github.com/OffchainLabs/prysm/v6/testing/spectest/shared/common/light_client" +) + +func TestMainnet_Deneb_LightClient_UpdateRanking(t *testing.T) { + light_client.RunLightClientUpdateRankingTests(t, "minimal", version.Deneb) +} diff --git a/testing/spectest/minimal/electra/light_client/BUILD.bazel b/testing/spectest/minimal/electra/light_client/BUILD.bazel new file mode 100644 index 0000000000..1a5e4f0941 --- /dev/null +++ b/testing/spectest/minimal/electra/light_client/BUILD.bazel @@ -0,0 +1,22 @@ +load("@prysm//tools/go:def.bzl", "go_test") + +go_test( + name = "go_default_test", + size = "small", + srcs = [ + "single_merkle_proof_test.go", + "update_ranking_test.go", + ], + data = glob(["*.yaml"]) + [ + "@consensus_spec_tests_minimal//:test_data", + ], + eth_network = "minimal", + tags = [ + "minimal", + "spectest", + ], + deps = [ + "//runtime/version:go_default_library", + "//testing/spectest/shared/common/light_client:go_default_library", + ], +) diff --git a/testing/spectest/minimal/electra/light_client/single_merkle_proof_test.go b/testing/spectest/minimal/electra/light_client/single_merkle_proof_test.go new file mode 100644 index 0000000000..bf8e635944 --- /dev/null +++ b/testing/spectest/minimal/electra/light_client/single_merkle_proof_test.go @@ -0,0 +1,12 @@ +package light_client + +import ( + "testing" + + "github.com/OffchainLabs/prysm/v6/runtime/version" + "github.com/OffchainLabs/prysm/v6/testing/spectest/shared/common/light_client" +) + +func TestMainnet_Electra_LightClient_SingleMerkleProof(t *testing.T) { + light_client.RunLightClientSingleMerkleProofTests(t, "minimal", version.Electra) +} diff --git a/testing/spectest/minimal/electra/light_client/update_ranking_test.go b/testing/spectest/minimal/electra/light_client/update_ranking_test.go new file mode 100644 index 0000000000..b646455ff8 --- /dev/null +++ b/testing/spectest/minimal/electra/light_client/update_ranking_test.go @@ -0,0 +1,12 @@ +package light_client + +import ( + "testing" + + "github.com/OffchainLabs/prysm/v6/runtime/version" + "github.com/OffchainLabs/prysm/v6/testing/spectest/shared/common/light_client" +) + +func TestMainnet_Electra_LightClient_UpdateRanking(t *testing.T) { + light_client.RunLightClientUpdateRankingTests(t, "minimal", version.Electra) +} diff --git a/testing/spectest/shared/common/light_client/BUILD.bazel b/testing/spectest/shared/common/light_client/BUILD.bazel index a588a4439d..8fe775bda4 100644 --- a/testing/spectest/shared/common/light_client/BUILD.bazel +++ b/testing/spectest/shared/common/light_client/BUILD.bazel @@ -3,13 +3,19 @@ load("@prysm//tools/go:def.bzl", "go_library") go_library( name = "go_default_library", testonly = True, - srcs = ["single_merkle_proof.go"], + srcs = [ + "single_merkle_proof.go", + "update_ranking.go", + ], importpath = "github.com/OffchainLabs/prysm/v6/testing/spectest/shared/common/light_client", visibility = ["//testing/spectest:__subpackages__"], deps = [ "//beacon-chain/core/helpers:go_default_library", + "//beacon-chain/core/light-client:go_default_library", "//beacon-chain/state:go_default_library", "//beacon-chain/state/state-native:go_default_library", + "//consensus-types/interfaces:go_default_library", + "//consensus-types/light-client:go_default_library", "//container/trie:go_default_library", "//proto/prysm/v1alpha1:go_default_library", "//runtime/version:go_default_library", diff --git a/testing/spectest/shared/common/light_client/update_ranking.go b/testing/spectest/shared/common/light_client/update_ranking.go new file mode 100644 index 0000000000..f403f61d5c --- /dev/null +++ b/testing/spectest/shared/common/light_client/update_ranking.go @@ -0,0 +1,105 @@ +package light_client + +import ( + "fmt" + "path" + "testing" + + "github.com/OffchainLabs/prysm/v6/beacon-chain/core/helpers" + lightclient "github.com/OffchainLabs/prysm/v6/beacon-chain/core/light-client" + "github.com/OffchainLabs/prysm/v6/consensus-types/interfaces" + lightclienttypes "github.com/OffchainLabs/prysm/v6/consensus-types/light-client" + ethpb "github.com/OffchainLabs/prysm/v6/proto/prysm/v1alpha1" + "github.com/OffchainLabs/prysm/v6/runtime/version" + "github.com/OffchainLabs/prysm/v6/testing/require" + "github.com/OffchainLabs/prysm/v6/testing/spectest/utils" + "github.com/OffchainLabs/prysm/v6/testing/util" + "github.com/golang/snappy" +) + +// RunLightClientUpdateRankingTests executes "light_client/update_ranking/pyspec_tests/update_ranking" tests. +func RunLightClientUpdateRankingTests(t *testing.T, config string, v int) { + require.NoError(t, utils.SetConfig(t, config)) + + _, testsFolderPath := utils.TestFolders(t, config, version.String(v), "light_client/update_ranking/pyspec_tests/") + testTypes, err := util.BazelListDirectories(testsFolderPath) + require.NoError(t, err) + + if len(testTypes) == 0 { + t.Fatalf("No test types found for %s", testsFolderPath) + } + if testTypes[0] != "update_ranking" { + t.Fatalf("Expected test type 'update_ranking', got %s", testTypes[0]) + } + + _, testsFolderPath = utils.TestFolders(t, config, version.String(v), "light_client/update_ranking/pyspec_tests/update_ranking") + helpers.ClearCache() + t.Run("update ranking", func(t *testing.T) { + runLightClientUpdateRankingProofTest(t, testsFolderPath, v) + }) +} + +func runLightClientUpdateRankingProofTest(t *testing.T, testFolderPath string, v int) { + metaFile, err := util.BazelFileBytes(path.Join(testFolderPath, "meta.yaml")) + require.NoError(t, err) + var meta struct { + Count int `json:"updates_count"` + } + require.NoError(t, utils.UnmarshalYaml(metaFile, &meta)) + + for i := 0; i < meta.Count-1; i++ { + oldUpdateFile, err := util.BazelFileBytes(path.Join(testFolderPath, fmt.Sprintf("updates_%d.ssz_snappy", i))) + require.NoError(t, err) + oldUpdateSSZ, err := snappy.Decode(nil, oldUpdateFile) + require.NoError(t, err, "Failed to decompress") + oldUpdate := createUpdate(t, oldUpdateSSZ, v) + + newUpdateFile, err := util.BazelFileBytes(path.Join(testFolderPath, fmt.Sprintf("updates_%d.ssz_snappy", i+1))) + require.NoError(t, err) + newUpdateSSZ, err := snappy.Decode(nil, newUpdateFile) + require.NoError(t, err, "Failed to decompress") + newUpdate := createUpdate(t, newUpdateSSZ, v) + + result, err := lightclient.IsBetterUpdate(newUpdate, oldUpdate) + require.NoError(t, err) + require.Equal(t, false, result, "Update %d is not better than update %d", i, i+1) + } +} + +func createUpdate(t *testing.T, ssz []byte, v int) interfaces.LightClientUpdate { + switch v { + case version.Altair: + updateBase := ðpb.LightClientUpdateAltair{} + require.NoError(t, updateBase.UnmarshalSSZ(ssz), "Failed to unmarshal") + update, err := lightclienttypes.NewWrappedUpdateAltair(updateBase) + require.NoError(t, err) + return update + case version.Bellatrix: + updateBase := ðpb.LightClientUpdateAltair{} + require.NoError(t, updateBase.UnmarshalSSZ(ssz), "Failed to unmarshal") + update, err := lightclienttypes.NewWrappedUpdateAltair(updateBase) + require.NoError(t, err) + return update + case version.Capella: + updateBase := ðpb.LightClientUpdateCapella{} + require.NoError(t, updateBase.UnmarshalSSZ(ssz), "Failed to unmarshal") + update, err := lightclienttypes.NewWrappedUpdateCapella(updateBase) + require.NoError(t, err) + return update + case version.Deneb: + updateBase := ðpb.LightClientUpdateDeneb{} + require.NoError(t, updateBase.UnmarshalSSZ(ssz), "Failed to unmarshal") + update, err := lightclienttypes.NewWrappedUpdateDeneb(updateBase) + require.NoError(t, err) + return update + case version.Electra: + updateBase := ðpb.LightClientUpdateElectra{} + require.NoError(t, updateBase.UnmarshalSSZ(ssz), "Failed to unmarshal") + update, err := lightclienttypes.NewWrappedUpdateElectra(updateBase) + require.NoError(t, err) + return update + default: + t.Fatalf("Unsupported version %d", v) + return nil + } +}