fuzz: Add fuzz tests for sparse merkle trie (#10662)

* Add fuzz tests for sparse merkle trie and change HTR signature to return an error

* fix capitalization of error message
This commit is contained in:
Preston Van Loon
2022-05-09 11:51:48 -05:00
committed by GitHub
parent 7d9d8454b1
commit 97663548a1
24 changed files with 418 additions and 90 deletions

View File

@@ -221,7 +221,8 @@ func TestChainService_InitializeBeaconChain(t *testing.T) {
require.NoError(t, err)
trie, _, err := util.DepositTrieFromDeposits(deposits)
require.NoError(t, err)
hashTreeRoot := trie.HashTreeRoot()
hashTreeRoot, err := trie.HashTreeRoot()
require.NoError(t, err)
genState, err := transition.EmptyGenesisState()
require.NoError(t, err)
err = genState.SetEth1Data(&ethpb.Eth1Data{

View File

@@ -430,7 +430,11 @@ func TestFinalizedDeposits_DepositsCachedCorrectly(t *testing.T) {
}
trie, err := trie.GenerateTrieFromItems(deps, params.BeaconConfig().DepositContractTreeDepth)
require.NoError(t, err, "Could not generate deposit trie")
assert.Equal(t, trie.HashTreeRoot(), cachedDeposits.Deposits.HashTreeRoot())
rootA, err := trie.HashTreeRoot()
require.NoError(t, err)
rootB, err := cachedDeposits.Deposits.HashTreeRoot()
require.NoError(t, err)
assert.Equal(t, rootA, rootB)
}
func TestFinalizedDeposits_UtilizesPreviouslyCachedDeposits(t *testing.T) {
@@ -488,7 +492,11 @@ func TestFinalizedDeposits_UtilizesPreviouslyCachedDeposits(t *testing.T) {
}
trie, err := trie.GenerateTrieFromItems(deps, params.BeaconConfig().DepositContractTreeDepth)
require.NoError(t, err, "Could not generate deposit trie")
assert.Equal(t, trie.HashTreeRoot(), cachedDeposits.Deposits.HashTreeRoot())
rootA, err := trie.HashTreeRoot()
require.NoError(t, err)
rootB, err := cachedDeposits.Deposits.HashTreeRoot()
require.NoError(t, err)
assert.Equal(t, rootA, rootB)
}
func TestFinalizedDeposits_HandleZeroDeposits(t *testing.T) {

View File

@@ -143,7 +143,8 @@ func TestProcessDeposits_RepeatedDeposit_IncreasesValidatorBalance(t *testing.T)
},
}
balances := []uint64{0, 50}
root := depositTrie.HashTreeRoot()
root, err := depositTrie.HashTreeRoot()
require.NoError(t, err)
beaconState, err := stateAltair.InitializeFromProto(&ethpb.BeaconStateAltair{
Validators: registry,
Balances: balances,
@@ -202,7 +203,8 @@ func TestProcessDeposit_SkipsInvalidDeposit(t *testing.T) {
dep[0].Data.Signature = make([]byte, 96)
trie, _, err := util.DepositTrieFromDeposits(dep)
require.NoError(t, err)
root := trie.HashTreeRoot()
root, err := trie.HashTreeRoot()
require.NoError(t, err)
eth1Data := &ethpb.Eth1Data{
DepositRoot: root[:],
DepositCount: 1,

View File

@@ -173,7 +173,8 @@ func TestProcessDeposits_RepeatedDeposit_IncreasesValidatorBalance(t *testing.T)
},
}
balances := []uint64{0, 50}
root := depositTrie.HashTreeRoot()
root, err := depositTrie.HashTreeRoot()
require.NoError(t, err)
beaconState, err := v1.InitializeFromProto(&ethpb.BeaconState{
Validators: registry,
Balances: balances,
@@ -233,7 +234,8 @@ func TestProcessDeposit_SkipsInvalidDeposit(t *testing.T) {
dep[0].Data.Signature = make([]byte, 96)
trie, _, err := util.DepositTrieFromDeposits(dep)
require.NoError(t, err)
root := trie.HashTreeRoot()
root, err := trie.HashTreeRoot()
require.NoError(t, err)
eth1Data := &ethpb.Eth1Data{
DepositRoot: root[:],
DepositCount: 1,
@@ -289,7 +291,9 @@ func TestPreGenesisDeposits_SkipInvalidDeposit(t *testing.T) {
require.NoError(t, err)
dep[i].Proof = proof
}
root := trie.HashTreeRoot()
root, err := trie.HashTreeRoot()
require.NoError(t, err)
eth1Data := &ethpb.Eth1Data{
DepositRoot: root[:],
DepositCount: 1,
@@ -376,7 +380,9 @@ func TestProcessDeposit_RepeatedDeposit_IncreasesValidatorBalance(t *testing.T)
},
}
balances := []uint64{0, 50}
root := depositTrie.HashTreeRoot()
root, err := depositTrie.HashTreeRoot()
require.NoError(t, err)
beaconState, err := v1.InitializeFromProto(&ethpb.BeaconState{
Validators: registry,
Balances: balances,

View File

@@ -41,7 +41,10 @@ func UpdateGenesisEth1Data(state state.BeaconState, deposits []*ethpb.Deposit, e
}
}
depositRoot := t.HashTreeRoot()
depositRoot, err := t.HashTreeRoot()
if err != nil {
return nil, err
}
eth1Data.DepositRoot = depositRoot[:]
err = state.SetEth1Data(eth1Data)
if err != nil {

View File

@@ -138,7 +138,8 @@ func TestProcessDeposit_InvalidPublicKey(t *testing.T) {
deposits[0].Proof, err = trie.MerkleProof(0)
require.NoError(t, err)
root := trie.HashTreeRoot()
root, err := trie.HashTreeRoot()
require.NoError(t, err)
eth1Data := &ethpb.Eth1Data{
DepositCount: 1,
@@ -178,7 +179,8 @@ func TestProcessDeposit_InvalidSignature(t *testing.T) {
trie, err := trie.GenerateTrieFromItems([][]byte{leaf[:]}, params.BeaconConfig().DepositContractTreeDepth)
require.NoError(t, err)
root := trie.HashTreeRoot()
root, err := trie.HashTreeRoot()
require.NoError(t, err)
eth1Data := &ethpb.Eth1Data{
DepositCount: 1,
@@ -213,7 +215,8 @@ func TestProcessDeposit_UnableToVerify(t *testing.T) {
trie, _, err := util.DepositTrieFromDeposits(deposits)
require.NoError(t, err)
root := trie.HashTreeRoot()
root, err := trie.HashTreeRoot()
require.NoError(t, err)
eth1Data := &ethpb.Eth1Data{
DepositCount: 1,
DepositRoot: root[:],
@@ -265,7 +268,8 @@ func TestProcessDeposit_IncompleteDeposit(t *testing.T) {
trie, err := trie.NewTrie(params.BeaconConfig().DepositContractTreeDepth)
require.NoError(t, err)
root := trie.HashTreeRoot()
root, err := trie.HashTreeRoot()
require.NoError(t, err)
eth1Data := &ethpb.Eth1Data{
DepositCount: 1,
DepositRoot: root[:],
@@ -281,7 +285,8 @@ func TestProcessDeposit_IncompleteDeposit(t *testing.T) {
for i := 0; i < int(factor-1); i++ {
assert.NoError(t, trie.Insert(dataRoot[:], i))
trieRoot := trie.HashTreeRoot()
trieRoot, err := trie.HashTreeRoot()
require.NoError(t, err)
eth1Data.DepositRoot = trieRoot[:]
eth1Data.DepositCount = uint64(i + 1)

View File

@@ -140,7 +140,7 @@ func (s *Service) ProcessDepositLog(ctx context.Context, depositLog gethTypes.Lo
depositHash, err := depositData.HashTreeRoot()
if err != nil {
return errors.Wrap(err, "Unable to determine hashed value of deposit")
return errors.Wrap(err, "unable to determine hashed value of deposit")
}
// Defensive check to validate incoming index.
@@ -158,20 +158,27 @@ func (s *Service) ProcessDepositLog(ctx context.Context, depositLog gethTypes.Lo
if !s.chainStartData.Chainstarted {
proof, err := s.depositTrie.MerkleProof(int(index))
if err != nil {
return errors.Wrap(err, "Unable to generate merkle proof for deposit")
return errors.Wrap(err, "unable to generate merkle proof for deposit")
}
deposit.Proof = proof
}
// We always store all historical deposits in the DB.
err = s.cfg.depositCache.InsertDeposit(ctx, deposit, depositLog.BlockNumber, index, s.depositTrie.HashTreeRoot())
root, err := s.depositTrie.HashTreeRoot()
if err != nil {
return errors.Wrap(err, "unable to determine root of deposit trie")
}
err = s.cfg.depositCache.InsertDeposit(ctx, deposit, depositLog.BlockNumber, index, root)
if err != nil {
return errors.Wrap(err, "unable to insert deposit into cache")
}
validData := true
if !s.chainStartData.Chainstarted {
s.chainStartData.ChainstartDeposits = append(s.chainStartData.ChainstartDeposits, deposit)
root := s.depositTrie.HashTreeRoot()
root, err := s.depositTrie.HashTreeRoot()
if err != nil {
return errors.Wrap(err, "unable to determine root of deposit trie")
}
eth1Data := &ethpb.Eth1Data{
DepositRoot: root[:],
DepositCount: uint64(len(s.chainStartData.ChainstartDeposits)),
@@ -181,7 +188,11 @@ func (s *Service) ProcessDepositLog(ctx context.Context, depositLog gethTypes.Lo
validData = false
}
} else {
s.cfg.depositCache.InsertPendingDeposit(ctx, deposit, depositLog.BlockNumber, index, s.depositTrie.HashTreeRoot())
root, err := s.depositTrie.HashTreeRoot()
if err != nil {
return errors.Wrap(err, "unable to determine root of deposit trie")
}
s.cfg.depositCache.InsertPendingDeposit(ctx, deposit, depositLog.BlockNumber, index, root)
}
if validData {
log.WithFields(logrus.Fields{
@@ -225,12 +236,16 @@ func (s *Service) ProcessChainStart(genesisTime uint64, eth1BlockHash [32]byte,
for i := range s.chainStartData.ChainstartDeposits {
proof, err := s.depositTrie.MerkleProof(i)
if err != nil {
log.Errorf("Unable to generate deposit proof %v", err)
log.Errorf("unable to generate deposit proof %v", err)
}
s.chainStartData.ChainstartDeposits[i].Proof = proof
}
root := s.depositTrie.HashTreeRoot()
root, err := s.depositTrie.HashTreeRoot()
if err != nil { // This should never happen.
log.WithError(err).Error("unable to determine root of deposit trie, aborting chain start")
return
}
s.chainStartData.Eth1Data = &ethpb.Eth1Data{
DepositCount: uint64(len(s.chainStartData.ChainstartDeposits)),
DepositRoot: root[:],

View File

@@ -197,10 +197,16 @@ func (vs *Server) rebuildDepositTrie(ctx context.Context, canonicalEth1Data *eth
// validate that the provided deposit trie matches up with the canonical eth1 data provided.
func validateDepositTrie(trie *trie.SparseMerkleTrie, canonicalEth1Data *ethpb.Eth1Data) (bool, error) {
if trie == nil || canonicalEth1Data == nil {
return false, errors.New("nil trie or eth1data provided")
}
if trie.NumOfItems() != int(canonicalEth1Data.DepositCount) {
return false, errors.Errorf("wanted the canonical count of %d but received %d", canonicalEth1Data.DepositCount, trie.NumOfItems())
}
rt := trie.HashTreeRoot()
rt, err := trie.HashTreeRoot()
if err != nil {
return false, err
}
if !bytes.Equal(rt[:], canonicalEth1Data.DepositRoot) {
return false, errors.Errorf("wanted the canonical deposit root of %#x but received %#x", canonicalEth1Data.DepositRoot, rt)
}

View File

@@ -503,10 +503,14 @@ func TestProposer_PendingDeposits_OutsideEth1FollowWindow(t *testing.T) {
require.NoError(t, err, "Unable to determine hashed value of deposit")
assert.NoError(t, depositTrie.Insert(depositHash[:], int(dp.Index)))
assert.NoError(t, depositCache.InsertDeposit(ctx, dp.Deposit, dp.Eth1BlockHeight, dp.Index, depositTrie.HashTreeRoot()))
root, err := depositTrie.HashTreeRoot()
require.NoError(t, err)
assert.NoError(t, depositCache.InsertDeposit(ctx, dp.Deposit, dp.Eth1BlockHeight, dp.Index, root))
}
for _, dp := range recentDeposits {
depositCache.InsertPendingDeposit(ctx, dp.Deposit, dp.Eth1BlockHeight, dp.Index, depositTrie.HashTreeRoot())
root, err := depositTrie.HashTreeRoot()
require.NoError(t, err)
depositCache.InsertPendingDeposit(ctx, dp.Deposit, dp.Eth1BlockHeight, dp.Index, root)
}
blk := util.NewBeaconBlock()
@@ -638,10 +642,14 @@ func TestProposer_PendingDeposits_FollowsCorrectEth1Block(t *testing.T) {
require.NoError(t, err, "Unable to determine hashed value of deposit")
assert.NoError(t, depositTrie.Insert(depositHash[:], int(dp.Index)))
assert.NoError(t, depositCache.InsertDeposit(ctx, dp.Deposit, dp.Eth1BlockHeight, dp.Index, depositTrie.HashTreeRoot()))
root, err := depositTrie.HashTreeRoot()
require.NoError(t, err)
assert.NoError(t, depositCache.InsertDeposit(ctx, dp.Deposit, dp.Eth1BlockHeight, dp.Index, root))
}
for _, dp := range recentDeposits {
depositCache.InsertPendingDeposit(ctx, dp.Deposit, dp.Eth1BlockHeight, dp.Index, depositTrie.HashTreeRoot())
root, err := depositTrie.HashTreeRoot()
require.NoError(t, err)
depositCache.InsertPendingDeposit(ctx, dp.Deposit, dp.Eth1BlockHeight, dp.Index, root)
}
bs := &Server{
@@ -737,10 +745,14 @@ func TestProposer_PendingDeposits_CantReturnBelowStateEth1DepositIndex(t *testin
require.NoError(t, err, "Unable to determine hashed value of deposit")
assert.NoError(t, depositTrie.Insert(depositHash[:], int(dp.Index)))
assert.NoError(t, depositCache.InsertDeposit(ctx, dp.Deposit, uint64(dp.Index), dp.Index, depositTrie.HashTreeRoot()))
root, err := depositTrie.HashTreeRoot()
require.NoError(t, err)
assert.NoError(t, depositCache.InsertDeposit(ctx, dp.Deposit, uint64(dp.Index), dp.Index, root))
}
for _, dp := range recentDeposits {
depositCache.InsertPendingDeposit(ctx, dp.Deposit, uint64(dp.Index), dp.Index, depositTrie.HashTreeRoot())
root, err := depositTrie.HashTreeRoot()
require.NoError(t, err)
depositCache.InsertPendingDeposit(ctx, dp.Deposit, uint64(dp.Index), dp.Index, root)
}
bs := &Server{
@@ -833,10 +845,14 @@ func TestProposer_PendingDeposits_CantReturnMoreThanMax(t *testing.T) {
require.NoError(t, err, "Unable to determine hashed value of deposit")
assert.NoError(t, depositTrie.Insert(depositHash[:], int(dp.Index)))
assert.NoError(t, depositCache.InsertDeposit(ctx, dp.Deposit, height.Uint64(), dp.Index, depositTrie.HashTreeRoot()))
root, err := depositTrie.HashTreeRoot()
require.NoError(t, err)
assert.NoError(t, depositCache.InsertDeposit(ctx, dp.Deposit, height.Uint64(), dp.Index, root))
}
for _, dp := range recentDeposits {
depositCache.InsertPendingDeposit(ctx, dp.Deposit, height.Uint64(), dp.Index, depositTrie.HashTreeRoot())
root, err := depositTrie.HashTreeRoot()
require.NoError(t, err)
depositCache.InsertPendingDeposit(ctx, dp.Deposit, height.Uint64(), dp.Index, root)
}
bs := &Server{
@@ -927,10 +943,14 @@ func TestProposer_PendingDeposits_CantReturnMoreThanDepositCount(t *testing.T) {
require.NoError(t, err, "Unable to determine hashed value of deposit")
assert.NoError(t, depositTrie.Insert(depositHash[:], int(dp.Index)))
assert.NoError(t, depositCache.InsertDeposit(ctx, dp.Deposit, uint64(dp.Index), dp.Index, depositTrie.HashTreeRoot()))
root, err := depositTrie.HashTreeRoot()
require.NoError(t, err)
assert.NoError(t, depositCache.InsertDeposit(ctx, dp.Deposit, uint64(dp.Index), dp.Index, root))
}
for _, dp := range recentDeposits {
depositCache.InsertPendingDeposit(ctx, dp.Deposit, uint64(dp.Index), dp.Index, depositTrie.HashTreeRoot())
root, err := depositTrie.HashTreeRoot()
require.NoError(t, err)
depositCache.InsertPendingDeposit(ctx, dp.Deposit, uint64(dp.Index), dp.Index, root)
}
bs := &Server{
@@ -1036,10 +1056,14 @@ func TestProposer_DepositTrie_UtilizesCachedFinalizedDeposits(t *testing.T) {
require.NoError(t, err, "Unable to determine hashed value of deposit")
assert.NoError(t, depositTrie.Insert(depositHash[:], int(dp.Index)))
assert.NoError(t, depositCache.InsertDeposit(ctx, dp.Deposit, dp.Eth1BlockHeight, dp.Index, depositTrie.HashTreeRoot()))
root, err := depositTrie.HashTreeRoot()
require.NoError(t, err)
assert.NoError(t, depositCache.InsertDeposit(ctx, dp.Deposit, dp.Eth1BlockHeight, dp.Index, root))
}
for _, dp := range recentDeposits {
depositCache.InsertPendingDeposit(ctx, dp.Deposit, dp.Eth1BlockHeight, dp.Index, depositTrie.HashTreeRoot())
root, err := depositTrie.HashTreeRoot()
require.NoError(t, err)
depositCache.InsertPendingDeposit(ctx, dp.Deposit, dp.Eth1BlockHeight, dp.Index, root)
}
bs := &Server{
@@ -1055,8 +1079,10 @@ func TestProposer_DepositTrie_UtilizesCachedFinalizedDeposits(t *testing.T) {
trie, err := bs.depositTrie(ctx, &ethpb.Eth1Data{}, big.NewInt(int64(params.BeaconConfig().Eth1FollowDistance)))
require.NoError(t, err)
actualRoot := trie.HashTreeRoot()
expectedRoot := depositTrie.HashTreeRoot()
actualRoot, err := trie.HashTreeRoot()
require.NoError(t, err)
expectedRoot, err := depositTrie.HashTreeRoot()
require.NoError(t, err)
assert.Equal(t, expectedRoot, actualRoot, "Incorrect deposit trie root")
}
@@ -1146,10 +1172,14 @@ func TestProposer_DepositTrie_RebuildTrie(t *testing.T) {
require.NoError(t, err, "Unable to determine hashed value of deposit")
assert.NoError(t, depositTrie.Insert(depositHash[:], int(dp.Index)))
assert.NoError(t, depositCache.InsertDeposit(ctx, dp.Deposit, dp.Eth1BlockHeight, dp.Index, depositTrie.HashTreeRoot()))
root, err := depositTrie.HashTreeRoot()
require.NoError(t, err)
assert.NoError(t, depositCache.InsertDeposit(ctx, dp.Deposit, dp.Eth1BlockHeight, dp.Index, root))
}
for _, dp := range recentDeposits {
depositCache.InsertPendingDeposit(ctx, dp.Deposit, dp.Eth1BlockHeight, dp.Index, depositTrie.HashTreeRoot())
root, err := depositTrie.HashTreeRoot()
require.NoError(t, err)
depositCache.InsertPendingDeposit(ctx, dp.Deposit, dp.Eth1BlockHeight, dp.Index, root)
}
d := depositCache.AllDepositContainers(ctx)
origDeposit, ok := proto.Clone(d[0].Deposit).(*ethpb.Deposit)
@@ -1177,8 +1207,10 @@ func TestProposer_DepositTrie_RebuildTrie(t *testing.T) {
trie, err := bs.depositTrie(ctx, &ethpb.Eth1Data{}, big.NewInt(int64(params.BeaconConfig().Eth1FollowDistance)))
require.NoError(t, err)
expectedRoot := depositTrie.HashTreeRoot()
actualRoot := trie.HashTreeRoot()
expectedRoot, err := depositTrie.HashTreeRoot()
require.NoError(t, err)
actualRoot, err := trie.HashTreeRoot()
require.NoError(t, err)
assert.Equal(t, expectedRoot, actualRoot, "Incorrect deposit trie root")
}
@@ -1230,7 +1262,8 @@ func TestProposer_ValidateDepositTrie(t *testing.T) {
assert.NoError(t, trie.Insert([]byte{'a'}, 0))
assert.NoError(t, trie.Insert([]byte{'b'}, 1))
assert.NoError(t, trie.Insert([]byte{'c'}, 2))
rt := trie.HashTreeRoot()
rt, err := trie.HashTreeRoot()
require.NoError(t, err)
return &ethpb.Eth1Data{DepositRoot: rt[:], DepositCount: 3, BlockHash: []byte{}}
},
trieCreator: func() *trie.SparseMerkleTrie {
@@ -1274,7 +1307,9 @@ func TestProposer_Eth1Data_MajorityVote(t *testing.T) {
require.NoError(t, err)
depositCache, err := depositcache.New()
require.NoError(t, err)
assert.NoError(t, depositCache.InsertDeposit(context.Background(), dc.Deposit, dc.Eth1BlockHeight, dc.Index, depositTrie.HashTreeRoot()))
root, err := depositTrie.HashTreeRoot()
require.NoError(t, err)
assert.NoError(t, depositCache.InsertDeposit(context.Background(), dc.Deposit, dc.Eth1BlockHeight, dc.Index, root))
t.Run("choose highest count", func(t *testing.T) {
t.Skip()
@@ -1976,10 +2011,14 @@ func TestProposer_Deposits_ReturnsEmptyList_IfLatestEth1DataEqGenesisEth1Block(t
require.NoError(t, err, "Unable to determine hashed value of deposit")
assert.NoError(t, depositTrie.Insert(depositHash[:], int(dp.Index)))
assert.NoError(t, depositCache.InsertDeposit(ctx, dp.Deposit, uint64(dp.Index), dp.Index, depositTrie.HashTreeRoot()))
root, err := depositTrie.HashTreeRoot()
require.NoError(t, err)
assert.NoError(t, depositCache.InsertDeposit(ctx, dp.Deposit, uint64(dp.Index), dp.Index, root))
}
for _, dp := range recentDeposits {
depositCache.InsertPendingDeposit(ctx, dp.Deposit, uint64(dp.Index), dp.Index, depositTrie.HashTreeRoot())
root, err := depositTrie.HashTreeRoot()
require.NoError(t, err)
depositCache.InsertPendingDeposit(ctx, dp.Deposit, uint64(dp.Index), dp.Index, root)
}
bs := &Server{

View File

@@ -137,7 +137,9 @@ func TestWaitForActivation_ValidatorOriginallyExists(t *testing.T) {
depositCache, err := depositcache.New()
require.NoError(t, err)
assert.NoError(t, depositCache.InsertDeposit(ctx, deposit, 10 /*blockNum*/, 0, depositTrie.HashTreeRoot()))
root, err := depositTrie.HashTreeRoot()
require.NoError(t, err)
assert.NoError(t, depositCache.InsertDeposit(ctx, deposit, 10 /*blockNum*/, 0, root))
trie, err := v1.InitializeFromProtoUnsafe(beaconState)
require.NoError(t, err)
vs := &Server{

View File

@@ -41,7 +41,9 @@ func TestValidatorStatus_DepositedEth1(t *testing.T) {
depositCache, err := depositcache.New()
require.NoError(t, err)
assert.NoError(t, depositCache.InsertDeposit(ctx, deposit, 0 /*blockNum*/, 0, depositTrie.HashTreeRoot()))
root, err := depositTrie.HashTreeRoot()
require.NoError(t, err)
assert.NoError(t, depositCache.InsertDeposit(ctx, deposit, 0 /*blockNum*/, 0, root))
height := time.Unix(int64(params.BeaconConfig().Eth1FollowDistance), 0).Unix()
p := &mockPOW.POWChain{
TimesByHeight: map[int]uint64{
@@ -84,7 +86,9 @@ func TestValidatorStatus_Deposited(t *testing.T) {
depositCache, err := depositcache.New()
require.NoError(t, err)
assert.NoError(t, depositCache.InsertDeposit(ctx, deposit, 0 /*blockNum*/, 0, depositTrie.HashTreeRoot()))
root, err := depositTrie.HashTreeRoot()
require.NoError(t, err)
assert.NoError(t, depositCache.InsertDeposit(ctx, deposit, 0 /*blockNum*/, 0, root))
height := time.Unix(int64(params.BeaconConfig().Eth1FollowDistance), 0).Unix()
p := &mockPOW.POWChain{
TimesByHeight: map[int]uint64{
@@ -134,7 +138,9 @@ func TestValidatorStatus_PartiallyDeposited(t *testing.T) {
depositCache, err := depositcache.New()
require.NoError(t, err)
assert.NoError(t, depositCache.InsertDeposit(ctx, deposit, 0 /*blockNum*/, 0, depositTrie.HashTreeRoot()))
root, err := depositTrie.HashTreeRoot()
require.NoError(t, err)
assert.NoError(t, depositCache.InsertDeposit(ctx, deposit, 0 /*blockNum*/, 0, root))
height := time.Unix(int64(params.BeaconConfig().Eth1FollowDistance), 0).Unix()
p := &mockPOW.POWChain{
TimesByHeight: map[int]uint64{
@@ -202,7 +208,9 @@ func TestValidatorStatus_Pending(t *testing.T) {
depositCache, err := depositcache.New()
require.NoError(t, err)
assert.NoError(t, depositCache.InsertDeposit(ctx, deposit, 0 /*blockNum*/, 0, depositTrie.HashTreeRoot()))
root, err := depositTrie.HashTreeRoot()
require.NoError(t, err)
assert.NoError(t, depositCache.InsertDeposit(ctx, deposit, 0 /*blockNum*/, 0, root))
height := time.Unix(int64(params.BeaconConfig().Eth1FollowDistance), 0).Unix()
p := &mockPOW.POWChain{
@@ -247,7 +255,9 @@ func TestValidatorStatus_Active(t *testing.T) {
depositCache, err := depositcache.New()
require.NoError(t, err)
assert.NoError(t, depositCache.InsertDeposit(ctx, deposit, 0 /*blockNum*/, 0, depositTrie.HashTreeRoot()))
root, err := depositTrie.HashTreeRoot()
require.NoError(t, err)
assert.NoError(t, depositCache.InsertDeposit(ctx, deposit, 0 /*blockNum*/, 0, root))
// Active because activation epoch <= current epoch < exit epoch.
activeEpoch := helpers.ActivationExitEpoch(0)
@@ -334,7 +344,9 @@ func TestValidatorStatus_Exiting(t *testing.T) {
depositCache, err := depositcache.New()
require.NoError(t, err)
assert.NoError(t, depositCache.InsertDeposit(ctx, deposit, 0 /*blockNum*/, 0, depositTrie.HashTreeRoot()))
root, err := depositTrie.HashTreeRoot()
require.NoError(t, err)
assert.NoError(t, depositCache.InsertDeposit(ctx, deposit, 0 /*blockNum*/, 0, root))
height := time.Unix(int64(params.BeaconConfig().Eth1FollowDistance), 0).Unix()
p := &mockPOW.POWChain{
TimesByHeight: map[int]uint64{
@@ -391,7 +403,9 @@ func TestValidatorStatus_Slashing(t *testing.T) {
depositCache, err := depositcache.New()
require.NoError(t, err)
assert.NoError(t, depositCache.InsertDeposit(ctx, deposit, 0 /*blockNum*/, 0, depositTrie.HashTreeRoot()))
root, err := depositTrie.HashTreeRoot()
require.NoError(t, err)
assert.NoError(t, depositCache.InsertDeposit(ctx, deposit, 0 /*blockNum*/, 0, root))
height := time.Unix(int64(params.BeaconConfig().Eth1FollowDistance), 0).Unix()
p := &mockPOW.POWChain{
TimesByHeight: map[int]uint64{
@@ -449,7 +463,9 @@ func TestValidatorStatus_Exited(t *testing.T) {
depositCache, err := depositcache.New()
require.NoError(t, err)
assert.NoError(t, depositCache.InsertDeposit(ctx, deposit, 0 /*blockNum*/, 0, depositTrie.HashTreeRoot()))
root, err := depositTrie.HashTreeRoot()
require.NoError(t, err)
assert.NoError(t, depositCache.InsertDeposit(ctx, deposit, 0 /*blockNum*/, 0, root))
height := time.Unix(int64(params.BeaconConfig().Eth1FollowDistance), 0).Unix()
p := &mockPOW.POWChain{
TimesByHeight: map[int]uint64{
@@ -532,11 +548,15 @@ func TestActivationStatus_OK(t *testing.T) {
depositCache, err := depositcache.New()
require.NoError(t, err)
assert.NoError(t, depositCache.InsertDeposit(ctx, dep, 10 /*blockNum*/, 0, depositTrie.HashTreeRoot()))
root, err := depositTrie.HashTreeRoot()
require.NoError(t, err)
assert.NoError(t, depositCache.InsertDeposit(ctx, dep, 10 /*blockNum*/, 0, root))
dep = deposits[2]
assert.NoError(t, depositTrie.Insert(dep.Data.Signature, 15))
assert.NoError(t, depositCache.InsertDeposit(context.Background(), dep, 0, 1, depositTrie.HashTreeRoot()))
root, err = depositTrie.HashTreeRoot()
require.NoError(t, err)
assert.NoError(t, depositCache.InsertDeposit(context.Background(), dep, 0, 1, root))
vs := &Server{
Ctx: context.Background(),
@@ -677,7 +697,9 @@ func TestValidatorStatus_CorrectActivationQueue(t *testing.T) {
deposit := &ethpb.Deposit{
Data: depData,
}
assert.NoError(t, depositCache.InsertDeposit(ctx, deposit, 0 /*blockNum*/, int64(i), depositTrie.HashTreeRoot()))
root, err := depositTrie.HashTreeRoot()
require.NoError(t, err)
assert.NoError(t, depositCache.InsertDeposit(ctx, deposit, 0 /*blockNum*/, int64(i), root))
}
@@ -758,10 +780,14 @@ func TestMultipleValidatorStatus_Pubkeys(t *testing.T) {
require.NoError(t, err)
dep := deposits[0]
assert.NoError(t, depositCache.InsertDeposit(ctx, dep, 10 /*blockNum*/, 0, depositTrie.HashTreeRoot()))
root, err := depositTrie.HashTreeRoot()
require.NoError(t, err)
assert.NoError(t, depositCache.InsertDeposit(ctx, dep, 10 /*blockNum*/, 0, root))
dep = deposits[2]
assert.NoError(t, depositTrie.Insert(dep.Data.Signature, 15))
assert.NoError(t, depositCache.InsertDeposit(context.Background(), dep, 0, 1, depositTrie.HashTreeRoot()))
root, err = depositTrie.HashTreeRoot()
require.NoError(t, err)
assert.NoError(t, depositCache.InsertDeposit(context.Background(), dep, 0, 1, root))
vs := &Server{
Ctx: context.Background(),
@@ -918,7 +944,9 @@ func TestValidatorStatus_Invalid(t *testing.T) {
depositCache, err := depositcache.New()
require.NoError(t, err)
assert.NoError(t, depositCache.InsertDeposit(ctx, deposit, 0 /*blockNum*/, 0, depositTrie.HashTreeRoot()))
root, err := depositTrie.HashTreeRoot()
require.NoError(t, err)
assert.NoError(t, depositCache.InsertDeposit(ctx, deposit, 0 /*blockNum*/, 0, root))
height := time.Unix(int64(params.BeaconConfig().Eth1FollowDistance), 0).Unix()
p := &mockPOW.POWChain{
TimesByHeight: map[int]uint64{

View File

@@ -19,7 +19,11 @@ go_library(
go_test(
name = "go_default_test",
size = "small",
srcs = ["sparse_merkle_test.go"],
srcs = [
"sparse_merkle_test.go",
"sparse_merkle_trie_fuzz_test.go",
],
data = glob(["testdata/**"]),
deps = [
":go_default_library",
"//config/fieldparams:go_default_library",
@@ -31,5 +35,6 @@ go_test(
"//testing/assert:go_default_library",
"//testing/require:go_default_library",
"@com_github_ethereum_go_ethereum//accounts/abi/bind:go_default_library",
"@com_github_golang_protobuf//proto:go_default_library",
],
)

View File

@@ -81,7 +81,11 @@ func (m *SparseMerkleTrie) Items() [][]byte {
// HashTreeRoot of the Merkle trie as defined in the deposit contract.
// Spec Definition:
// sha256(concat(node, self.to_little_endian_64(self.deposit_count), slice(zero_bytes32, start=0, len=24)))
func (m *SparseMerkleTrie) HashTreeRoot() [32]byte {
func (m *SparseMerkleTrie) HashTreeRoot() ([32]byte, error) {
if len(m.branches) == 0 || len(m.branches[len(m.branches)-1]) == 0 {
return [32]byte{}, errors.New("invalid branches provided to compute root")
}
enc := [32]byte{}
depositCount := uint64(len(m.originalItems))
if len(m.originalItems) == 1 && bytes.Equal(m.originalItems[0], ZeroHashes[0][:]) {
@@ -89,7 +93,7 @@ func (m *SparseMerkleTrie) HashTreeRoot() [32]byte {
depositCount = 0
}
binary.LittleEndian.PutUint64(enc[:], depositCount)
return hash.Hash(append(m.branches[len(m.branches)-1][0], enc[:]...))
return hash.Hash(append(m.branches[len(m.branches)-1][0], enc[:]...)), nil
}
// Insert an item into the trie.
@@ -97,6 +101,12 @@ func (m *SparseMerkleTrie) Insert(item []byte, index int) error {
if index < 0 {
return fmt.Errorf("negative index provided: %d", index)
}
if len(m.branches) == 0 {
return errors.New("invalid trie: no branches")
}
if m.depth > uint(len(m.branches)) {
return errors.New("invalid trie: depth is greater than number of branches")
}
for index >= len(m.branches[0]) {
m.branches[0] = append(m.branches[0], ZeroHashes[0][:])
}
@@ -143,11 +153,17 @@ func (m *SparseMerkleTrie) MerkleProof(index int) ([][]byte, error) {
if index < 0 {
return nil, fmt.Errorf("merkle index is negative: %d", index)
}
merkleIndex := uint(index)
if len(m.branches) == 0 {
return nil, errors.New("invalid trie: no branches")
}
leaves := m.branches[0]
if index >= len(leaves) {
return nil, fmt.Errorf("merkle index out of range in trie, max range: %d, received: %d", len(leaves), index)
}
if m.depth > uint(len(m.branches)) {
return nil, errors.New("invalid trie: depth is greater than number of branches")
}
merkleIndex := uint(index)
proof := make([][]byte, m.depth+1)
for i := uint(0); i < m.depth; i++ {
subIndex := (merkleIndex / (1 << i)) ^ 1
@@ -185,6 +201,9 @@ func VerifyMerkleProofWithDepth(root, item []byte, merkleIndex uint64, proof [][
if uint64(len(proof)) != depth+1 {
return false
}
if depth >= 64 {
return false // PowerOf2 would overflow.
}
node := bytesutil.ToBytes32(item)
for i := uint64(0); i <= depth; i++ {
if (merkleIndex / math.PowerOf2(i) % 2) != 0 {
@@ -200,15 +219,10 @@ func VerifyMerkleProofWithDepth(root, item []byte, merkleIndex uint64, proof [][
// VerifyMerkleProof given a trie root, a leaf, the generalized merkle index
// of the leaf in the trie, and the proof itself.
func VerifyMerkleProof(root, item []byte, merkleIndex uint64, proof [][]byte) bool {
node := bytesutil.ToBytes32(item)
for i := 0; i < len(proof); i++ {
if (merkleIndex / math.PowerOf2(uint64(i)) % 2) != 0 {
node = hash.Hash(append(proof[i], node[:]...))
} else {
node = hash.Hash(append(node[:], proof[i]...))
if len(proof) == 0 {
return false
}
}
return bytes.Equal(root, node[:])
return VerifyMerkleProofWithDepth(root, item, merkleIndex, proof, uint64(len(proof)-1))
}
// Copy performs a deep copy of the trie.

View File

@@ -79,7 +79,9 @@ func TestMerkleTrieRoot_EmptyTrie(t *testing.T) {
depRoot, err := testAccount.Contract.GetDepositRoot(&bind.CallOpts{})
require.NoError(t, err)
require.DeepEqual(t, depRoot, trie.HashTreeRoot())
root, err := trie.HashTreeRoot()
require.NoError(t, err)
require.DeepEqual(t, depRoot, root)
}
func TestGenerateTrieFromItems_NoItemsProvided(t *testing.T) {
@@ -104,7 +106,8 @@ func TestMerkleTrie_VerifyMerkleProofWithDepth(t *testing.T) {
proof, err := m.MerkleProof(0)
require.NoError(t, err)
require.Equal(t, int(params.BeaconConfig().DepositContractTreeDepth)+1, len(proof))
root := m.HashTreeRoot()
root, err := m.HashTreeRoot()
require.NoError(t, err)
if ok := trie.VerifyMerkleProofWithDepth(root[:], items[0], 0, proof, params.BeaconConfig().DepositContractTreeDepth); !ok {
t.Error("First Merkle proof did not verify")
}
@@ -130,7 +133,8 @@ func TestMerkleTrie_VerifyMerkleProof(t *testing.T) {
proof, err := m.MerkleProof(0)
require.NoError(t, err)
require.Equal(t, int(params.BeaconConfig().DepositContractTreeDepth)+1, len(proof))
root := m.HashTreeRoot()
root, err := m.HashTreeRoot()
require.NoError(t, err)
if ok := trie.VerifyMerkleProof(root[:], items[0], 0, proof); !ok {
t.Error("First Merkle proof did not verify")
}
@@ -170,14 +174,16 @@ func TestMerkleTrie_VerifyMerkleProof_TrieUpdated(t *testing.T) {
require.NoError(t, err)
proof, err := m.MerkleProof(0)
require.NoError(t, err)
root := m.HashTreeRoot()
root, err := m.HashTreeRoot()
require.NoError(t, err)
require.Equal(t, true, trie.VerifyMerkleProofWithDepth(root[:], items[0], 0, proof, depth))
// Now we update the trie.
assert.NoError(t, m.Insert([]byte{5}, 3))
proof, err = m.MerkleProof(3)
require.NoError(t, err)
root = m.HashTreeRoot()
root, err = m.HashTreeRoot()
require.NoError(t, err)
if ok := trie.VerifyMerkleProofWithDepth(root[:], []byte{5}, 3, proof, depth); !ok {
t.Error("Second Merkle proof did not verify")
}
@@ -200,10 +206,13 @@ func TestRoundtripProto_OK(t *testing.T) {
require.NoError(t, err)
protoTrie := m.ToProto()
depositRoot := m.HashTreeRoot()
depositRoot, err := m.HashTreeRoot()
require.NoError(t, err)
newTrie := trie.CreateTrieFromProto(protoTrie)
require.DeepEqual(t, depositRoot, newTrie.HashTreeRoot())
root, err := newTrie.HashTreeRoot()
require.NoError(t, err)
require.DeepEqual(t, depositRoot, root)
}
@@ -221,8 +230,11 @@ func TestCopy_OK(t *testing.T) {
if copiedTrie == source {
t.Errorf("Original trie returned.")
}
copyHash := copiedTrie.HashTreeRoot()
require.DeepEqual(t, copyHash, copiedTrie.HashTreeRoot())
a, err := copiedTrie.HashTreeRoot()
require.NoError(t, err)
b, err := source.HashTreeRoot()
require.NoError(t, err)
require.DeepEqual(t, a, b)
}
func BenchmarkGenerateTrieFromItems(b *testing.B) {
@@ -296,7 +308,8 @@ func BenchmarkVerifyMerkleProofWithDepth(b *testing.B) {
proof, err := m.MerkleProof(2)
require.NoError(b, err)
root := m.HashTreeRoot()
root, err := m.HashTreeRoot()
require.NoError(b, err)
b.StartTimer()
for i := 0; i < b.N; i++ {
if ok := trie.VerifyMerkleProofWithDepth(root[:], items[2], 2, proof, params.BeaconConfig().DepositContractTreeDepth); !ok {

View File

@@ -0,0 +1,148 @@
package trie_test
import (
"testing"
"github.com/golang/protobuf/proto"
"github.com/prysmaticlabs/prysm/config/params"
"github.com/prysmaticlabs/prysm/container/trie"
"github.com/prysmaticlabs/prysm/crypto/hash"
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/testing/require"
)
func FuzzSparseMerkleTrie_HashTreeRoot(f *testing.F) {
h := hash.Hash([]byte("hi"))
pb := &ethpb.SparseMerkleTrie{
Layers: []*ethpb.TrieLayer{
{
Layer: [][]byte{h[:]},
},
{
Layer: [][]byte{h[:]},
},
{
Layer: [][]byte{},
},
},
Depth: 4,
}
b, err := proto.Marshal(pb)
require.NoError(f, err)
f.Add(b)
f.Fuzz(func(t *testing.T, b []byte) {
pb := &ethpb.SparseMerkleTrie{}
if err := proto.Unmarshal(b, pb); err != nil {
return
}
_, err := trie.CreateTrieFromProto(pb).HashTreeRoot()
if err != nil {
return
}
})
}
func FuzzSparseMerkleTrie_MerkleProof(f *testing.F) {
h := hash.Hash([]byte("hi"))
pb := &ethpb.SparseMerkleTrie{
Layers: []*ethpb.TrieLayer{
{
Layer: [][]byte{h[:]},
},
{
Layer: [][]byte{h[:]},
},
{
Layer: [][]byte{},
},
},
Depth: 4,
}
b, err := proto.Marshal(pb)
require.NoError(f, err)
f.Add(b, 0)
f.Fuzz(func(t *testing.T, b []byte, i int) {
pb := &ethpb.SparseMerkleTrie{}
if err := proto.Unmarshal(b, pb); err != nil {
return
}
_, err := trie.CreateTrieFromProto(pb).MerkleProof(i)
if err != nil {
return
}
})
}
func FuzzSparseMerkleTrie_Insert(f *testing.F) {
h := hash.Hash([]byte("hi"))
pb := &ethpb.SparseMerkleTrie{
Layers: []*ethpb.TrieLayer{
{
Layer: [][]byte{h[:]},
},
{
Layer: [][]byte{h[:]},
},
{
Layer: [][]byte{},
},
},
Depth: 4,
}
b, err := proto.Marshal(pb)
require.NoError(f, err)
f.Add(b, []byte{}, 0)
f.Fuzz(func(t *testing.T, b, item []byte, i int) {
pb := &ethpb.SparseMerkleTrie{}
if err := proto.Unmarshal(b, pb); err != nil {
return
}
if err := trie.CreateTrieFromProto(pb).Insert(item, i); err != nil {
return
}
})
}
func FuzzSparseMerkleTrie_VerifyMerkleProofWithDepth(f *testing.F) {
splitProofs := func(proofRaw []byte) [][]byte {
var proofs [][]byte
for i := 0; i < len(proofRaw); i += 32 {
end := i + 32
if end >= len(proofRaw) {
end = len(proofRaw) - 1
}
proofs = append(proofs, proofRaw[i:end])
}
return proofs
}
items := [][]byte{
[]byte("A"),
[]byte("B"),
[]byte("C"),
[]byte("D"),
[]byte("E"),
[]byte("F"),
[]byte("G"),
[]byte("H"),
}
m, err := trie.GenerateTrieFromItems(items, params.BeaconConfig().DepositContractTreeDepth)
require.NoError(f, err)
proof, err := m.MerkleProof(0)
require.NoError(f, err)
require.Equal(f, int(params.BeaconConfig().DepositContractTreeDepth)+1, len(proof))
root, err := m.HashTreeRoot()
require.NoError(f, err)
var proofRaw []byte
for _, p := range proof {
proofRaw = append(proofRaw, p...)
}
f.Add(root[:], items[0], uint64(0), proofRaw, params.BeaconConfig().DepositContractTreeDepth)
f.Fuzz(func(t *testing.T, root, item []byte, merkleIndex uint64, proofRaw []byte, depth uint64) {
trie.VerifyMerkleProofWithDepth(root, item, merkleIndex, splitProofs(proofRaw), depth)
})
}

View File

@@ -0,0 +1,4 @@
go test fuzz v1
[]byte("")
[]byte("0")
int(41)

View File

@@ -0,0 +1,3 @@
go test fuzz v1
[]byte("")
int(63)

View File

@@ -0,0 +1,6 @@
go test fuzz v1
[]byte("0")
[]byte("000000000")
uint64(0)
[]byte("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))00000000000000000000000000000000000000000000000000000000000000")
uint64(71)

View File

@@ -23,7 +23,9 @@ func TestDepositTrieRoot_OK(t *testing.T) {
depRoot, err := testAcc.Contract.GetDepositRoot(&bind.CallOpts{})
require.NoError(t, err)
assert.Equal(t, depRoot, localTrie.HashTreeRoot(), "Local deposit trie root and contract deposit trie root are not equal")
localRoot, err := localTrie.HashTreeRoot()
require.NoError(t, err)
assert.Equal(t, depRoot, localRoot, "Local deposit trie root and contract deposit trie root are not equal")
privKeys, pubKeys, err := interop.DeterministicallyGenerateKeys(0 /*startIndex*/, 101)
require.NoError(t, err)
@@ -47,7 +49,9 @@ func TestDepositTrieRoot_OK(t *testing.T) {
assert.NoError(t, localTrie.Insert(item[:], i))
depRoot, err = testAcc.Contract.GetDepositRoot(&bind.CallOpts{})
require.NoError(t, err)
assert.Equal(t, depRoot, localTrie.HashTreeRoot(), "Local deposit trie root and contract deposit trie root are not equal for index %d", i)
localRoot, err := localTrie.HashTreeRoot()
require.NoError(t, err)
assert.Equal(t, depRoot, localRoot, "Local deposit trie root and contract deposit trie root are not equal for index %d", i)
}
}
@@ -61,7 +65,9 @@ func TestDepositTrieRoot_Fail(t *testing.T) {
depRoot, err := testAcc.Contract.GetDepositRoot(&bind.CallOpts{})
require.NoError(t, err)
assert.Equal(t, depRoot, localTrie.HashTreeRoot(), "Local deposit trie root and contract deposit trie root are not equal")
localRoot, err := localTrie.HashTreeRoot()
require.NoError(t, err)
assert.Equal(t, depRoot, localRoot, "Local deposit trie root and contract deposit trie root are not equal")
privKeys, pubKeys, err := interop.DeterministicallyGenerateKeys(0 /*startIndex*/, 101)
require.NoError(t, err)
@@ -89,6 +95,8 @@ func TestDepositTrieRoot_Fail(t *testing.T) {
depRoot, err = testAcc.Contract.GetDepositRoot(&bind.CallOpts{})
require.NoError(t, err)
assert.NotEqual(t, depRoot, localTrie.HashTreeRoot(), "Local deposit trie root and contract deposit trie root are equal for index %d", i)
localRoot, err := localTrie.HashTreeRoot()
require.NoError(t, err)
assert.NotEqual(t, depRoot, localRoot, "Local deposit trie root and contract deposit trie root are equal for index %d", i)
}
}

View File

@@ -54,7 +54,10 @@ func GenerateGenesisStateFromDepositData(
if err != nil {
return nil, nil, errors.Wrap(err, "could not generate deposits from the deposit data provided")
}
root := trie.HashTreeRoot()
root, err := trie.HashTreeRoot()
if err != nil {
return nil, nil, errors.Wrap(err, "could not hash tree root of deposit trie")
}
if genesisTime == 0 {
genesisTime = uint64(time.Now().Unix())
}

View File

@@ -23,7 +23,8 @@ func TestGenerateGenesisState(t *testing.T) {
require.NoError(t, err)
deposits, err := interop.GenerateDepositsFromData(depositDataItems, tr)
require.NoError(t, err)
root := tr.HashTreeRoot()
root, err := tr.HashTreeRoot()
require.NoError(t, err)
genesisState, err := transition.GenesisBeaconState(context.Background(), deposits, 0, &eth.Eth1Data{
DepositRoot: root[:],
DepositCount: uint64(len(deposits)),

View File

@@ -242,7 +242,10 @@ func DeterministicEth1Data(size int) (*ethpb.Eth1Data, error) {
if err != nil {
return nil, errors.Wrap(err, "failed to create trie")
}
root := depositTrie.HashTreeRoot()
root, err := depositTrie.HashTreeRoot()
if err != nil {
return nil, errors.Wrap(err, "failed to compute deposit trie root")
}
eth1Data := &ethpb.Eth1Data{
BlockHash: root[:],
DepositRoot: root[:],

View File

@@ -276,7 +276,10 @@ func TestDepositTrieFromDeposits(t *testing.T) {
depositTrie, _, err := DepositTrieFromDeposits(deposits)
require.NoError(t, err)
root := depositTrie.HashTreeRoot()
root, err := depositTrie.HashTreeRoot()
if err != nil {
t.Fatal(err)
}
if !bytes.Equal(root[:], eth1Data.DepositRoot) {
t.Fatal("expected deposit trie root to equal eth1data deposit root")
}