prysm-pulse/beacon-chain/cache/depositsnapshot/merkle_tree_test.go
Sammy Rosso d55757500f
Integrate EIP-4881 Deposit Tree Into Prysm via a Feature Flag (#11942)
* Initial spec rewrite

* Finish adding merkle tree implementation

* Last bits

* Move reverse function

* Add comments

* Add deposit tree snapshot

* Add deposit tree

* Add comments + cleanup

* Fixes

* Add missing errors

* Small fixes

* Add unhandled error

* Cleanup

* Fix unsafe file.Close

* Add missing comments

* Small fixes

* Address some of deepSource' compaints

* Add depositCount check

* Add finalizedDeposit check

* Replace pointer magic with copy()

* Add test for slice reversal

* add back bytes method

* Add package level description

* Remove zerohash gen and add additional checks

* Add additional comments

* Small lint fixes

* Forgot an error

* Small fixes

* Move Uint64ToBytesLittleEndian32 + test

* Fix uint subtraction issue

* Move mixInLength below error handling

* Fix

* Fix deposit root

* integrate 4881

* edits

* added in deposit tree fetcher

* add file

* Add remaining fetcher functions

* Add new file for inserter functions

* Fixes and additional funcs

* Cleanup

* Add

* Graph

* pushed up edits

* fix up

* Updates

* Add EIP4881 toggle flag

* Add interfaces

* Fix tests

* More changes

* Fix

* Remove generated graph

* Fix spacing

* Changes

* Fixes

* Changes

* Test Fix

* gaz

* Fix a couple tests

* Fix last tests

* define protos

* proto methods

* pushed

* regen

* Add proto funcs

* builds

* pushin up

* Fix and cleanup

* Fix spectest

* General cleanup

* add 4881 to e2e

* Remove debug statements + remove test skip

* Implement first set of  missing methods

* Replace Zerohashes + cleanup

* gazelle

* fmt

* Put back defensive check

* Add error logs

* InsertFinalizedDeposits: return an error

* Remove logging

* Radek' Review

* Lint fixes

* build

* Remove cancel

* Update beacon-chain/deterministic-genesis/service.go

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>

* Update beacon-chain/cache/depositsnapshot/deposit_inserter.go

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>

* Cleanup

* Fix panic when DepositSnapshot is nil on init

* Gofmt

* Fix RootEquivalence test

* Gofmt

* Add missing comments

* Nishant' review

* Add Insert benchmarks

* fix up copy method

* Fix deep copy

* Fix conflicts

* Return error

* Fix linter issues

* add in migration logic

* Cleanup + tests

* fix

* Fix incorrect index in test

* Fix linter

* Gofmt

* fix it

* fixes for off by 1

* gaz

* fix cast

* fix it

* remove ErrZeroIndex

* Fix merkle_tree_test

* add fallback

* add fix for insertion bug

* add many fixes

* fix empty snapshot

* clean up

* use feature

* remove check

* fix failing tests

* skip it

* fix test

* fix test again

* fix for the last time

* Apply suggestions from code review

Co-authored-by: Radosław Kapka <rkapka@wp.pl>

* fix it

* remove cancel

* fix for voting

* addressing more comments

* fix err

* potuz's review

* one more test

* fix bad test

* make 4881 part of dev mode

* add workaround for new trie

* comment

* preston's review

* james's review

* add comment

* james review

* preston's review

* remove skipped test

* gaz

---------

Co-authored-by: rauljordan <raul@prysmaticlabs.com>
Co-authored-by: nisdas <nishdas93@gmail.com>
Co-authored-by: Radosław Kapka <rkapka@wp.pl>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2023-09-07 03:19:32 +00:00

153 lines
3.5 KiB
Go

package depositsnapshot
import (
"encoding/hex"
"fmt"
"reflect"
"testing"
"github.com/prysmaticlabs/prysm/v4/container/trie"
"github.com/prysmaticlabs/prysm/v4/encoding/bytesutil"
"github.com/prysmaticlabs/prysm/v4/testing/assert"
"github.com/prysmaticlabs/prysm/v4/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
}{
{
name: "multiple deposits and multiple Finalized",
finalized: [][32]byte{hexString(t, fmt.Sprintf("%064d", 1)), hexString(t, fmt.Sprintf("%064d", 2))},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
test := NewDepositTree()
for _, leaf := range tt.finalized {
err := test.pushLeaf(leaf)
require.NoError(t, err)
}
got, err := test.HashTreeRoot()
require.NoError(t, err)
transformed := make([][]byte, len(tt.finalized))
for i := 0; i < len(tt.finalized); i++ {
transformed[i] = bytesutil.SafeCopyBytes(tt.finalized[i][:])
}
generatedTrie, err := trie.GenerateTrieFromItems(transformed, 32)
require.NoError(t, err)
want, err := generatedTrie.HashTreeRoot()
require.NoError(t, err)
require.Equal(t, want, got)
// Test finalization
for i := 0; i < len(tt.finalized); i++ {
err = test.Finalize(int64(i), tt.finalized[i], 0)
require.NoError(t, err)
}
sShot, err := test.GetSnapshot()
require.NoError(t, err)
got, err = sShot.CalculateRoot()
require.NoError(t, err)
require.Equal(t, 1, len(sShot.finalized))
require.Equal(t, want, got)
// Build from the snapshot once more
recovered, err := fromSnapshot(sShot)
require.NoError(t, err)
got, err = recovered.HashTreeRoot()
require.NoError(t, err)
require.Equal(t, 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 := NewDepositTree()
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)
}
})
}
}