mirror of
https://gitlab.com/pulsechaincom/prysm-pulse.git
synced 2024-12-22 03:30:35 +00:00
Eip4881: Tests (#11754)
This commit is contained in:
parent
cc764c346b
commit
8aec170f9b
15
WORKSPACE
15
WORKSPACE
@ -190,6 +190,21 @@ filegroup(
|
||||
url = "https://github.com/eth-clients/slashing-protection-interchange-tests/archive/b8413ca42dc92308019d0d4db52c87e9e125c4e9.tar.gz",
|
||||
)
|
||||
|
||||
http_archive(
|
||||
name = "eip4881_spec_tests",
|
||||
build_file_content = """
|
||||
filegroup(
|
||||
name = "test_data",
|
||||
srcs = glob([
|
||||
"**/*.yaml",
|
||||
]),
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
""",
|
||||
sha256 = "89cb659498c0d196fc9f957f8b849b2e1a5c041c3b2b3ae5432ac5c26944297e",
|
||||
url = "https://github.com/ethereum/EIPs/archive/5480440fe51742ed23342b68cf106cefd427e39d.tar.gz",
|
||||
)
|
||||
|
||||
consensus_spec_version = "v1.3.0-rc.3"
|
||||
|
||||
bls_test_version = "v0.1.1"
|
||||
|
24
beacon-chain/cache/depositsnapshot/BUILD.bazel
vendored
24
beacon-chain/cache/depositsnapshot/BUILD.bazel
vendored
@ -1,4 +1,4 @@
|
||||
load("@prysm//tools/go:def.bzl", "go_library")
|
||||
load("@prysm//tools/go:def.bzl", "go_library", "go_test")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
@ -19,3 +19,25 @@ go_library(
|
||||
"@com_github_pkg_errors//:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = [
|
||||
"deposit_tree_snapshot_test.go",
|
||||
"merkle_tree_test.go",
|
||||
"spec_test.go",
|
||||
],
|
||||
data = [
|
||||
"@eip4881_spec_tests//:test_data",
|
||||
],
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//io/file:go_default_library",
|
||||
"//proto/eth/v1:go_default_library",
|
||||
"//testing/assert:go_default_library",
|
||||
"//testing/require:go_default_library",
|
||||
"@com_github_pkg_errors//:go_default_library",
|
||||
"@in_gopkg_yaml_v3//:go_default_library",
|
||||
"@io_bazel_rules_go//go/tools/bazel:go_default_library",
|
||||
],
|
||||
)
|
||||
|
@ -23,8 +23,6 @@ var (
|
||||
ErrInvalidIndex = errors.New("index should be greater than finalizedDeposits - 1")
|
||||
// ErrNoDeposits occurs when the number of deposits is 0.
|
||||
ErrNoDeposits = errors.New("number of deposits should be greater than 0")
|
||||
// ErrNoFinalizedDeposits occurs when the number of finalized deposits is 0.
|
||||
ErrNoFinalizedDeposits = errors.New("number of finalized deposits should be greater than 0")
|
||||
// ErrTooManyDeposits occurs when the number of deposits exceeds the capacity of the tree.
|
||||
ErrTooManyDeposits = errors.New("number of deposits should not be greater than the capacity of the tree")
|
||||
)
|
||||
@ -62,7 +60,7 @@ func (d *DepositTree) getSnapshot() (DepositTreeSnapshot, error) {
|
||||
return DepositTreeSnapshot{}, ErrEmptyExecutionBlock
|
||||
}
|
||||
var finalized [][32]byte
|
||||
depositCount, _ := d.tree.GetFinalized(finalized)
|
||||
depositCount, finalized := d.tree.GetFinalized(finalized)
|
||||
return fromTreeParts(finalized, depositCount, d.finalizedExecutionBlock)
|
||||
}
|
||||
|
||||
@ -119,9 +117,6 @@ func (d *DepositTree) getProof(index uint64) ([32]byte, [][32]byte, error) {
|
||||
return [32]byte{}, nil, ErrInvalidMixInLength
|
||||
}
|
||||
finalizedDeposits, _ := d.tree.GetFinalized([][32]byte{})
|
||||
if finalizedDeposits == 0 {
|
||||
return [32]byte{}, nil, ErrNoFinalizedDeposits
|
||||
}
|
||||
if finalizedDeposits != 0 {
|
||||
finalizedDeposits = finalizedDeposits - 1
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ func (ds *DepositTreeSnapshot) CalculateRoot() ([32]byte, error) {
|
||||
}
|
||||
size >>= 1
|
||||
}
|
||||
return sha256.Sum256(append(root[:], bytesutil.Uint64ToBytesLittleEndian(ds.depositCount)...)), nil
|
||||
return sha256.Sum256(append(root[:], bytesutil.Uint64ToBytesLittleEndian32(ds.depositCount)...)), nil
|
||||
}
|
||||
|
||||
// fromTreeParts constructs the deposit tree from pre-existing data.
|
||||
|
54
beacon-chain/cache/depositsnapshot/deposit_tree_snapshot_test.go
vendored
Normal file
54
beacon-chain/cache/depositsnapshot/deposit_tree_snapshot_test.go
vendored
Normal file
@ -0,0 +1,54 @@
|
||||
package depositsnapshot
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/prysmaticlabs/prysm/v3/testing/require"
|
||||
)
|
||||
|
||||
func TestDepositTreeSnapshot_CalculateRoot(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
finalized int
|
||||
depositCount uint64
|
||||
want [32]byte
|
||||
}{
|
||||
{
|
||||
name: "empty",
|
||||
finalized: 0,
|
||||
depositCount: 0,
|
||||
want: [32]byte{215, 10, 35, 71, 49, 40, 92, 104, 4, 194, 164, 245, 103, 17, 221, 184, 200, 44, 153, 116, 15, 32, 120, 84, 137, 16, 40, 175, 52, 226, 126, 94},
|
||||
},
|
||||
{
|
||||
name: "1 Finalized",
|
||||
finalized: 1,
|
||||
depositCount: 2,
|
||||
want: [32]byte{36, 118, 154, 57, 217, 109, 145, 116, 238, 1, 207, 59, 187, 28, 69, 187, 70, 55, 153, 180, 15, 150, 37, 72, 140, 36, 109, 154, 212, 202, 47, 59},
|
||||
},
|
||||
{
|
||||
name: "many finalised",
|
||||
finalized: 6,
|
||||
depositCount: 20,
|
||||
want: [32]byte{210, 63, 57, 119, 12, 5, 3, 25, 139, 20, 244, 59, 114, 119, 35, 88, 222, 88, 122, 106, 239, 20, 45, 140, 99, 92, 222, 166, 133, 159, 128, 72},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
var finalized [][32]byte
|
||||
for i := 0; i < tt.finalized; i++ {
|
||||
finalized = append(finalized, hexString(t, fmt.Sprintf("%064d", i)))
|
||||
}
|
||||
ds := &DepositTreeSnapshot{
|
||||
finalized: finalized,
|
||||
depositCount: tt.depositCount,
|
||||
}
|
||||
root, err := ds.CalculateRoot()
|
||||
require.NoError(t, err)
|
||||
if got := root; !reflect.DeepEqual(got, tt.want) {
|
||||
require.DeepEqual(t, tt.want, got)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
141
beacon-chain/cache/depositsnapshot/merkle_tree_test.go
vendored
Normal file
141
beacon-chain/cache/depositsnapshot/merkle_tree_test.go
vendored
Normal file
@ -0,0 +1,141 @@
|
||||
package depositsnapshot
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/prysmaticlabs/prysm/v3/testing/assert"
|
||||
"github.com/prysmaticlabs/prysm/v3/testing/require"
|
||||
)
|
||||
|
||||
func hexString(t *testing.T, hexStr string) [32]byte {
|
||||
t.Helper()
|
||||
b, err := hex.DecodeString(hexStr)
|
||||
require.NoError(t, err)
|
||||
if len(b) != 32 {
|
||||
assert.Equal(t, 32, len(b), "bad hash length, expected 32")
|
||||
}
|
||||
x := (*[32]byte)(b)
|
||||
return *x
|
||||
}
|
||||
|
||||
func Test_create(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
leaves [][32]byte
|
||||
depth uint64
|
||||
want MerkleTreeNode
|
||||
}{
|
||||
{
|
||||
name: "empty tree",
|
||||
leaves: nil,
|
||||
depth: 0,
|
||||
want: &ZeroNode{},
|
||||
},
|
||||
{
|
||||
name: "zero depth",
|
||||
leaves: [][32]byte{hexString(t, fmt.Sprintf("%064d", 0))},
|
||||
depth: 0,
|
||||
want: &LeafNode{},
|
||||
},
|
||||
{
|
||||
name: "depth of 1",
|
||||
leaves: [][32]byte{hexString(t, fmt.Sprintf("%064d", 0))},
|
||||
depth: 1,
|
||||
want: &InnerNode{&LeafNode{}, &ZeroNode{}},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := create(tt.leaves, tt.depth); !reflect.DeepEqual(got, tt.want) {
|
||||
require.DeepEqual(t, tt.want, got)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_fromSnapshotParts(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
finalized [][32]byte
|
||||
deposits uint64
|
||||
level uint64
|
||||
want MerkleTreeNode
|
||||
}{
|
||||
{
|
||||
name: "empty",
|
||||
finalized: nil,
|
||||
deposits: 0,
|
||||
level: 0,
|
||||
want: &ZeroNode{},
|
||||
},
|
||||
{
|
||||
name: "single finalized node",
|
||||
finalized: [][32]byte{hexString(t, fmt.Sprintf("%064d", 0))},
|
||||
deposits: 1,
|
||||
level: 0,
|
||||
want: &FinalizedNode{
|
||||
depositCount: 1,
|
||||
hash: [32]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "multiple deposits and 1 Finalized",
|
||||
finalized: [][32]byte{hexString(t, fmt.Sprintf("%064d", 0))},
|
||||
deposits: 2,
|
||||
level: 4,
|
||||
want: &InnerNode{
|
||||
left: &InnerNode{&InnerNode{&FinalizedNode{depositCount: 2, hash: hexString(t, fmt.Sprintf("%064d", 0))}, &ZeroNode{1}}, &ZeroNode{2}},
|
||||
right: &ZeroNode{3},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
tree, err := fromSnapshotParts(tt.finalized, tt.deposits, tt.level)
|
||||
require.NoError(t, err)
|
||||
if got := tree; !reflect.DeepEqual(got, tt.want) {
|
||||
require.DeepEqual(t, tt.want, got)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_generateProof(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
leaves uint64
|
||||
}{
|
||||
{
|
||||
name: "1 leaf",
|
||||
leaves: 1,
|
||||
},
|
||||
{
|
||||
name: "4 leaves",
|
||||
leaves: 4,
|
||||
},
|
||||
{
|
||||
name: "10 leaves",
|
||||
leaves: 10,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
testCases, err := readTestCases()
|
||||
require.NoError(t, err)
|
||||
tree := New()
|
||||
for _, c := range testCases[:tt.leaves] {
|
||||
err = tree.pushLeaf(c.DepositDataRoot)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
for i := uint64(0); i < tt.leaves; i++ {
|
||||
leaf, proof := generateProof(tree.tree, i, DepositContractDepth)
|
||||
require.Equal(t, leaf, testCases[i].DepositDataRoot)
|
||||
calcRoot := merkleRootFromBranch(leaf, proof, i)
|
||||
require.Equal(t, tree.tree.GetRoot(), calcRoot)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
355
beacon-chain/cache/depositsnapshot/spec_test.go
vendored
Normal file
355
beacon-chain/cache/depositsnapshot/spec_test.go
vendored
Normal file
@ -0,0 +1,355 @@
|
||||
package depositsnapshot
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
"strconv"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/bazelbuild/rules_go/go/tools/bazel"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prysmaticlabs/prysm/v3/io/file"
|
||||
eth "github.com/prysmaticlabs/prysm/v3/proto/eth/v1"
|
||||
"github.com/prysmaticlabs/prysm/v3/testing/require"
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
type testCase struct {
|
||||
DepositData depositData `yaml:"deposit_data"`
|
||||
DepositDataRoot [32]byte `yaml:"deposit_data_root"`
|
||||
Eth1Data *eth1Data `yaml:"eth1_data"`
|
||||
BlockHeight uint64 `yaml:"block_height"`
|
||||
Snapshot snapshot `yaml:"snapshot"`
|
||||
}
|
||||
|
||||
func (tc *testCase) UnmarshalYAML(value *yaml.Node) error {
|
||||
raw := struct {
|
||||
DepositData depositData `yaml:"deposit_data"`
|
||||
DepositDataRoot string `yaml:"deposit_data_root"`
|
||||
Eth1Data *eth1Data `yaml:"eth1_data"`
|
||||
BlockHeight string `yaml:"block_height"`
|
||||
Snapshot snapshot `yaml:"snapshot"`
|
||||
}{}
|
||||
err := value.Decode(&raw)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
tc.DepositDataRoot, err = hexStringToByteArray(raw.DepositDataRoot)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
tc.DepositData = raw.DepositData
|
||||
tc.Eth1Data = raw.Eth1Data
|
||||
tc.BlockHeight, err = stringToUint64(raw.BlockHeight)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
tc.Snapshot = raw.Snapshot
|
||||
return nil
|
||||
}
|
||||
|
||||
type depositData struct {
|
||||
Pubkey []byte `yaml:"pubkey"`
|
||||
WithdrawalCredentials []byte `yaml:"withdrawal_credentials"`
|
||||
Amount uint64 `yaml:"amount"`
|
||||
Signature []byte `yaml:"signature"`
|
||||
}
|
||||
|
||||
func (dd *depositData) UnmarshalYAML(value *yaml.Node) error {
|
||||
raw := struct {
|
||||
Pubkey string `yaml:"pubkey"`
|
||||
WithdrawalCredentials string `yaml:"withdrawal_credentials"`
|
||||
Amount string `yaml:"amount"`
|
||||
Signature string `yaml:"signature"`
|
||||
}{}
|
||||
err := value.Decode(&raw)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
dd.Pubkey, err = hexStringToBytes(raw.Pubkey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
dd.WithdrawalCredentials, err = hexStringToBytes(raw.WithdrawalCredentials)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
dd.Amount, err = strconv.ParseUint(raw.Amount, 10, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
dd.Signature, err = hexStringToBytes(raw.Signature)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type eth1Data struct {
|
||||
DepositRoot [32]byte `yaml:"deposit_root"`
|
||||
DepositCount uint64 `yaml:"deposit_count"`
|
||||
BlockHash [32]byte `yaml:"block_hash"`
|
||||
}
|
||||
|
||||
func (ed *eth1Data) UnmarshalYAML(value *yaml.Node) error {
|
||||
raw := struct {
|
||||
DepositRoot string `yaml:"deposit_root"`
|
||||
DepositCount string `yaml:"deposit_count"`
|
||||
BlockHash string `yaml:"block_hash"`
|
||||
}{}
|
||||
err := value.Decode(&raw)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ed.DepositRoot, err = hexStringToByteArray(raw.DepositRoot)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ed.DepositCount, err = stringToUint64(raw.DepositCount)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ed.BlockHash, err = hexStringToByteArray(raw.BlockHash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type snapshot struct {
|
||||
DepositTreeSnapshot
|
||||
}
|
||||
|
||||
func (sd *snapshot) UnmarshalYAML(value *yaml.Node) error {
|
||||
raw := struct {
|
||||
Finalized []string `yaml:"finalized"`
|
||||
DepositRoot string `yaml:"deposit_root"`
|
||||
DepositCount string `yaml:"deposit_count"`
|
||||
ExecutionBlockHash string `yaml:"execution_block_hash"`
|
||||
ExecutionBlockHeight string `yaml:"execution_block_height"`
|
||||
}{}
|
||||
err := value.Decode(&raw)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
sd.finalized = make([][32]byte, len(raw.Finalized))
|
||||
for i, finalized := range raw.Finalized {
|
||||
sd.finalized[i], err = hexStringToByteArray(finalized)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
sd.depositRoot, err = hexStringToByteArray(raw.DepositRoot)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
sd.depositCount, err = stringToUint64(raw.DepositCount)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
sd.executionBlock.Hash, err = hexStringToByteArray(raw.ExecutionBlockHash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
sd.executionBlock.Depth, err = stringToUint64(raw.ExecutionBlockHeight)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func readTestCases() ([]testCase, error) {
|
||||
testFolders, err := bazel.ListRunfiles()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, ff := range testFolders {
|
||||
if strings.Contains(ff.ShortPath, "eip4881_spec_tests") &&
|
||||
strings.Contains(ff.ShortPath, "eip-4881/test_cases.yaml") {
|
||||
enc, err := file.ReadFileAsBytes(ff.Path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var testCases []testCase
|
||||
err = yaml.Unmarshal(enc, &testCases)
|
||||
if err != nil {
|
||||
return []testCase{}, err
|
||||
}
|
||||
return testCases, nil
|
||||
}
|
||||
}
|
||||
return nil, errors.New("spec test file not found")
|
||||
}
|
||||
|
||||
func TestRead(t *testing.T) {
|
||||
tcs, err := readTestCases()
|
||||
require.NoError(t, err)
|
||||
for _, tc := range tcs {
|
||||
t.Log(tc)
|
||||
}
|
||||
}
|
||||
|
||||
func hexStringToByteArray(s string) (b [32]byte, err error) {
|
||||
var raw []byte
|
||||
raw, err = hexStringToBytes(s)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if len(raw) != 32 {
|
||||
err = errors.New("invalid hex string length")
|
||||
return
|
||||
}
|
||||
copy(b[:], raw[:32])
|
||||
return
|
||||
}
|
||||
|
||||
func hexStringToBytes(s string) (b []byte, err error) {
|
||||
b, err = hex.DecodeString(strings.TrimPrefix(s, "0x"))
|
||||
return
|
||||
}
|
||||
|
||||
func stringToUint64(s string) (uint64, error) {
|
||||
value, err := strconv.ParseUint(s, 10, 32)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return value, nil
|
||||
}
|
||||
|
||||
func merkleRootFromBranch(leaf [32]byte, branch [][32]byte, index uint64) [32]byte {
|
||||
root := leaf
|
||||
for i, l := range branch {
|
||||
ithBit := (index >> i) & 0x1
|
||||
if ithBit == 1 {
|
||||
root = sha256.Sum256(append(l[:], root[:]...))
|
||||
} else {
|
||||
root = sha256.Sum256(append(root[:], l[:]...))
|
||||
}
|
||||
}
|
||||
return root
|
||||
}
|
||||
|
||||
func checkProof(t *testing.T, tree *DepositTree, index uint64) {
|
||||
leaf, proof, err := tree.getProof(index)
|
||||
require.NoError(t, err)
|
||||
calcRoot := merkleRootFromBranch(leaf, proof, index)
|
||||
require.Equal(t, tree.getRoot(), calcRoot)
|
||||
}
|
||||
|
||||
func compareProof(t *testing.T, tree1, tree2 *DepositTree, index uint64) {
|
||||
require.Equal(t, tree1.getRoot(), tree2.getRoot())
|
||||
checkProof(t, tree1, index)
|
||||
checkProof(t, tree2, index)
|
||||
}
|
||||
|
||||
func cloneFromSnapshot(t *testing.T, snapshot DepositTreeSnapshot, testCases []testCase) *DepositTree {
|
||||
cp, err := fromSnapshot(snapshot)
|
||||
require.NoError(t, err)
|
||||
for _, c := range testCases {
|
||||
err = cp.pushLeaf(c.DepositDataRoot)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
return &cp
|
||||
}
|
||||
|
||||
func TestDepositCases(t *testing.T) {
|
||||
tree := New()
|
||||
testCases, err := readTestCases()
|
||||
require.NoError(t, err)
|
||||
for _, c := range testCases {
|
||||
err = tree.pushLeaf(c.DepositDataRoot)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFinalization(t *testing.T) {
|
||||
tree := New()
|
||||
testCases, err := readTestCases()
|
||||
require.NoError(t, err)
|
||||
for _, c := range testCases[:128] {
|
||||
err = tree.pushLeaf(c.DepositDataRoot)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
originalRoot := tree.getRoot()
|
||||
require.DeepEqual(t, testCases[127].Eth1Data.DepositRoot, originalRoot)
|
||||
err = tree.finalize(ð.Eth1Data{
|
||||
DepositRoot: testCases[100].Eth1Data.DepositRoot[:],
|
||||
DepositCount: testCases[100].Eth1Data.DepositCount,
|
||||
BlockHash: testCases[100].Eth1Data.BlockHash[:],
|
||||
}, testCases[100].BlockHeight)
|
||||
require.NoError(t, err)
|
||||
// ensure finalization doesn't change root
|
||||
require.Equal(t, tree.getRoot(), originalRoot)
|
||||
snapshotData, err := tree.getSnapshot()
|
||||
require.NoError(t, err)
|
||||
require.DeepEqual(t, testCases[100].Snapshot.DepositTreeSnapshot, snapshotData)
|
||||
// create a copy of the tree from a snapshot by replaying
|
||||
// the deposits after the finalized deposit
|
||||
cp := cloneFromSnapshot(t, snapshotData, testCases[101:128])
|
||||
// ensure original and copy have the same root
|
||||
require.Equal(t, tree.getRoot(), cp.getRoot())
|
||||
// finalize original again to check double finalization
|
||||
err = tree.finalize(ð.Eth1Data{
|
||||
DepositRoot: testCases[105].Eth1Data.DepositRoot[:],
|
||||
DepositCount: testCases[105].Eth1Data.DepositCount,
|
||||
BlockHash: testCases[105].Eth1Data.BlockHash[:],
|
||||
}, testCases[105].BlockHeight)
|
||||
require.NoError(t, err)
|
||||
// root should still be the same
|
||||
require.Equal(t, originalRoot, tree.getRoot())
|
||||
// create a copy of the tree by taking a snapshot again
|
||||
snapshotData, err = tree.getSnapshot()
|
||||
require.NoError(t, err)
|
||||
cp = cloneFromSnapshot(t, snapshotData, testCases[106:128])
|
||||
// create a copy of the tree by replaying ALL deposits from nothing
|
||||
fullTreeCopy := New()
|
||||
for _, c := range testCases[:128] {
|
||||
err = fullTreeCopy.pushLeaf(c.DepositDataRoot)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
for i := 106; i < 128; i++ {
|
||||
compareProof(t, tree, cp, uint64(i))
|
||||
compareProof(t, tree, fullTreeCopy, uint64(i))
|
||||
}
|
||||
}
|
||||
|
||||
func TestSnapshotCases(t *testing.T) {
|
||||
tree := New()
|
||||
testCases, err := readTestCases()
|
||||
require.NoError(t, err)
|
||||
for _, c := range testCases {
|
||||
err = tree.pushLeaf(c.DepositDataRoot)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
for _, c := range testCases {
|
||||
err = tree.finalize(ð.Eth1Data{
|
||||
DepositRoot: c.Eth1Data.DepositRoot[:],
|
||||
DepositCount: c.Eth1Data.DepositCount,
|
||||
BlockHash: c.Eth1Data.BlockHash[:],
|
||||
}, c.BlockHeight)
|
||||
require.NoError(t, err)
|
||||
s, err := tree.getSnapshot()
|
||||
require.NoError(t, err)
|
||||
require.DeepEqual(t, c.Snapshot.DepositTreeSnapshot, s)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEmptyTreeSnapshot(t *testing.T) {
|
||||
_, err := New().getSnapshot()
|
||||
require.ErrorContains(t, "empty execution block", err)
|
||||
}
|
||||
|
||||
func TestInvalidSnapshot(t *testing.T) {
|
||||
invalidSnapshot := DepositTreeSnapshot{
|
||||
finalized: nil,
|
||||
depositRoot: Zerohashes[0],
|
||||
depositCount: 0,
|
||||
executionBlock: executionBlock{
|
||||
Hash: Zerohashes[0],
|
||||
Depth: 0,
|
||||
},
|
||||
}
|
||||
_, err := fromSnapshot(invalidSnapshot)
|
||||
require.ErrorContains(t, "snapshot root is invalid", err)
|
||||
}
|
2
go.mod
2
go.mod
@ -91,6 +91,7 @@ require (
|
||||
google.golang.org/protobuf v1.28.1
|
||||
gopkg.in/d4l3k/messagediff.v1 v1.2.1
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
k8s.io/client-go v0.18.3
|
||||
)
|
||||
|
||||
@ -230,7 +231,6 @@ require (
|
||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce // indirect
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
k8s.io/apimachinery v0.18.3 // indirect
|
||||
k8s.io/klog v1.0.0 // indirect
|
||||
lukechampine.com/blake3 v1.1.7 // indirect
|
||||
|
Loading…
Reference in New Issue
Block a user