mirror of
https://gitlab.com/pulsechaincom/prysm-pulse.git
synced 2025-01-03 00:27:38 +00:00
Implement Merkle proof spectests (#13146)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
This commit is contained in:
parent
8a743a6430
commit
daa6d2e741
@ -11,7 +11,6 @@ go_library(
|
|||||||
deps = [
|
deps = [
|
||||||
"//crypto/hash:go_default_library",
|
"//crypto/hash:go_default_library",
|
||||||
"//encoding/bytesutil:go_default_library",
|
"//encoding/bytesutil:go_default_library",
|
||||||
"//math:go_default_library",
|
|
||||||
"//proto/prysm/v1alpha1:go_default_library",
|
"//proto/prysm/v1alpha1:go_default_library",
|
||||||
"@com_github_pkg_errors//:go_default_library",
|
"@com_github_pkg_errors//:go_default_library",
|
||||||
],
|
],
|
||||||
|
@ -9,7 +9,6 @@ import (
|
|||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/prysmaticlabs/prysm/v4/crypto/hash"
|
"github.com/prysmaticlabs/prysm/v4/crypto/hash"
|
||||||
"github.com/prysmaticlabs/prysm/v4/encoding/bytesutil"
|
"github.com/prysmaticlabs/prysm/v4/encoding/bytesutil"
|
||||||
"github.com/prysmaticlabs/prysm/v4/math"
|
|
||||||
protodb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
|
protodb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -214,18 +213,15 @@ func VerifyMerkleProofWithDepth(root, item []byte, merkleIndex uint64, proof [][
|
|||||||
if uint64(len(proof)) != depth+1 {
|
if uint64(len(proof)) != depth+1 {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if depth >= 64 {
|
|
||||||
return false // PowerOf2 would overflow.
|
|
||||||
}
|
|
||||||
node := bytesutil.ToBytes32(item)
|
node := bytesutil.ToBytes32(item)
|
||||||
for i := uint64(0); i <= depth; i++ {
|
for i := uint64(0); i <= depth; i++ {
|
||||||
if (merkleIndex / math.PowerOf2(i) % 2) != 0 {
|
if (merkleIndex & 1) == 1 {
|
||||||
node = hash.Hash(append(proof[i], node[:]...))
|
node = hash.Hash(append(proof[i], node[:]...))
|
||||||
} else {
|
} else {
|
||||||
node = hash.Hash(append(node[:], proof[i]...))
|
node = hash.Hash(append(node[:], proof[i]...))
|
||||||
}
|
}
|
||||||
|
merkleIndex /= 2
|
||||||
}
|
}
|
||||||
|
|
||||||
return bytes.Equal(root, node[:])
|
return bytes.Equal(root, node[:])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
11
testing/spectest/mainnet/deneb/merkle_proof/BUILD.bazel
Normal file
11
testing/spectest/mainnet/deneb/merkle_proof/BUILD.bazel
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
load("@prysm//tools/go:def.bzl", "go_test")
|
||||||
|
|
||||||
|
go_test(
|
||||||
|
name = "go_default_test",
|
||||||
|
srcs = ["merkle_proof_test.go"],
|
||||||
|
data = glob(["*.yaml"]) + [
|
||||||
|
"@consensus_spec_tests_mainnet//:test_data",
|
||||||
|
],
|
||||||
|
tags = ["spectest"],
|
||||||
|
deps = ["//testing/spectest/shared/deneb/merkle_proof:go_default_library"],
|
||||||
|
)
|
@ -0,0 +1,11 @@
|
|||||||
|
package merkle_proof
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/prysmaticlabs/prysm/v4/testing/spectest/shared/deneb/merkle_proof"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestMainnet_Deneb_MerkleProof(t *testing.T) {
|
||||||
|
merkle_proof.RunMerkleProofTests(t, "mainnet")
|
||||||
|
}
|
16
testing/spectest/minimal/deneb/merkle_proof/BUILD.bazel
Normal file
16
testing/spectest/minimal/deneb/merkle_proof/BUILD.bazel
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
load("@prysm//tools/go:def.bzl", "go_test")
|
||||||
|
|
||||||
|
go_test(
|
||||||
|
name = "go_default_test",
|
||||||
|
size = "small",
|
||||||
|
srcs = ["merkle_proof_test.go"],
|
||||||
|
data = glob(["*.yaml"]) + [
|
||||||
|
"@consensus_spec_tests_minimal//:test_data",
|
||||||
|
],
|
||||||
|
eth_network = "minimal",
|
||||||
|
tags = [
|
||||||
|
"minimal",
|
||||||
|
"spectest",
|
||||||
|
],
|
||||||
|
deps = ["//testing/spectest/shared/deneb/merkle_proof:go_default_library"],
|
||||||
|
)
|
@ -0,0 +1,11 @@
|
|||||||
|
package merkle_proof
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/prysmaticlabs/prysm/v4/testing/spectest/shared/deneb/merkle_proof"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestMainnet_Deneb_MerkleProof(t *testing.T) {
|
||||||
|
merkle_proof.RunMerkleProofTests(t, "minimal")
|
||||||
|
}
|
19
testing/spectest/shared/common/merkle_proof/BUILD.bazel
Normal file
19
testing/spectest/shared/common/merkle_proof/BUILD.bazel
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
load("@prysm//tools/go:def.bzl", "go_library")
|
||||||
|
|
||||||
|
go_library(
|
||||||
|
name = "go_default_library",
|
||||||
|
testonly = True,
|
||||||
|
srcs = ["single_merkle_proof.go"],
|
||||||
|
importpath = "github.com/prysmaticlabs/prysm/v4/testing/spectest/shared/common/merkle_proof",
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
deps = [
|
||||||
|
"//container/trie:go_default_library",
|
||||||
|
"//testing/require:go_default_library",
|
||||||
|
"//testing/spectest/shared/common/ssz_static:go_default_library",
|
||||||
|
"//testing/spectest/utils:go_default_library",
|
||||||
|
"//testing/util:go_default_library",
|
||||||
|
"@com_github_golang_snappy//:go_default_library",
|
||||||
|
"@com_github_prysmaticlabs_fastssz//:go_default_library",
|
||||||
|
"@io_bazel_rules_go//go/tools/bazel:go_default_library",
|
||||||
|
],
|
||||||
|
)
|
@ -0,0 +1,80 @@
|
|||||||
|
package merkle_proof
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/hex"
|
||||||
|
"os"
|
||||||
|
"path"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/bazelbuild/rules_go/go/tools/bazel"
|
||||||
|
"github.com/golang/snappy"
|
||||||
|
fssz "github.com/prysmaticlabs/fastssz"
|
||||||
|
"github.com/prysmaticlabs/prysm/v4/container/trie"
|
||||||
|
"github.com/prysmaticlabs/prysm/v4/testing/require"
|
||||||
|
"github.com/prysmaticlabs/prysm/v4/testing/spectest/shared/common/ssz_static"
|
||||||
|
"github.com/prysmaticlabs/prysm/v4/testing/spectest/utils"
|
||||||
|
"github.com/prysmaticlabs/prysm/v4/testing/util"
|
||||||
|
)
|
||||||
|
|
||||||
|
// SingleMerkleProof is the format used to read spectest Merkle Proof test data.
|
||||||
|
type SingleMerkleProof struct {
|
||||||
|
Leaf string `json:"leaf"`
|
||||||
|
LeafIndex uint64 `json:"leaf_index"`
|
||||||
|
Branch []string `json:"branch"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func RunMerkleProofTests(t *testing.T, config, forkOrPhase string, unmarshaller ssz_static.Unmarshaller) {
|
||||||
|
t.Skip("testvectors are not available yet")
|
||||||
|
runSingleMerkleProofTests(t, config, forkOrPhase, unmarshaller)
|
||||||
|
}
|
||||||
|
|
||||||
|
func runSingleMerkleProofTests(t *testing.T, config, forkOrPhase string, unmarshaller ssz_static.Unmarshaller) {
|
||||||
|
require.NoError(t, utils.SetConfig(t, config))
|
||||||
|
|
||||||
|
testFolders, basePath := utils.TestFolders(t, config, forkOrPhase, "merkle_proof/single_merkle_proof")
|
||||||
|
|
||||||
|
if len(testFolders) == 0 {
|
||||||
|
t.Fatalf("No test folders found for %s/%s/merkle_proof", config, forkOrPhase)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, folder := range testFolders {
|
||||||
|
typeFolderBase := path.Join(basePath, folder.Name())
|
||||||
|
typeFolder, err := bazel.Runfile(typeFolderBase)
|
||||||
|
require.NoError(t, err)
|
||||||
|
modeFolders, err := os.ReadDir(typeFolder)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
if len(modeFolders) == 0 {
|
||||||
|
t.Fatalf("No test folders found for %s", typeFolder)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, modeFolder := range modeFolders {
|
||||||
|
t.Run(path.Join(folder.Name(), modeFolder.Name()), func(t *testing.T) {
|
||||||
|
serializedBytes, err := util.BazelFileBytes(typeFolder, modeFolder.Name(), "object.ssz_snappy")
|
||||||
|
require.NoError(t, err)
|
||||||
|
serializedSSZ, err := snappy.Decode(nil /* dst */, serializedBytes)
|
||||||
|
require.NoError(t, err, "Failed to decompress")
|
||||||
|
object, err := unmarshaller(t, serializedSSZ, folder.Name())
|
||||||
|
require.NoError(t, err, "Could not unmarshall serialized SSZ")
|
||||||
|
sszObj, ok := object.(fssz.HashRoot)
|
||||||
|
require.Equal(t, true, ok)
|
||||||
|
root, err := sszObj.HashTreeRoot()
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
proofYamlFile, err := util.BazelFileBytes(typeFolder, modeFolder.Name(), "proof.yaml")
|
||||||
|
require.NoError(t, err)
|
||||||
|
proof := &SingleMerkleProof{}
|
||||||
|
require.NoError(t, utils.UnmarshalYaml(proofYamlFile, proof), "Failed to Unmarshal single Merkle proof")
|
||||||
|
branch := make([][]byte, len(proof.Branch))
|
||||||
|
for i, proofRoot := range proof.Branch {
|
||||||
|
branch[i], err = hex.DecodeString(proofRoot[2:])
|
||||||
|
require.NoError(t, err)
|
||||||
|
}
|
||||||
|
leaf, err := hex.DecodeString(proof.Leaf[2:])
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
require.Equal(t, true, trie.VerifyMerkleProof(root[:], leaf, proof.LeafIndex, branch))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
13
testing/spectest/shared/deneb/merkle_proof/BUILD.bazel
Normal file
13
testing/spectest/shared/deneb/merkle_proof/BUILD.bazel
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
load("@prysm//tools/go:def.bzl", "go_library")
|
||||||
|
|
||||||
|
go_library(
|
||||||
|
name = "go_default_library",
|
||||||
|
testonly = True,
|
||||||
|
srcs = ["merkle_proof.go"],
|
||||||
|
importpath = "github.com/prysmaticlabs/prysm/v4/testing/spectest/shared/deneb/merkle_proof",
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
deps = [
|
||||||
|
"//testing/spectest/shared/common/merkle_proof:go_default_library",
|
||||||
|
"//testing/spectest/shared/deneb/ssz_static:go_default_library",
|
||||||
|
],
|
||||||
|
)
|
12
testing/spectest/shared/deneb/merkle_proof/merkle_proof.go
Normal file
12
testing/spectest/shared/deneb/merkle_proof/merkle_proof.go
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
package merkle_proof
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
common "github.com/prysmaticlabs/prysm/v4/testing/spectest/shared/common/merkle_proof"
|
||||||
|
"github.com/prysmaticlabs/prysm/v4/testing/spectest/shared/deneb/ssz_static"
|
||||||
|
)
|
||||||
|
|
||||||
|
func RunMerkleProofTests(t *testing.T, config string) {
|
||||||
|
common.RunMerkleProofTests(t, config, "deneb", ssz_static.UnmarshalledSSZ)
|
||||||
|
}
|
@ -15,7 +15,7 @@ import (
|
|||||||
|
|
||||||
// RunSSZStaticTests executes "ssz_static" tests.
|
// RunSSZStaticTests executes "ssz_static" tests.
|
||||||
func RunSSZStaticTests(t *testing.T, config string) {
|
func RunSSZStaticTests(t *testing.T, config string) {
|
||||||
common.RunSSZStaticTests(t, config, "deneb", unmarshalledSSZ, customHtr)
|
common.RunSSZStaticTests(t, config, "deneb", UnmarshalledSSZ, customHtr)
|
||||||
}
|
}
|
||||||
|
|
||||||
func customHtr(t *testing.T, htrs []common.HTR, object interface{}) []common.HTR {
|
func customHtr(t *testing.T, htrs []common.HTR, object interface{}) []common.HTR {
|
||||||
@ -32,8 +32,8 @@ func customHtr(t *testing.T, htrs []common.HTR, object interface{}) []common.HTR
|
|||||||
return htrs
|
return htrs
|
||||||
}
|
}
|
||||||
|
|
||||||
// unmarshalledSSZ unmarshalls serialized input.
|
// UnmarshalledSSZ unmarshalls serialized input.
|
||||||
func unmarshalledSSZ(t *testing.T, serializedBytes []byte, folderName string) (interface{}, error) {
|
func UnmarshalledSSZ(t *testing.T, serializedBytes []byte, folderName string) (interface{}, error) {
|
||||||
var obj interface{}
|
var obj interface{}
|
||||||
switch folderName {
|
switch folderName {
|
||||||
case "ExecutionPayload":
|
case "ExecutionPayload":
|
||||||
|
Loading…
Reference in New Issue
Block a user