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 := ðpb.Attestation{Data: ðpb.AttestationData{ 77 Target: ðpb.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 := ðpb.Attestation{Data: ðpb.AttestationData{ 97 Target: ðpb.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 := ðpb.Attestation{Data: ðpb.AttestationData{ 117 Target: ðpb.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 := ðpb.Attestation{Data: ðpb.AttestationData{ 135 Target: ðpb.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 := ðpb.Attestation{Data: ðpb.AttestationData{ 159 Target: ðpb.Checkpoint{Epoch: 0}}, 160 AggregationBits: bf} 161 att2 := ðpb.Attestation{Data: ðpb.AttestationData{ 162 Target: ðpb.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 }