github.com/prysmaticlabs/prysm@v1.4.4/beacon-chain/core/blocks/attester_slashing_test.go (about) 1 package blocks_test 2 3 import ( 4 "context" 5 "testing" 6 7 types "github.com/prysmaticlabs/eth2-types" 8 "github.com/prysmaticlabs/prysm/beacon-chain/core/blocks" 9 "github.com/prysmaticlabs/prysm/beacon-chain/core/helpers" 10 v "github.com/prysmaticlabs/prysm/beacon-chain/core/validators" 11 "github.com/prysmaticlabs/prysm/beacon-chain/state/v1" 12 pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1" 13 ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1" 14 "github.com/prysmaticlabs/prysm/shared/bls" 15 "github.com/prysmaticlabs/prysm/shared/bytesutil" 16 "github.com/prysmaticlabs/prysm/shared/params" 17 "github.com/prysmaticlabs/prysm/shared/testutil" 18 "github.com/prysmaticlabs/prysm/shared/testutil/assert" 19 "github.com/prysmaticlabs/prysm/shared/testutil/require" 20 ) 21 22 func TestSlashableAttestationData_CanSlash(t *testing.T) { 23 att1 := testutil.HydrateAttestationData(ðpb.AttestationData{ 24 Target: ðpb.Checkpoint{Epoch: 1, Root: make([]byte, 32)}, 25 Source: ðpb.Checkpoint{Root: bytesutil.PadTo([]byte{'A'}, 32)}, 26 }) 27 att2 := testutil.HydrateAttestationData(ðpb.AttestationData{ 28 Target: ðpb.Checkpoint{Epoch: 1, Root: make([]byte, 32)}, 29 Source: ðpb.Checkpoint{Root: bytesutil.PadTo([]byte{'B'}, 32)}, 30 }) 31 assert.Equal(t, true, blocks.IsSlashableAttestationData(att1, att2), "Atts should have been slashable") 32 att1.Target.Epoch = 4 33 att1.Source.Epoch = 2 34 att2.Source.Epoch = 3 35 assert.Equal(t, true, blocks.IsSlashableAttestationData(att1, att2), "Atts should have been slashable") 36 } 37 38 func TestProcessAttesterSlashings_DataNotSlashable(t *testing.T) { 39 slashings := []*ethpb.AttesterSlashing{{ 40 Attestation_1: testutil.HydrateIndexedAttestation(ðpb.IndexedAttestation{}), 41 Attestation_2: testutil.HydrateIndexedAttestation(ðpb.IndexedAttestation{ 42 Data: ðpb.AttestationData{ 43 Source: ðpb.Checkpoint{Epoch: 1}, 44 Target: ðpb.Checkpoint{Epoch: 1}}, 45 })}} 46 47 var registry []*ethpb.Validator 48 currentSlot := types.Slot(0) 49 50 beaconState, err := v1.InitializeFromProto(&pb.BeaconState{ 51 Validators: registry, 52 Slot: currentSlot, 53 }) 54 require.NoError(t, err) 55 b := testutil.NewBeaconBlock() 56 b.Block = ðpb.BeaconBlock{ 57 Body: ðpb.BeaconBlockBody{ 58 AttesterSlashings: slashings, 59 }, 60 } 61 _, err = blocks.ProcessAttesterSlashings(context.Background(), beaconState, b.Block.Body.AttesterSlashings, v.SlashValidator) 62 assert.ErrorContains(t, "attestations are not slashable", err) 63 } 64 65 func TestProcessAttesterSlashings_IndexedAttestationFailedToVerify(t *testing.T) { 66 var registry []*ethpb.Validator 67 currentSlot := types.Slot(0) 68 69 beaconState, err := v1.InitializeFromProto(&pb.BeaconState{ 70 Validators: registry, 71 Slot: currentSlot, 72 }) 73 require.NoError(t, err) 74 75 slashings := []*ethpb.AttesterSlashing{ 76 { 77 Attestation_1: testutil.HydrateIndexedAttestation(ðpb.IndexedAttestation{ 78 Data: ðpb.AttestationData{ 79 Source: ðpb.Checkpoint{Epoch: 1}, 80 }, 81 AttestingIndices: make([]uint64, params.BeaconConfig().MaxValidatorsPerCommittee+1), 82 }), 83 Attestation_2: testutil.HydrateIndexedAttestation(ðpb.IndexedAttestation{ 84 AttestingIndices: make([]uint64, params.BeaconConfig().MaxValidatorsPerCommittee+1), 85 }), 86 }, 87 } 88 89 b := testutil.NewBeaconBlock() 90 b.Block = ðpb.BeaconBlock{ 91 Body: ðpb.BeaconBlockBody{ 92 AttesterSlashings: slashings, 93 }, 94 } 95 96 _, err = blocks.ProcessAttesterSlashings(context.Background(), beaconState, b.Block.Body.AttesterSlashings, v.SlashValidator) 97 assert.ErrorContains(t, "validator indices count exceeds MAX_VALIDATORS_PER_COMMITTEE", err) 98 } 99 100 func TestProcessAttesterSlashings_AppliesCorrectStatus(t *testing.T) { 101 beaconState, privKeys := testutil.DeterministicGenesisState(t, 100) 102 for _, vv := range beaconState.Validators() { 103 vv.WithdrawableEpoch = types.Epoch(params.BeaconConfig().SlotsPerEpoch) 104 } 105 106 att1 := testutil.HydrateIndexedAttestation(ðpb.IndexedAttestation{ 107 Data: ðpb.AttestationData{ 108 Source: ðpb.Checkpoint{Epoch: 1}, 109 }, 110 AttestingIndices: []uint64{0, 1}, 111 }) 112 domain, err := helpers.Domain(beaconState.Fork(), 0, params.BeaconConfig().DomainBeaconAttester, beaconState.GenesisValidatorRoot()) 113 require.NoError(t, err) 114 signingRoot, err := helpers.ComputeSigningRoot(att1.Data, domain) 115 assert.NoError(t, err, "Could not get signing root of beacon block header") 116 sig0 := privKeys[0].Sign(signingRoot[:]) 117 sig1 := privKeys[1].Sign(signingRoot[:]) 118 aggregateSig := bls.AggregateSignatures([]bls.Signature{sig0, sig1}) 119 att1.Signature = aggregateSig.Marshal() 120 121 att2 := testutil.HydrateIndexedAttestation(ðpb.IndexedAttestation{ 122 AttestingIndices: []uint64{0, 1}, 123 }) 124 signingRoot, err = helpers.ComputeSigningRoot(att2.Data, domain) 125 assert.NoError(t, err, "Could not get signing root of beacon block header") 126 sig0 = privKeys[0].Sign(signingRoot[:]) 127 sig1 = privKeys[1].Sign(signingRoot[:]) 128 aggregateSig = bls.AggregateSignatures([]bls.Signature{sig0, sig1}) 129 att2.Signature = aggregateSig.Marshal() 130 131 slashings := []*ethpb.AttesterSlashing{ 132 { 133 Attestation_1: att1, 134 Attestation_2: att2, 135 }, 136 } 137 138 currentSlot := 2 * params.BeaconConfig().SlotsPerEpoch 139 require.NoError(t, beaconState.SetSlot(currentSlot)) 140 141 b := testutil.NewBeaconBlock() 142 b.Block = ðpb.BeaconBlock{ 143 Body: ðpb.BeaconBlockBody{ 144 AttesterSlashings: slashings, 145 }, 146 } 147 148 newState, err := blocks.ProcessAttesterSlashings(context.Background(), beaconState, b.Block.Body.AttesterSlashings, v.SlashValidator) 149 require.NoError(t, err) 150 newRegistry := newState.Validators() 151 152 // Given the intersection of slashable indices is [1], only validator 153 // at index 1 should be slashed and exited. We confirm this below. 154 if newRegistry[1].ExitEpoch != beaconState.Validators()[1].ExitEpoch { 155 t.Errorf( 156 ` 157 Expected validator at index 1's exit epoch to match 158 %d, received %d instead 159 `, 160 beaconState.Validators()[1].ExitEpoch, 161 newRegistry[1].ExitEpoch, 162 ) 163 } 164 }