github.com/prysmaticlabs/prysm@v1.4.4/beacon-chain/rpc/prysm/v1alpha1/beacon/slashings_test.go (about)

     1  package beacon
     2  
     3  import (
     4  	"context"
     5  	"testing"
     6  
     7  	types "github.com/prysmaticlabs/eth2-types"
     8  	ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
     9  	"github.com/prysmaticlabs/prysm/shared/featureconfig"
    10  	"google.golang.org/protobuf/proto"
    11  
    12  	mock "github.com/prysmaticlabs/prysm/beacon-chain/blockchain/testing"
    13  	"github.com/prysmaticlabs/prysm/beacon-chain/operations/slashings"
    14  	mockp2p "github.com/prysmaticlabs/prysm/beacon-chain/p2p/testing"
    15  	"github.com/prysmaticlabs/prysm/shared/testutil"
    16  	"github.com/prysmaticlabs/prysm/shared/testutil/assert"
    17  	"github.com/prysmaticlabs/prysm/shared/testutil/require"
    18  )
    19  
    20  func TestServer_SubmitProposerSlashing(t *testing.T) {
    21  	ctx := context.Background()
    22  
    23  	st, privs := testutil.DeterministicGenesisState(t, 64)
    24  	slashedVal, err := st.ValidatorAtIndex(5)
    25  	require.NoError(t, err)
    26  	// We mark the validator at index 5 as already slashed.
    27  	slashedVal.Slashed = true
    28  	require.NoError(t, st.UpdateValidatorAtIndex(5, slashedVal))
    29  
    30  	mb := &mockp2p.MockBroadcaster{}
    31  	bs := &Server{
    32  		HeadFetcher: &mock.ChainService{
    33  			State: st,
    34  		},
    35  		SlashingsPool: slashings.NewPool(),
    36  		Broadcaster:   mb,
    37  	}
    38  
    39  	// We want a proposer slashing for validator with index 2 to
    40  	// be included in the pool.
    41  	slashing, err := testutil.GenerateProposerSlashingForValidator(st, privs[2], types.ValidatorIndex(2))
    42  	require.NoError(t, err)
    43  
    44  	_, err = bs.SubmitProposerSlashing(ctx, slashing)
    45  	require.NoError(t, err)
    46  	assert.Equal(t, true, mb.BroadcastCalled, "Expected broadcast to be called")
    47  }
    48  
    49  func TestServer_SubmitAttesterSlashing(t *testing.T) {
    50  	ctx := context.Background()
    51  	// We mark the validators at index 5, 6 as already slashed.
    52  	st, privs := testutil.DeterministicGenesisState(t, 64)
    53  	slashedVal, err := st.ValidatorAtIndex(5)
    54  	require.NoError(t, err)
    55  
    56  	// We mark the validator at index 5 as already slashed.
    57  	slashedVal.Slashed = true
    58  	require.NoError(t, st.UpdateValidatorAtIndex(5, slashedVal))
    59  
    60  	mb := &mockp2p.MockBroadcaster{}
    61  	bs := &Server{
    62  		HeadFetcher: &mock.ChainService{
    63  			State: st,
    64  		},
    65  		SlashingsPool: slashings.NewPool(),
    66  		Broadcaster:   mb,
    67  	}
    68  
    69  	slashing, err := testutil.GenerateAttesterSlashingForValidator(st, privs[2], types.ValidatorIndex(2))
    70  	require.NoError(t, err)
    71  
    72  	// We want the intersection of the slashing attesting indices
    73  	// to be slashed, so we expect validators 2 and 3 to be in the response
    74  	// slashed indices.
    75  	_, err = bs.SubmitAttesterSlashing(ctx, slashing)
    76  	require.NoError(t, err)
    77  	assert.Equal(t, true, mb.BroadcastCalled, "Expected broadcast to be called when flag is set")
    78  }
    79  
    80  func TestServer_SubmitProposerSlashing_DontBroadcast(t *testing.T) {
    81  	resetCfg := featureconfig.InitWithReset(&featureconfig.Flags{DisableBroadcastSlashings: true})
    82  	defer resetCfg()
    83  	ctx := context.Background()
    84  	st, privs := testutil.DeterministicGenesisState(t, 64)
    85  	slashedVal, err := st.ValidatorAtIndex(5)
    86  	require.NoError(t, err)
    87  	// We mark the validator at index 5 as already slashed.
    88  	slashedVal.Slashed = true
    89  	require.NoError(t, st.UpdateValidatorAtIndex(5, slashedVal))
    90  
    91  	mb := &mockp2p.MockBroadcaster{}
    92  	bs := &Server{
    93  		HeadFetcher: &mock.ChainService{
    94  			State: st,
    95  		},
    96  		SlashingsPool: slashings.NewPool(),
    97  		Broadcaster:   mb,
    98  	}
    99  
   100  	// We want a proposer slashing for validator with index 2 to
   101  	// be included in the pool.
   102  	wanted := &ethpb.SubmitSlashingResponse{
   103  		SlashedIndices: []types.ValidatorIndex{2},
   104  	}
   105  	slashing, err := testutil.GenerateProposerSlashingForValidator(st, privs[2], types.ValidatorIndex(2))
   106  	require.NoError(t, err)
   107  
   108  	res, err := bs.SubmitProposerSlashing(ctx, slashing)
   109  	require.NoError(t, err)
   110  	if !proto.Equal(wanted, res) {
   111  		t.Errorf("Wanted %v, received %v", wanted, res)
   112  	}
   113  
   114  	assert.Equal(t, false, mb.BroadcastCalled, "Expected broadcast not to be called by default")
   115  
   116  	slashing, err = testutil.GenerateProposerSlashingForValidator(st, privs[5], types.ValidatorIndex(5))
   117  	require.NoError(t, err)
   118  
   119  	// We do not want a proposer slashing for an already slashed validator
   120  	// (the validator at index 5) to be included in the pool.
   121  	_, err = bs.SubmitProposerSlashing(ctx, slashing)
   122  	require.ErrorContains(t, "Could not insert proposer slashing into pool", err)
   123  }
   124  
   125  func TestServer_SubmitAttesterSlashing_DontBroadcast(t *testing.T) {
   126  	resetCfg := featureconfig.InitWithReset(&featureconfig.Flags{DisableBroadcastSlashings: true})
   127  	defer resetCfg()
   128  	ctx := context.Background()
   129  	// We mark the validators at index 5, 6 as already slashed.
   130  	st, privs := testutil.DeterministicGenesisState(t, 64)
   131  	slashedVal, err := st.ValidatorAtIndex(5)
   132  	require.NoError(t, err)
   133  
   134  	// We mark the validator at index 5 as already slashed.
   135  	slashedVal.Slashed = true
   136  	require.NoError(t, st.UpdateValidatorAtIndex(5, slashedVal))
   137  
   138  	mb := &mockp2p.MockBroadcaster{}
   139  	bs := &Server{
   140  		HeadFetcher: &mock.ChainService{
   141  			State: st,
   142  		},
   143  		SlashingsPool: slashings.NewPool(),
   144  		Broadcaster:   mb,
   145  	}
   146  
   147  	slashing, err := testutil.GenerateAttesterSlashingForValidator(st, privs[2], types.ValidatorIndex(2))
   148  	require.NoError(t, err)
   149  
   150  	// We want the intersection of the slashing attesting indices
   151  	// to be slashed, so we expect validators 2 and 3 to be in the response
   152  	// slashed indices.
   153  	wanted := &ethpb.SubmitSlashingResponse{
   154  		SlashedIndices: []types.ValidatorIndex{2},
   155  	}
   156  	res, err := bs.SubmitAttesterSlashing(ctx, slashing)
   157  	require.NoError(t, err)
   158  	if !proto.Equal(wanted, res) {
   159  		t.Errorf("Wanted %v, received %v", wanted, res)
   160  	}
   161  	assert.Equal(t, false, mb.BroadcastCalled, "Expected broadcast not to be called by default")
   162  
   163  	slashing, err = testutil.GenerateAttesterSlashingForValidator(st, privs[5], types.ValidatorIndex(5))
   164  	require.NoError(t, err)
   165  	// If any of the attesting indices in the slashing object have already
   166  	// been slashed, we should fail to insert properly into the attester slashing pool.
   167  	_, err = bs.SubmitAttesterSlashing(ctx, slashing)
   168  	assert.NotNil(t, err, "Expected including a attester slashing for an already slashed validator to fail")
   169  }