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(&ethpb.AttestationData{
    24  		Target: &ethpb.Checkpoint{Epoch: 1, Root: make([]byte, 32)},
    25  		Source: &ethpb.Checkpoint{Root: bytesutil.PadTo([]byte{'A'}, 32)},
    26  	})
    27  	att2 := testutil.HydrateAttestationData(&ethpb.AttestationData{
    28  		Target: &ethpb.Checkpoint{Epoch: 1, Root: make([]byte, 32)},
    29  		Source: &ethpb.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(&ethpb.IndexedAttestation{}),
    41  		Attestation_2: testutil.HydrateIndexedAttestation(&ethpb.IndexedAttestation{
    42  			Data: &ethpb.AttestationData{
    43  				Source: &ethpb.Checkpoint{Epoch: 1},
    44  				Target: &ethpb.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 = &ethpb.BeaconBlock{
    57  		Body: &ethpb.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(&ethpb.IndexedAttestation{
    78  				Data: &ethpb.AttestationData{
    79  					Source: &ethpb.Checkpoint{Epoch: 1},
    80  				},
    81  				AttestingIndices: make([]uint64, params.BeaconConfig().MaxValidatorsPerCommittee+1),
    82  			}),
    83  			Attestation_2: testutil.HydrateIndexedAttestation(&ethpb.IndexedAttestation{
    84  				AttestingIndices: make([]uint64, params.BeaconConfig().MaxValidatorsPerCommittee+1),
    85  			}),
    86  		},
    87  	}
    88  
    89  	b := testutil.NewBeaconBlock()
    90  	b.Block = &ethpb.BeaconBlock{
    91  		Body: &ethpb.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(&ethpb.IndexedAttestation{
   107  		Data: &ethpb.AttestationData{
   108  			Source: &ethpb.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(&ethpb.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 = &ethpb.BeaconBlock{
   143  		Body: &ethpb.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  }