github.com/prysmaticlabs/prysm@v1.4.4/validator/client/attest_protect_test.go (about)

     1  package client
     2  
     3  import (
     4  	"context"
     5  	"testing"
     6  
     7  	"github.com/golang/mock/gomock"
     8  	types "github.com/prysmaticlabs/eth2-types"
     9  	ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
    10  	"github.com/prysmaticlabs/prysm/shared/bytesutil"
    11  	"github.com/prysmaticlabs/prysm/shared/featureconfig"
    12  	"github.com/prysmaticlabs/prysm/shared/testutil/require"
    13  	mockSlasher "github.com/prysmaticlabs/prysm/validator/testing"
    14  )
    15  
    16  func Test_slashableAttestationCheck(t *testing.T) {
    17  	config := &featureconfig.Flags{
    18  		SlasherProtection: true,
    19  	}
    20  	reset := featureconfig.InitWithReset(config)
    21  	defer reset()
    22  	validator, _, validatorKey, finish := setup(t)
    23  	defer finish()
    24  	pubKey := [48]byte{}
    25  	copy(pubKey[:], validatorKey.PublicKey().Marshal())
    26  	att := &ethpb.IndexedAttestation{
    27  		AttestingIndices: []uint64{1, 2},
    28  		Data: &ethpb.AttestationData{
    29  			Slot:            5,
    30  			CommitteeIndex:  2,
    31  			BeaconBlockRoot: bytesutil.PadTo([]byte("great block"), 32),
    32  			Source: &ethpb.Checkpoint{
    33  				Epoch: 4,
    34  				Root:  bytesutil.PadTo([]byte("good source"), 32),
    35  			},
    36  			Target: &ethpb.Checkpoint{
    37  				Epoch: 10,
    38  				Root:  bytesutil.PadTo([]byte("good target"), 32),
    39  			},
    40  		},
    41  	}
    42  	mockProtector := &mockSlasher.MockProtector{AllowAttestation: false}
    43  	validator.protector = mockProtector
    44  	err := validator.slashableAttestationCheck(context.Background(), att, pubKey, [32]byte{1})
    45  	require.ErrorContains(t, failedPostAttSignExternalErr, err)
    46  	mockProtector.AllowAttestation = true
    47  	err = validator.slashableAttestationCheck(context.Background(), att, pubKey, [32]byte{1})
    48  	require.NoError(t, err, "Expected allowed attestation not to throw error")
    49  }
    50  
    51  func Test_slashableAttestationCheck_UpdatesLowestSignedEpochs(t *testing.T) {
    52  	config := &featureconfig.Flags{
    53  		SlasherProtection: true,
    54  	}
    55  	reset := featureconfig.InitWithReset(config)
    56  	defer reset()
    57  	validator, m, validatorKey, finish := setup(t)
    58  	defer finish()
    59  	ctx := context.Background()
    60  	pubKey := [48]byte{}
    61  	copy(pubKey[:], validatorKey.PublicKey().Marshal())
    62  	att := &ethpb.IndexedAttestation{
    63  		AttestingIndices: []uint64{1, 2},
    64  		Data: &ethpb.AttestationData{
    65  			Slot:            5,
    66  			CommitteeIndex:  2,
    67  			BeaconBlockRoot: bytesutil.PadTo([]byte("great block"), 32),
    68  			Source: &ethpb.Checkpoint{
    69  				Epoch: 4,
    70  				Root:  bytesutil.PadTo([]byte("good source"), 32),
    71  			},
    72  			Target: &ethpb.Checkpoint{
    73  				Epoch: 10,
    74  				Root:  bytesutil.PadTo([]byte("good target"), 32),
    75  			},
    76  		},
    77  	}
    78  	mockProtector := &mockSlasher.MockProtector{AllowAttestation: false}
    79  	validator.protector = mockProtector
    80  	m.validatorClient.EXPECT().DomainData(
    81  		gomock.Any(), // ctx
    82  		&ethpb.DomainRequest{Epoch: 10, Domain: []byte{1, 0, 0, 0}},
    83  	).Return(&ethpb.DomainResponse{SignatureDomain: make([]byte, 32)}, nil /*err*/)
    84  	_, sr, err := validator.getDomainAndSigningRoot(ctx, att.Data)
    85  	require.NoError(t, err)
    86  	mockProtector.AllowAttestation = true
    87  	err = validator.slashableAttestationCheck(context.Background(), att, pubKey, sr)
    88  	require.NoError(t, err)
    89  	differentSigningRoot := [32]byte{2}
    90  	err = validator.slashableAttestationCheck(context.Background(), att, pubKey, differentSigningRoot)
    91  	require.ErrorContains(t, "could not sign attestation", err)
    92  
    93  	e, exists, err := validator.db.LowestSignedSourceEpoch(context.Background(), pubKey)
    94  	require.NoError(t, err)
    95  	require.Equal(t, true, exists)
    96  	require.Equal(t, types.Epoch(4), e)
    97  	e, exists, err = validator.db.LowestSignedTargetEpoch(context.Background(), pubKey)
    98  	require.NoError(t, err)
    99  	require.Equal(t, true, exists)
   100  	require.Equal(t, types.Epoch(10), e)
   101  }
   102  
   103  func Test_slashableAttestationCheck_OK(t *testing.T) {
   104  	config := &featureconfig.Flags{
   105  		SlasherProtection: false,
   106  	}
   107  	reset := featureconfig.InitWithReset(config)
   108  	defer reset()
   109  	ctx := context.Background()
   110  	validator, _, _, finish := setup(t)
   111  	defer finish()
   112  	att := &ethpb.IndexedAttestation{
   113  		AttestingIndices: []uint64{1, 2},
   114  		Data: &ethpb.AttestationData{
   115  			Slot:            5,
   116  			CommitteeIndex:  2,
   117  			BeaconBlockRoot: []byte("great block"),
   118  			Source: &ethpb.Checkpoint{
   119  				Epoch: 4,
   120  				Root:  []byte("good source"),
   121  			},
   122  			Target: &ethpb.Checkpoint{
   123  				Epoch: 10,
   124  				Root:  []byte("good target"),
   125  			},
   126  		},
   127  	}
   128  	sr := [32]byte{1}
   129  	fakePubkey := bytesutil.ToBytes48([]byte("test"))
   130  	err := validator.slashableAttestationCheck(ctx, att, fakePubkey, sr)
   131  	require.NoError(t, err, "Expected allowed attestation not to throw error")
   132  }
   133  
   134  func Test_slashableAttestationCheck_GenesisEpoch(t *testing.T) {
   135  	config := &featureconfig.Flags{
   136  		SlasherProtection: false,
   137  	}
   138  	reset := featureconfig.InitWithReset(config)
   139  	defer reset()
   140  	ctx := context.Background()
   141  	validator, _, _, finish := setup(t)
   142  	defer finish()
   143  	att := &ethpb.IndexedAttestation{
   144  		AttestingIndices: []uint64{1, 2},
   145  		Data: &ethpb.AttestationData{
   146  			Slot:            5,
   147  			CommitteeIndex:  2,
   148  			BeaconBlockRoot: bytesutil.PadTo([]byte("great block root"), 32),
   149  			Source: &ethpb.Checkpoint{
   150  				Epoch: 0,
   151  				Root:  bytesutil.PadTo([]byte("great root"), 32),
   152  			},
   153  			Target: &ethpb.Checkpoint{
   154  				Epoch: 0,
   155  				Root:  bytesutil.PadTo([]byte("great root"), 32),
   156  			},
   157  		},
   158  	}
   159  	fakePubkey := bytesutil.ToBytes48([]byte("test"))
   160  	err := validator.slashableAttestationCheck(ctx, att, fakePubkey, [32]byte{})
   161  	require.NoError(t, err, "Expected allowed attestation not to throw error")
   162  	e, exists, err := validator.db.LowestSignedSourceEpoch(context.Background(), fakePubkey)
   163  	require.NoError(t, err)
   164  	require.Equal(t, true, exists)
   165  	require.Equal(t, types.Epoch(0), e)
   166  	e, exists, err = validator.db.LowestSignedTargetEpoch(context.Background(), fakePubkey)
   167  	require.NoError(t, err)
   168  	require.Equal(t, true, exists)
   169  	require.Equal(t, types.Epoch(0), e)
   170  }