github.com/prysmaticlabs/prysm@v1.4.4/beacon-chain/forkchoice/protoarray/helpers_test.go (about)

     1  package protoarray
     2  
     3  import (
     4  	"context"
     5  	"encoding/binary"
     6  	"testing"
     7  
     8  	"github.com/prysmaticlabs/prysm/shared/hashutil"
     9  	"github.com/prysmaticlabs/prysm/shared/params"
    10  	"github.com/prysmaticlabs/prysm/shared/testutil/assert"
    11  	"github.com/prysmaticlabs/prysm/shared/testutil/require"
    12  )
    13  
    14  func TestComputeDelta_ZeroHash(t *testing.T) {
    15  	validatorCount := uint64(16)
    16  	indices := make(map[[32]byte]uint64)
    17  	votes := make([]Vote, 0)
    18  	oldBalances := make([]uint64, 0)
    19  	newBalances := make([]uint64, 0)
    20  
    21  	for i := uint64(0); i < validatorCount; i++ {
    22  		indices[indexToHash(i)] = i
    23  		votes = append(votes, Vote{params.BeaconConfig().ZeroHash, params.BeaconConfig().ZeroHash, 0})
    24  		oldBalances = append(oldBalances, 0)
    25  		newBalances = append(newBalances, 0)
    26  	}
    27  
    28  	delta, _, err := computeDeltas(context.Background(), indices, votes, oldBalances, newBalances)
    29  	require.NoError(t, err)
    30  	assert.Equal(t, int(validatorCount), len(delta))
    31  
    32  	for _, d := range delta {
    33  		assert.Equal(t, 0, d)
    34  	}
    35  	for _, vote := range votes {
    36  		assert.Equal(t, vote.currentRoot, vote.nextRoot, "The vote should not have changed")
    37  	}
    38  }
    39  
    40  func TestComputeDelta_AllVoteTheSame(t *testing.T) {
    41  	validatorCount := uint64(16)
    42  	balance := uint64(32)
    43  	indices := make(map[[32]byte]uint64)
    44  	votes := make([]Vote, 0)
    45  	oldBalances := make([]uint64, 0)
    46  	newBalances := make([]uint64, 0)
    47  
    48  	for i := uint64(0); i < validatorCount; i++ {
    49  		indices[indexToHash(i)] = i
    50  		votes = append(votes, Vote{params.BeaconConfig().ZeroHash, indexToHash(0), 0})
    51  		oldBalances = append(oldBalances, balance)
    52  		newBalances = append(newBalances, balance)
    53  	}
    54  
    55  	delta, _, err := computeDeltas(context.Background(), indices, votes, oldBalances, newBalances)
    56  	require.NoError(t, err)
    57  	assert.Equal(t, int(validatorCount), len(delta))
    58  
    59  	for i, d := range delta {
    60  		if i == 0 {
    61  			assert.Equal(t, balance*validatorCount, uint64(d))
    62  		} else {
    63  			assert.Equal(t, 0, d)
    64  		}
    65  	}
    66  
    67  	for _, vote := range votes {
    68  		assert.Equal(t, vote.currentRoot, vote.nextRoot, "The vote should not have changed")
    69  	}
    70  }
    71  
    72  func TestComputeDelta_DifferentVotes(t *testing.T) {
    73  	validatorCount := uint64(16)
    74  	balance := uint64(32)
    75  	indices := make(map[[32]byte]uint64)
    76  	votes := make([]Vote, 0)
    77  	oldBalances := make([]uint64, 0)
    78  	newBalances := make([]uint64, 0)
    79  
    80  	for i := uint64(0); i < validatorCount; i++ {
    81  		indices[indexToHash(i)] = i
    82  		votes = append(votes, Vote{params.BeaconConfig().ZeroHash, indexToHash(i), 0})
    83  		oldBalances = append(oldBalances, balance)
    84  		newBalances = append(newBalances, balance)
    85  	}
    86  
    87  	delta, _, err := computeDeltas(context.Background(), indices, votes, oldBalances, newBalances)
    88  	require.NoError(t, err)
    89  	assert.Equal(t, int(validatorCount), len(delta))
    90  
    91  	for _, d := range delta {
    92  		assert.Equal(t, balance, uint64(d))
    93  	}
    94  
    95  	for _, vote := range votes {
    96  		assert.Equal(t, vote.currentRoot, vote.nextRoot, "The vote should not have changed")
    97  	}
    98  }
    99  
   100  func TestComputeDelta_MovingVotes(t *testing.T) {
   101  	validatorCount := uint64(16)
   102  	balance := uint64(32)
   103  	indices := make(map[[32]byte]uint64)
   104  	votes := make([]Vote, 0)
   105  	oldBalances := make([]uint64, 0)
   106  	newBalances := make([]uint64, 0)
   107  
   108  	lastIndex := uint64(len(indices) - 1)
   109  	for i := uint64(0); i < validatorCount; i++ {
   110  		indices[indexToHash(i)] = i
   111  		votes = append(votes, Vote{indexToHash(0), indexToHash(lastIndex), 0})
   112  		oldBalances = append(oldBalances, balance)
   113  		newBalances = append(newBalances, balance)
   114  	}
   115  
   116  	delta, _, err := computeDeltas(context.Background(), indices, votes, oldBalances, newBalances)
   117  	require.NoError(t, err)
   118  	assert.Equal(t, int(validatorCount), len(delta))
   119  
   120  	for i, d := range delta {
   121  		if i == 0 {
   122  			assert.Equal(t, -int(balance*validatorCount), d, "First root should have negative delta")
   123  		} else if i == int(lastIndex) {
   124  			assert.Equal(t, int(balance*validatorCount), d, "Last root should have positive delta")
   125  		} else {
   126  			assert.Equal(t, 0, d)
   127  		}
   128  	}
   129  
   130  	for _, vote := range votes {
   131  		assert.Equal(t, vote.currentRoot, vote.nextRoot, "The vote should not have changed")
   132  	}
   133  }
   134  
   135  func TestComputeDelta_MoveOutOfTree(t *testing.T) {
   136  	balance := uint64(32)
   137  	indices := make(map[[32]byte]uint64)
   138  	votes := make([]Vote, 0)
   139  	oldBalances := []uint64{balance, balance}
   140  	newBalances := []uint64{balance, balance}
   141  
   142  	indices[indexToHash(1)] = 0
   143  
   144  	votes = append(votes,
   145  		Vote{indexToHash(1), params.BeaconConfig().ZeroHash, 0},
   146  		Vote{indexToHash(1), [32]byte{'A'}, 0})
   147  
   148  	delta, _, err := computeDeltas(context.Background(), indices, votes, oldBalances, newBalances)
   149  	require.NoError(t, err)
   150  	assert.Equal(t, 1, len(delta))
   151  	assert.Equal(t, 0-2*int(balance), delta[0])
   152  
   153  	for _, vote := range votes {
   154  		assert.Equal(t, vote.currentRoot, vote.nextRoot, "The vote should not have changed")
   155  	}
   156  }
   157  
   158  func TestComputeDelta_ChangingBalances(t *testing.T) {
   159  	oldBalance := uint64(32)
   160  	newBalance := oldBalance * 2
   161  	validatorCount := uint64(16)
   162  	indices := make(map[[32]byte]uint64)
   163  	votes := make([]Vote, 0)
   164  	oldBalances := make([]uint64, 0)
   165  	newBalances := make([]uint64, 0)
   166  
   167  	indices[indexToHash(1)] = 0
   168  
   169  	for i := uint64(0); i < validatorCount; i++ {
   170  		indices[indexToHash(i)] = i
   171  		votes = append(votes, Vote{indexToHash(0), indexToHash(1), 0})
   172  		oldBalances = append(oldBalances, oldBalance)
   173  		newBalances = append(newBalances, newBalance)
   174  	}
   175  
   176  	delta, _, err := computeDeltas(context.Background(), indices, votes, oldBalances, newBalances)
   177  	require.NoError(t, err)
   178  	assert.Equal(t, 16, len(delta))
   179  
   180  	for i, d := range delta {
   181  		if i == 0 {
   182  			assert.Equal(t, -int(oldBalance*validatorCount), d, "First root should have negative delta")
   183  		} else if i == 1 {
   184  			assert.Equal(t, int(newBalance*validatorCount), d, "Last root should have positive delta")
   185  		} else {
   186  			assert.Equal(t, 0, d)
   187  		}
   188  	}
   189  
   190  	for _, vote := range votes {
   191  		assert.Equal(t, vote.currentRoot, vote.nextRoot, "The vote should not have changed")
   192  	}
   193  }
   194  
   195  func TestComputeDelta_ValidatorAppear(t *testing.T) {
   196  	balance := uint64(32)
   197  	indices := make(map[[32]byte]uint64)
   198  	votes := make([]Vote, 0)
   199  	oldBalances := []uint64{balance}
   200  	newBalances := []uint64{balance, balance}
   201  
   202  	indices[indexToHash(1)] = 0
   203  	indices[indexToHash(2)] = 1
   204  
   205  	votes = append(votes,
   206  		Vote{indexToHash(1), indexToHash(2), 0},
   207  		Vote{indexToHash(1), indexToHash(2), 0})
   208  
   209  	delta, _, err := computeDeltas(context.Background(), indices, votes, oldBalances, newBalances)
   210  	require.NoError(t, err)
   211  	assert.Equal(t, 2, len(delta))
   212  	assert.Equal(t, 0-int(balance), delta[0])
   213  	assert.Equal(t, 2*int(balance), delta[1])
   214  
   215  	for _, vote := range votes {
   216  		assert.Equal(t, vote.currentRoot, vote.nextRoot, "The vote should not have changed")
   217  	}
   218  }
   219  
   220  func TestComputeDelta_ValidatorDisappears(t *testing.T) {
   221  	balance := uint64(32)
   222  	indices := make(map[[32]byte]uint64)
   223  	votes := make([]Vote, 0)
   224  	oldBalances := []uint64{balance, balance}
   225  	newBalances := []uint64{balance}
   226  
   227  	indices[indexToHash(1)] = 0
   228  	indices[indexToHash(2)] = 1
   229  
   230  	votes = append(votes,
   231  		Vote{indexToHash(1), indexToHash(2), 0},
   232  		Vote{indexToHash(1), indexToHash(2), 0})
   233  
   234  	delta, _, err := computeDeltas(context.Background(), indices, votes, oldBalances, newBalances)
   235  	require.NoError(t, err)
   236  	assert.Equal(t, 2, len(delta))
   237  	assert.Equal(t, 0-2*int(balance), delta[0])
   238  	assert.Equal(t, int(balance), delta[1])
   239  
   240  	for _, vote := range votes {
   241  		assert.Equal(t, vote.currentRoot, vote.nextRoot, "The vote should not have changed")
   242  	}
   243  }
   244  
   245  func indexToHash(i uint64) [32]byte {
   246  	var b [8]byte
   247  	binary.LittleEndian.PutUint64(b[:], i)
   248  	return hashutil.Hash(b[:])
   249  }