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 := ð.Checkpoint{Epoch: 1} 93 c2 := ð.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 := ð.Checkpoint{Epoch: 1} 106 c2 := ð.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(ð.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(ð.Validator{PublicKey: key[:]})) 154 assert.NoError(t, b.AppendValidator(ð.Validator{PublicKey: key1[:]})) 155 assert.NoError(t, b.AppendValidator(ð.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(ð.Validator{PublicKey: key1[:]})) 166 assert.NoError(t, b.AppendValidator(ð.Validator{PublicKey: key2[:]})) 167 assert.NoError(t, b.AppendValidator(ð.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(ð.Validator{PublicKey: key[:]})) 178 _ = b.Copy() 179 assert.NoError(t, b.AppendValidator(ð.Validator{PublicKey: key1[:]})) 180 assert.NoError(t, b.AppendValidator(ð.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(ð.Validator{PublicKey: key1[:]})) 191 assert.NoError(t, b.AppendValidator(ð.Validator{PublicKey: key2[:]})) 192 n := b.Copy() 193 // Append to another state 194 assert.NoError(t, n.AppendValidator(ð.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(ð.Validator{PublicKey: key1[:]})) 205 n := b.Copy() 206 // Append to another state 207 assert.NoError(t, n.AppendValidator(ð.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 }