github.com/prysmaticlabs/prysm@v1.4.4/beacon-chain/state/v1/getters_test.go (about)

     1  package v1
     2  
     3  import (
     4  	"runtime/debug"
     5  	"sync"
     6  	"testing"
     7  
     8  	types "github.com/prysmaticlabs/eth2-types"
     9  	pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
    10  	eth "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
    11  	"github.com/prysmaticlabs/prysm/shared/testutil/assert"
    12  	"github.com/prysmaticlabs/prysm/shared/testutil/require"
    13  )
    14  
    15  func TestBeaconState_SlotDataRace(t *testing.T) {
    16  	headState, err := InitializeFromProto(&pb.BeaconState{Slot: 1})
    17  	require.NoError(t, err)
    18  
    19  	wg := sync.WaitGroup{}
    20  	wg.Add(2)
    21  	go func() {
    22  		require.NoError(t, headState.SetSlot(0))
    23  		wg.Done()
    24  	}()
    25  	go func() {
    26  		headState.Slot()
    27  		wg.Done()
    28  	}()
    29  
    30  	wg.Wait()
    31  }
    32  
    33  func TestNilState_NoPanic(t *testing.T) {
    34  	var st *BeaconState
    35  	defer func() {
    36  		if r := recover(); r != nil {
    37  			t.Errorf("Method panicked when it was not supposed to: %v\n%v\n", r, string(debug.Stack()))
    38  		}
    39  	}()
    40  	// retrieve elements from nil state
    41  	_ = st.GenesisTime()
    42  	_ = st.GenesisValidatorRoot()
    43  	_ = st.GenesisValidatorRoot()
    44  	_ = st.Slot()
    45  	_ = st.Fork()
    46  	_ = st.LatestBlockHeader()
    47  	_ = st.BlockRoots()
    48  	_, err := st.BlockRootAtIndex(0)
    49  	_ = err
    50  	_ = st.StateRoots()
    51  	_ = st.HistoricalRoots()
    52  	_ = st.Eth1Data()
    53  	_ = st.Eth1DataVotes()
    54  	_ = st.Eth1DepositIndex()
    55  	_, err = st.ValidatorAtIndex(0)
    56  	_ = err
    57  	_, err = st.ValidatorAtIndexReadOnly(0)
    58  	_ = err
    59  	_, _ = st.ValidatorIndexByPubkey([48]byte{})
    60  	_ = st.PubkeyAtIndex(0)
    61  	_ = st.NumValidators()
    62  	_ = st.Balances()
    63  	_, err = st.BalanceAtIndex(0)
    64  	_ = err
    65  	_ = st.BalancesLength()
    66  	_ = st.RandaoMixes()
    67  	_, err = st.RandaoMixAtIndex(0)
    68  	_ = err
    69  	_ = st.RandaoMixesLength()
    70  	_ = st.Slashings()
    71  	_, err = st.PreviousEpochAttestations()
    72  	require.NoError(t, err)
    73  	_, err = st.CurrentEpochAttestations()
    74  	require.NoError(t, err)
    75  	_ = st.JustificationBits()
    76  	_ = st.PreviousJustifiedCheckpoint()
    77  	_ = st.CurrentJustifiedCheckpoint()
    78  	_ = st.FinalizedCheckpoint()
    79  }
    80  
    81  func TestReadOnlyValidator_NoPanic(t *testing.T) {
    82  	v := &ReadOnlyValidator{}
    83  	assert.Equal(t, false, v.Slashed(), "Expected not slashed")
    84  }
    85  
    86  func TestReadOnlyValidator_ActivationEligibilityEpochNoPanic(t *testing.T) {
    87  	v := &ReadOnlyValidator{}
    88  	assert.Equal(t, types.Epoch(0), v.ActivationEligibilityEpoch(), "Expected 0 and not panic")
    89  }
    90  
    91  func TestBeaconState_MatchCurrentJustifiedCheckpt(t *testing.T) {
    92  	c1 := &eth.Checkpoint{Epoch: 1}
    93  	c2 := &eth.Checkpoint{Epoch: 2}
    94  	beaconState, err := InitializeFromProto(&pb.BeaconState{CurrentJustifiedCheckpoint: c1})
    95  	require.NoError(t, err)
    96  	require.Equal(t, true, beaconState.MatchCurrentJustifiedCheckpoint(c1))
    97  	require.Equal(t, false, beaconState.MatchCurrentJustifiedCheckpoint(c2))
    98  	require.Equal(t, false, beaconState.MatchPreviousJustifiedCheckpoint(c1))
    99  	require.Equal(t, false, beaconState.MatchPreviousJustifiedCheckpoint(c2))
   100  	beaconState.state = nil
   101  	require.Equal(t, false, beaconState.MatchCurrentJustifiedCheckpoint(c1))
   102  }
   103  
   104  func TestBeaconState_MatchPreviousJustifiedCheckpt(t *testing.T) {
   105  	c1 := &eth.Checkpoint{Epoch: 1}
   106  	c2 := &eth.Checkpoint{Epoch: 2}
   107  	beaconState, err := InitializeFromProto(&pb.BeaconState{PreviousJustifiedCheckpoint: c1})
   108  	require.NoError(t, err)
   109  	require.NoError(t, err)
   110  	require.Equal(t, false, beaconState.MatchCurrentJustifiedCheckpoint(c1))
   111  	require.Equal(t, false, beaconState.MatchCurrentJustifiedCheckpoint(c2))
   112  	require.Equal(t, true, beaconState.MatchPreviousJustifiedCheckpoint(c1))
   113  	require.Equal(t, false, beaconState.MatchPreviousJustifiedCheckpoint(c2))
   114  	beaconState.state = nil
   115  	require.Equal(t, false, beaconState.MatchPreviousJustifiedCheckpoint(c1))
   116  }
   117  
   118  func TestBeaconState_MarshalSSZ_NilState(t *testing.T) {
   119  	s, err := InitializeFromProto(&pb.BeaconState{})
   120  	require.NoError(t, err)
   121  	s.state = nil
   122  	_, err = s.MarshalSSZ()
   123  	require.ErrorContains(t, "nil beacon state", err)
   124  }
   125  
   126  func TestBeaconState_ValidatorByPubkey(t *testing.T) {
   127  	keyCreator := func(input []byte) [48]byte {
   128  		nKey := [48]byte{}
   129  		copy(nKey[:1], input)
   130  		return nKey
   131  	}
   132  
   133  	tests := []struct {
   134  		name            string
   135  		modifyFunc      func(b *BeaconState, k [48]byte)
   136  		exists          bool
   137  		expectedIdx     types.ValidatorIndex
   138  		largestIdxInSet types.ValidatorIndex
   139  	}{
   140  		{
   141  			name: "retrieve validator",
   142  			modifyFunc: func(b *BeaconState, key [48]byte) {
   143  				assert.NoError(t, b.AppendValidator(&eth.Validator{PublicKey: key[:]}))
   144  			},
   145  			exists:      true,
   146  			expectedIdx: 0,
   147  		},
   148  		{
   149  			name: "retrieve validator with multiple validators from the start",
   150  			modifyFunc: func(b *BeaconState, key [48]byte) {
   151  				key1 := keyCreator([]byte{'C'})
   152  				key2 := keyCreator([]byte{'D'})
   153  				assert.NoError(t, b.AppendValidator(&eth.Validator{PublicKey: key[:]}))
   154  				assert.NoError(t, b.AppendValidator(&eth.Validator{PublicKey: key1[:]}))
   155  				assert.NoError(t, b.AppendValidator(&eth.Validator{PublicKey: key2[:]}))
   156  			},
   157  			exists:      true,
   158  			expectedIdx: 0,
   159  		},
   160  		{
   161  			name: "retrieve validator with multiple validators",
   162  			modifyFunc: func(b *BeaconState, key [48]byte) {
   163  				key1 := keyCreator([]byte{'C'})
   164  				key2 := keyCreator([]byte{'D'})
   165  				assert.NoError(t, b.AppendValidator(&eth.Validator{PublicKey: key1[:]}))
   166  				assert.NoError(t, b.AppendValidator(&eth.Validator{PublicKey: key2[:]}))
   167  				assert.NoError(t, b.AppendValidator(&eth.Validator{PublicKey: key[:]}))
   168  			},
   169  			exists:      true,
   170  			expectedIdx: 2,
   171  		},
   172  		{
   173  			name: "retrieve validator with multiple validators from the start with shared state",
   174  			modifyFunc: func(b *BeaconState, key [48]byte) {
   175  				key1 := keyCreator([]byte{'C'})
   176  				key2 := keyCreator([]byte{'D'})
   177  				assert.NoError(t, b.AppendValidator(&eth.Validator{PublicKey: key[:]}))
   178  				_ = b.Copy()
   179  				assert.NoError(t, b.AppendValidator(&eth.Validator{PublicKey: key1[:]}))
   180  				assert.NoError(t, b.AppendValidator(&eth.Validator{PublicKey: key2[:]}))
   181  			},
   182  			exists:      true,
   183  			expectedIdx: 0,
   184  		},
   185  		{
   186  			name: "retrieve validator with multiple validators with shared state",
   187  			modifyFunc: func(b *BeaconState, key [48]byte) {
   188  				key1 := keyCreator([]byte{'C'})
   189  				key2 := keyCreator([]byte{'D'})
   190  				assert.NoError(t, b.AppendValidator(&eth.Validator{PublicKey: key1[:]}))
   191  				assert.NoError(t, b.AppendValidator(&eth.Validator{PublicKey: key2[:]}))
   192  				n := b.Copy()
   193  				// Append to another state
   194  				assert.NoError(t, n.AppendValidator(&eth.Validator{PublicKey: key[:]}))
   195  
   196  			},
   197  			exists:      false,
   198  			expectedIdx: 0,
   199  		},
   200  		{
   201  			name: "retrieve validator with multiple validators with shared state at boundary",
   202  			modifyFunc: func(b *BeaconState, key [48]byte) {
   203  				key1 := keyCreator([]byte{'C'})
   204  				assert.NoError(t, b.AppendValidator(&eth.Validator{PublicKey: key1[:]}))
   205  				n := b.Copy()
   206  				// Append to another state
   207  				assert.NoError(t, n.AppendValidator(&eth.Validator{PublicKey: key[:]}))
   208  
   209  			},
   210  			exists:      false,
   211  			expectedIdx: 0,
   212  		},
   213  	}
   214  
   215  	for _, tt := range tests {
   216  		t.Run(tt.name, func(t *testing.T) {
   217  			s, err := InitializeFromProto(&pb.BeaconState{})
   218  			require.NoError(t, err)
   219  			nKey := keyCreator([]byte{'A'})
   220  			tt.modifyFunc(s, nKey)
   221  			idx, ok := s.ValidatorIndexByPubkey(nKey)
   222  			assert.Equal(t, tt.exists, ok)
   223  			assert.Equal(t, tt.expectedIdx, idx)
   224  		})
   225  	}
   226  }