package v1 import ( "strconv" "sync" "testing" "github.com/prysmaticlabs/prysm/beacon-chain/state/stateutil" "github.com/prysmaticlabs/prysm/config/params" "github.com/prysmaticlabs/prysm/encoding/bytesutil" ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1" "github.com/prysmaticlabs/prysm/shared/testutil/assert" ) func TestValidatorMap_DistinctCopy(t *testing.T) { count := uint64(100) vals := make([]*ethpb.Validator, 0, count) for i := uint64(1); i < count; i++ { someRoot := [32]byte{} someKey := [48]byte{} copy(someRoot[:], strconv.Itoa(int(i))) copy(someKey[:], strconv.Itoa(int(i))) vals = append(vals, ðpb.Validator{ PublicKey: someKey[:], WithdrawalCredentials: someRoot[:], EffectiveBalance: params.BeaconConfig().MaxEffectiveBalance, Slashed: false, ActivationEligibilityEpoch: 1, ActivationEpoch: 1, ExitEpoch: 1, WithdrawableEpoch: 1, }) } handler := stateutil.NewValMapHandler(vals) newHandler := handler.Copy() wantedPubkey := strconv.Itoa(22) handler.Set(bytesutil.ToBytes48([]byte(wantedPubkey)), 27) val1, _ := handler.Get(bytesutil.ToBytes48([]byte(wantedPubkey))) val2, _ := newHandler.Get(bytesutil.ToBytes48([]byte(wantedPubkey))) assert.NotEqual(t, val1, val2, "Values are supposed to be unequal due to copy") } func TestBeaconState_NoDeadlock(t *testing.T) { count := uint64(100) vals := make([]*ethpb.Validator, 0, count) for i := uint64(1); i < count; i++ { someRoot := [32]byte{} someKey := [48]byte{} copy(someRoot[:], strconv.Itoa(int(i))) copy(someKey[:], strconv.Itoa(int(i))) vals = append(vals, ðpb.Validator{ PublicKey: someKey[:], WithdrawalCredentials: someRoot[:], EffectiveBalance: params.BeaconConfig().MaxEffectiveBalance, Slashed: false, ActivationEligibilityEpoch: 1, ActivationEpoch: 1, ExitEpoch: 1, WithdrawableEpoch: 1, }) } st, err := InitializeFromProtoUnsafe(ðpb.BeaconState{ Validators: vals, }) assert.NoError(t, err) wg := new(sync.WaitGroup) wg.Add(1) go func() { // Continuously lock and unlock the state // by acquiring the lock. for i := 0; i < 1000; i++ { for _, f := range st.stateFieldLeaves { f.Lock() if f.Empty() { f.InsertFieldLayer(make([][]*[32]byte, 10)) } f.Unlock() f.FieldReference().AddRef() } } wg.Done() }() // Constantly read from the offending portion // of the code to ensure there is no possible // recursive read locking. for i := 0; i < 1000; i++ { go func() { _ = st.FieldReferencesCount() }() } // Test will not terminate in the event of a deadlock. wg.Wait() } func TestStateTrie_IsNil(t *testing.T) { var emptyState *BeaconState assert.Equal(t, true, emptyState.IsNil()) emptyProto := &BeaconState{state: nil} assert.Equal(t, true, emptyProto.IsNil()) nonNilState := &BeaconState{state: ðpb.BeaconState{}} assert.Equal(t, false, nonNilState.IsNil()) }