github.com/prysmaticlabs/prysm@v1.4.4/beacon-chain/core/epoch/precompute/attestation_test.go (about)

     1  package precompute_test
     2  
     3  import (
     4  	"context"
     5  	"testing"
     6  
     7  	"github.com/prysmaticlabs/go-bitfield"
     8  	"github.com/prysmaticlabs/prysm/beacon-chain/core/epoch/precompute"
     9  	"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
    10  	pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
    11  	ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
    12  	"github.com/prysmaticlabs/prysm/shared/attestationutil"
    13  	"github.com/prysmaticlabs/prysm/shared/params"
    14  	"github.com/prysmaticlabs/prysm/shared/testutil"
    15  	"github.com/prysmaticlabs/prysm/shared/testutil/assert"
    16  	"github.com/prysmaticlabs/prysm/shared/testutil/require"
    17  )
    18  
    19  func TestUpdateValidator_Works(t *testing.T) {
    20  	e := params.BeaconConfig().FarFutureSlot
    21  	vp := []*precompute.Validator{{}, {InclusionSlot: e}, {}, {InclusionSlot: e}, {}, {InclusionSlot: e}}
    22  	record := &precompute.Validator{IsCurrentEpochAttester: true, IsCurrentEpochTargetAttester: true,
    23  		IsPrevEpochAttester: true, IsPrevEpochTargetAttester: true, IsPrevEpochHeadAttester: true}
    24  	a := &pb.PendingAttestation{InclusionDelay: 1, ProposerIndex: 2}
    25  
    26  	// Indices 1 3 and 5 attested
    27  	vp = precompute.UpdateValidator(vp, record, []uint64{1, 3, 5}, a, 100)
    28  
    29  	wanted := &precompute.Validator{IsCurrentEpochAttester: true, IsCurrentEpochTargetAttester: true,
    30  		IsPrevEpochAttester: true, IsPrevEpochTargetAttester: true, IsPrevEpochHeadAttester: true,
    31  		ProposerIndex: 2, InclusionDistance: 1, InclusionSlot: 101}
    32  	wantedVp := []*precompute.Validator{{}, wanted, {}, wanted, {}, wanted}
    33  	assert.DeepEqual(t, wantedVp, vp, "Incorrect attesting validator calculations")
    34  }
    35  
    36  func TestUpdateValidator_InclusionOnlyCountsPrevEpoch(t *testing.T) {
    37  	e := params.BeaconConfig().FarFutureSlot
    38  	vp := []*precompute.Validator{{InclusionSlot: e}}
    39  	record := &precompute.Validator{IsCurrentEpochAttester: true, IsCurrentEpochTargetAttester: true}
    40  	a := &pb.PendingAttestation{InclusionDelay: 1, ProposerIndex: 2}
    41  
    42  	// Verify inclusion info doesnt get updated.
    43  	vp = precompute.UpdateValidator(vp, record, []uint64{0}, a, 100)
    44  	wanted := &precompute.Validator{IsCurrentEpochAttester: true, IsCurrentEpochTargetAttester: true, InclusionSlot: e}
    45  	wantedVp := []*precompute.Validator{wanted}
    46  	assert.DeepEqual(t, wantedVp, vp, "Incorrect attesting validator calculations")
    47  }
    48  
    49  func TestUpdateBalance(t *testing.T) {
    50  	vp := []*precompute.Validator{
    51  		{IsCurrentEpochAttester: true, CurrentEpochEffectiveBalance: 100 * params.BeaconConfig().EffectiveBalanceIncrement},
    52  		{IsCurrentEpochTargetAttester: true, IsCurrentEpochAttester: true, CurrentEpochEffectiveBalance: 100 * params.BeaconConfig().EffectiveBalanceIncrement},
    53  		{IsCurrentEpochTargetAttester: true, CurrentEpochEffectiveBalance: 100 * params.BeaconConfig().EffectiveBalanceIncrement},
    54  		{IsPrevEpochAttester: true, CurrentEpochEffectiveBalance: 100 * params.BeaconConfig().EffectiveBalanceIncrement},
    55  		{IsPrevEpochAttester: true, IsPrevEpochTargetAttester: true, CurrentEpochEffectiveBalance: 100 * params.BeaconConfig().EffectiveBalanceIncrement},
    56  		{IsPrevEpochHeadAttester: true, CurrentEpochEffectiveBalance: 100 * params.BeaconConfig().EffectiveBalanceIncrement},
    57  		{IsPrevEpochAttester: true, IsPrevEpochHeadAttester: true, CurrentEpochEffectiveBalance: 100 * params.BeaconConfig().EffectiveBalanceIncrement},
    58  		{IsSlashed: true, IsCurrentEpochAttester: true, CurrentEpochEffectiveBalance: 100 * params.BeaconConfig().EffectiveBalanceIncrement},
    59  	}
    60  	wantedPBal := &precompute.Balance{
    61  		ActiveCurrentEpoch:         params.BeaconConfig().EffectiveBalanceIncrement,
    62  		ActivePrevEpoch:            params.BeaconConfig().EffectiveBalanceIncrement,
    63  		CurrentEpochAttested:       200 * params.BeaconConfig().EffectiveBalanceIncrement,
    64  		CurrentEpochTargetAttested: 200 * params.BeaconConfig().EffectiveBalanceIncrement,
    65  		PrevEpochAttested:          300 * params.BeaconConfig().EffectiveBalanceIncrement,
    66  		PrevEpochTargetAttested:    100 * params.BeaconConfig().EffectiveBalanceIncrement,
    67  		PrevEpochHeadAttested:      200 * params.BeaconConfig().EffectiveBalanceIncrement,
    68  	}
    69  	pBal := precompute.UpdateBalance(vp, &precompute.Balance{})
    70  	assert.DeepEqual(t, wantedPBal, pBal, "Incorrect balance calculations")
    71  }
    72  
    73  func TestSameHead(t *testing.T) {
    74  	beaconState, _ := testutil.DeterministicGenesisState(t, 100)
    75  	require.NoError(t, beaconState.SetSlot(1))
    76  	att := &ethpb.Attestation{Data: &ethpb.AttestationData{
    77  		Target: &ethpb.Checkpoint{Epoch: 0}}}
    78  	r := [32]byte{'A'}
    79  	br := beaconState.BlockRoots()
    80  	br[0] = r[:]
    81  	require.NoError(t, beaconState.SetBlockRoots(br))
    82  	att.Data.BeaconBlockRoot = r[:]
    83  	same, err := precompute.SameHead(beaconState, &pb.PendingAttestation{Data: att.Data})
    84  	require.NoError(t, err)
    85  	assert.Equal(t, true, same, "Head in state does not match head in attestation")
    86  	newRoot := [32]byte{'B'}
    87  	att.Data.BeaconBlockRoot = newRoot[:]
    88  	same, err = precompute.SameHead(beaconState, &pb.PendingAttestation{Data: att.Data})
    89  	require.NoError(t, err)
    90  	assert.Equal(t, false, same, "Head in state matches head in attestation")
    91  }
    92  
    93  func TestSameTarget(t *testing.T) {
    94  	beaconState, _ := testutil.DeterministicGenesisState(t, 100)
    95  	require.NoError(t, beaconState.SetSlot(1))
    96  	att := &ethpb.Attestation{Data: &ethpb.AttestationData{
    97  		Target: &ethpb.Checkpoint{Epoch: 0}}}
    98  	r := [32]byte{'A'}
    99  	br := beaconState.BlockRoots()
   100  	br[0] = r[:]
   101  	require.NoError(t, beaconState.SetBlockRoots(br))
   102  	att.Data.Target.Root = r[:]
   103  	same, err := precompute.SameTarget(beaconState, &pb.PendingAttestation{Data: att.Data}, 0)
   104  	require.NoError(t, err)
   105  	assert.Equal(t, true, same, "Head in state does not match head in attestation")
   106  	newRoot := [32]byte{'B'}
   107  	att.Data.Target.Root = newRoot[:]
   108  	same, err = precompute.SameTarget(beaconState, &pb.PendingAttestation{Data: att.Data}, 0)
   109  	require.NoError(t, err)
   110  	assert.Equal(t, false, same, "Head in state matches head in attestation")
   111  }
   112  
   113  func TestAttestedPrevEpoch(t *testing.T) {
   114  	beaconState, _ := testutil.DeterministicGenesisState(t, 100)
   115  	require.NoError(t, beaconState.SetSlot(params.BeaconConfig().SlotsPerEpoch))
   116  	att := &ethpb.Attestation{Data: &ethpb.AttestationData{
   117  		Target: &ethpb.Checkpoint{Epoch: 0}}}
   118  	r := [32]byte{'A'}
   119  	br := beaconState.BlockRoots()
   120  	br[0] = r[:]
   121  	require.NoError(t, beaconState.SetBlockRoots(br))
   122  	att.Data.Target.Root = r[:]
   123  	att.Data.BeaconBlockRoot = r[:]
   124  	votedEpoch, votedTarget, votedHead, err := precompute.AttestedPrevEpoch(beaconState, &pb.PendingAttestation{Data: att.Data})
   125  	require.NoError(t, err)
   126  	assert.Equal(t, true, votedEpoch, "Did not vote epoch")
   127  	assert.Equal(t, true, votedTarget, "Did not vote target")
   128  	assert.Equal(t, true, votedHead, "Did not vote head")
   129  }
   130  
   131  func TestAttestedCurrentEpoch(t *testing.T) {
   132  	beaconState, _ := testutil.DeterministicGenesisState(t, 100)
   133  	require.NoError(t, beaconState.SetSlot(params.BeaconConfig().SlotsPerEpoch+1))
   134  	att := &ethpb.Attestation{Data: &ethpb.AttestationData{
   135  		Target: &ethpb.Checkpoint{Epoch: 1}}}
   136  	r := [32]byte{'A'}
   137  
   138  	br := beaconState.BlockRoots()
   139  	br[params.BeaconConfig().SlotsPerEpoch] = r[:]
   140  	require.NoError(t, beaconState.SetBlockRoots(br))
   141  	att.Data.Target.Root = r[:]
   142  	att.Data.BeaconBlockRoot = r[:]
   143  	votedEpoch, votedTarget, err := precompute.AttestedCurrentEpoch(beaconState, &pb.PendingAttestation{Data: att.Data})
   144  	require.NoError(t, err)
   145  	assert.Equal(t, true, votedEpoch, "Did not vote epoch")
   146  	assert.Equal(t, true, votedTarget, "Did not vote target")
   147  }
   148  
   149  func TestProcessAttestations(t *testing.T) {
   150  	params.UseMinimalConfig()
   151  	defer params.UseMainnetConfig()
   152  
   153  	validators := uint64(128)
   154  	beaconState, _ := testutil.DeterministicGenesisState(t, validators)
   155  	require.NoError(t, beaconState.SetSlot(params.BeaconConfig().SlotsPerEpoch))
   156  	c := helpers.SlotCommitteeCount(validators)
   157  	bf := bitfield.NewBitlist(c)
   158  	att1 := &ethpb.Attestation{Data: &ethpb.AttestationData{
   159  		Target: &ethpb.Checkpoint{Epoch: 0}},
   160  		AggregationBits: bf}
   161  	att2 := &ethpb.Attestation{Data: &ethpb.AttestationData{
   162  		Target: &ethpb.Checkpoint{Epoch: 0}},
   163  		AggregationBits: bf}
   164  	rt := [32]byte{'A'}
   165  	att1.Data.Target.Root = rt[:]
   166  	att1.Data.BeaconBlockRoot = rt[:]
   167  	br := beaconState.BlockRoots()
   168  	newRt := [32]byte{'B'}
   169  	br[0] = newRt[:]
   170  	require.NoError(t, beaconState.SetBlockRoots(br))
   171  	att2.Data.Target.Root = newRt[:]
   172  	att2.Data.BeaconBlockRoot = newRt[:]
   173  	err := beaconState.AppendPreviousEpochAttestations(&pb.PendingAttestation{Data: att1.Data, AggregationBits: bf, InclusionDelay: 1})
   174  	require.NoError(t, err)
   175  	err = beaconState.AppendCurrentEpochAttestations(&pb.PendingAttestation{Data: att2.Data, AggregationBits: bf, InclusionDelay: 1})
   176  	require.NoError(t, err)
   177  
   178  	pVals := make([]*precompute.Validator, validators)
   179  	for i := 0; i < len(pVals); i++ {
   180  		pVals[i] = &precompute.Validator{CurrentEpochEffectiveBalance: 100}
   181  	}
   182  	pVals, _, err = precompute.ProcessAttestations(context.Background(), beaconState, pVals, &precompute.Balance{})
   183  	require.NoError(t, err)
   184  
   185  	committee, err := helpers.BeaconCommitteeFromState(beaconState, att1.Data.Slot, att1.Data.CommitteeIndex)
   186  	require.NoError(t, err)
   187  	indices, err := attestationutil.AttestingIndices(att1.AggregationBits, committee)
   188  	require.NoError(t, err)
   189  	for _, i := range indices {
   190  		if !pVals[i].IsPrevEpochAttester {
   191  			t.Error("Not a prev epoch attester")
   192  		}
   193  	}
   194  	committee, err = helpers.BeaconCommitteeFromState(beaconState, att2.Data.Slot, att2.Data.CommitteeIndex)
   195  	require.NoError(t, err)
   196  	indices, err = attestationutil.AttestingIndices(att2.AggregationBits, committee)
   197  	require.NoError(t, err)
   198  	for _, i := range indices {
   199  		assert.Equal(t, true, pVals[i].IsPrevEpochAttester, "Not a prev epoch attester")
   200  		assert.Equal(t, true, pVals[i].IsPrevEpochTargetAttester, "Not a prev epoch target attester")
   201  		assert.Equal(t, true, pVals[i].IsPrevEpochHeadAttester, "Not a prev epoch head attester")
   202  	}
   203  }
   204  
   205  func TestEnsureBalancesLowerBound(t *testing.T) {
   206  	b := &precompute.Balance{}
   207  	b = precompute.EnsureBalancesLowerBound(b)
   208  	balanceIncrement := params.BeaconConfig().EffectiveBalanceIncrement
   209  	assert.Equal(t, balanceIncrement, b.ActiveCurrentEpoch, "Did not get wanted active current balance")
   210  	assert.Equal(t, balanceIncrement, b.ActivePrevEpoch, "Did not get wanted active previous balance")
   211  	assert.Equal(t, balanceIncrement, b.CurrentEpochAttested, "Did not get wanted current attested balance")
   212  	assert.Equal(t, balanceIncrement, b.CurrentEpochTargetAttested, "Did not get wanted target attested balance")
   213  	assert.Equal(t, balanceIncrement, b.PrevEpochAttested, "Did not get wanted prev attested balance")
   214  	assert.Equal(t, balanceIncrement, b.PrevEpochTargetAttested, "Did not get wanted prev target attested balance")
   215  	assert.Equal(t, balanceIncrement, b.PrevEpochHeadAttested, "Did not get wanted prev head attested balance")
   216  }