Validator Changes for Optimized Slasher (#9705)

* val changes

* mock

* mocks

* gomock any

* gaz

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
This commit is contained in:
Raul Jordan 2021-09-29 16:25:45 -05:00 committed by GitHub
parent 520bc9d955
commit 13cdb83591
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 278 additions and 260 deletions

View File

@ -21,7 +21,7 @@ go_library(
"//testing/fuzz:__pkg__",
"//testing/spectest:__subpackages__",
"//testing/util:__pkg__",
"//validator/accounts:__pkg__",
"//validator:__subpackages__",
],
deps = [
"//beacon-chain/core:go_default_library",

View File

@ -3,12 +3,13 @@
# Script to update mock files after proto/prysm/v1alpha1/services.proto changes.
# Use a space to separate mock destination from its interfaces.
mock_path="shared/mock"
mock_path="testing/mock"
mocks=(
"$mock_path/beacon_service_mock.go BeaconChainClient,BeaconChain_StreamChainHeadClient,BeaconChain_StreamAttestationsClient,BeaconChain_StreamBlocksClient,BeaconChain_StreamValidatorsInfoClient,BeaconChain_StreamIndexedAttestationsClient"
"$mock_path/beacon_chain_service_mock.go BeaconChain_StreamChainHeadServer,BeaconChain_StreamAttestationsServer,BeaconChain_StreamBlocksServer,BeaconChain_StreamValidatorsInfoServer,BeaconChain_StreamIndexedAttestationsServer"
"$mock_path/beacon_validator_server_mock.go BeaconNodeValidatorServer,BeaconNodeValidator_WaitForActivationServer,BeaconNodeValidator_WaitForChainStartServer,BeaconNodeValidator_StreamDutiesServer"
"$mock_path/beacon_validator_client_mock.go BeaconNodeValidatorClient,BeaconNodeValidator_WaitForChainStartClient,BeaconNodeValidator_WaitForActivationClient,BeaconNodeValidator_StreamDutiesClient"
"$mock_path/slasher_client_mock.go SlasherClient"
"$mock_path/event_service_mock.go EventsClient,Events_StreamEventsClient,Events_StreamEventsServer"
"$mock_path/node_service_mock.go NodeClient"
"$mock_path/keymanager_mock.go RemoteSignerClient"
@ -19,8 +20,8 @@ for ((i = 0; i < ${#mocks[@]}; i++)); do
interfaces=${mocks[i]#* };
echo "generating $file for interfaces: $interfaces";
GO11MODULE=on mockgen -package=mock -destination="$file" github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1 "$interfaces"
GO11MODULE=on mockgen -package=mock -destination="$file" github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1 "$interfaces"
done
goimports -w "$mock_path/."
gofmt -s -w "$mock_path/."

View File

@ -16,6 +16,7 @@ go_library(
"event_service_mock.go",
"keymanager_mock.go",
"node_service_mock.go",
"slasher_client_mock.go",
],
importpath = "github.com/prysmaticlabs/prysm/testing/mock",
visibility = ["//visibility:public"],

97
testing/mock/slasher_client_mock.go generated Normal file
View File

@ -0,0 +1,97 @@
// Code generated by MockGen. DO NOT EDIT.
// Source: github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1 (interfaces: SlasherClient)
// Package mock is a generated GoMock package.
package mock
import (
context "context"
reflect "reflect"
gomock "github.com/golang/mock/gomock"
eth "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
grpc "google.golang.org/grpc"
)
// MockSlasherClient is a mock of SlasherClient interface.
type MockSlasherClient struct {
ctrl *gomock.Controller
recorder *MockSlasherClientMockRecorder
}
// MockSlasherClientMockRecorder is the mock recorder for MockSlasherClient.
type MockSlasherClientMockRecorder struct {
mock *MockSlasherClient
}
// NewMockSlasherClient creates a new mock instance.
func NewMockSlasherClient(ctrl *gomock.Controller) *MockSlasherClient {
mock := &MockSlasherClient{ctrl: ctrl}
mock.recorder = &MockSlasherClientMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use.
func (m *MockSlasherClient) EXPECT() *MockSlasherClientMockRecorder {
return m.recorder
}
// HighestAttestations mocks base method.
func (m *MockSlasherClient) HighestAttestations(arg0 context.Context, arg1 *eth.HighestAttestationRequest, arg2 ...grpc.CallOption) (*eth.HighestAttestationResponse, error) {
m.ctrl.T.Helper()
varargs := []interface{}{arg0, arg1}
for _, a := range arg2 {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "HighestAttestations", varargs...)
ret0, _ := ret[0].(*eth.HighestAttestationResponse)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// HighestAttestations indicates an expected call of HighestAttestations.
func (mr *MockSlasherClientMockRecorder) HighestAttestations(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]interface{}{arg0, arg1}, arg2...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HighestAttestations", reflect.TypeOf((*MockSlasherClient)(nil).HighestAttestations), varargs...)
}
// IsSlashableAttestation mocks base method.
func (m *MockSlasherClient) IsSlashableAttestation(arg0 context.Context, arg1 *eth.IndexedAttestation, arg2 ...grpc.CallOption) (*eth.AttesterSlashingResponse, error) {
m.ctrl.T.Helper()
varargs := []interface{}{arg0, arg1}
for _, a := range arg2 {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "IsSlashableAttestation", varargs...)
ret0, _ := ret[0].(*eth.AttesterSlashingResponse)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// IsSlashableAttestation indicates an expected call of IsSlashableAttestation.
func (mr *MockSlasherClientMockRecorder) IsSlashableAttestation(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]interface{}{arg0, arg1}, arg2...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsSlashableAttestation", reflect.TypeOf((*MockSlasherClient)(nil).IsSlashableAttestation), varargs...)
}
// IsSlashableBlock mocks base method.
func (m *MockSlasherClient) IsSlashableBlock(arg0 context.Context, arg1 *eth.SignedBeaconBlockHeader, arg2 ...grpc.CallOption) (*eth.ProposerSlashingResponse, error) {
m.ctrl.T.Helper()
varargs := []interface{}{arg0, arg1}
for _, a := range arg2 {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "IsSlashableBlock", varargs...)
ret0, _ := ret[0].(*eth.ProposerSlashingResponse)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// IsSlashableBlock indicates an expected call of IsSlashableBlock.
func (mr *MockSlasherClientMockRecorder) IsSlashableBlock(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]interface{}{arg0, arg1}, arg2...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsSlashableBlock", reflect.TypeOf((*MockSlasherClient)(nil).IsSlashableBlock), varargs...)
}

View File

@ -53,7 +53,6 @@ go_library(
"//validator/keymanager:go_default_library",
"//validator/keymanager/imported:go_default_library",
"//validator/keymanager/remote:go_default_library",
"//validator/slashing-protection/iface:go_default_library",
"@com_github_dgraph_io_ristretto//:go_default_library",
"@com_github_ferranbt_fastssz//:go_default_library",
"@com_github_grpc_ecosystem_go_grpc_middleware//:go_default_library",
@ -113,6 +112,7 @@ go_test(
"//encoding/bytesutil:go_default_library",
"//io/file:go_default_library",
"//proto/prysm/v1alpha1:go_default_library",
"//proto/prysm/v1alpha1/block:go_default_library",
"//proto/prysm/v1alpha1/validator-client:go_default_library",
"//proto/prysm/v1alpha1/wrapper:go_default_library",
"//runtime:go_default_library",

View File

@ -81,8 +81,12 @@ func (v *validator) slashableAttestationCheck(
return errors.Wrap(err, "could not save attestation history for validator public key")
}
if features.Get().RemoteSlasherProtection && v.protector != nil {
if !v.protector.CheckAttestationSafety(ctx, indexedAtt) {
if features.Get().RemoteSlasherProtection {
slashing, err := v.slashingProtectionClient.IsSlashableAttestation(ctx, indexedAtt)
if err != nil {
return errors.Wrap(err, "could not check if attestation is slashable")
}
if slashing != nil && len(slashing.AttesterSlashings) > 0 {
if v.emitAccountMetrics {
ValidatorAttestFailVecSlasher.WithLabelValues(fmtKey).Inc()
}

View File

@ -10,7 +10,6 @@ import (
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/testing/require"
mockSlasher "github.com/prysmaticlabs/prysm/validator/testing"
)
func Test_slashableAttestationCheck(t *testing.T) {
@ -19,7 +18,7 @@ func Test_slashableAttestationCheck(t *testing.T) {
}
reset := features.InitWithReset(config)
defer reset()
validator, _, validatorKey, finish := setup(t)
validator, m, validatorKey, finish := setup(t)
defer finish()
pubKey := [48]byte{}
copy(pubKey[:], validatorKey.PublicKey().Marshal())
@ -39,11 +38,23 @@ func Test_slashableAttestationCheck(t *testing.T) {
},
},
}
mockProtector := &mockSlasher.MockProtector{AllowAttestation: false}
validator.protector = mockProtector
m.slasherClient.EXPECT().IsSlashableAttestation(
gomock.Any(), // ctx
att,
).Return(&ethpb.AttesterSlashingResponse{AttesterSlashings: []*ethpb.AttesterSlashing{{
Attestation_1: &ethpb.IndexedAttestation{},
Attestation_2: &ethpb.IndexedAttestation{},
}}}, nil /*err*/)
err := validator.slashableAttestationCheck(context.Background(), att, pubKey, [32]byte{1})
require.ErrorContains(t, failedPostAttSignExternalErr, err)
mockProtector.AllowAttestation = true
m.slasherClient.EXPECT().IsSlashableAttestation(
gomock.Any(), // ctx
att,
).Return(&ethpb.AttesterSlashingResponse{}, nil /*err*/)
err = validator.slashableAttestationCheck(context.Background(), att, pubKey, [32]byte{1})
require.NoError(t, err, "Expected allowed attestation not to throw error")
}
@ -75,18 +86,23 @@ func Test_slashableAttestationCheck_UpdatesLowestSignedEpochs(t *testing.T) {
},
},
}
mockProtector := &mockSlasher.MockProtector{AllowAttestation: false}
validator.protector = mockProtector
m.slasherClient.EXPECT().IsSlashableAttestation(
gomock.Any(), // ctx
att,
).Return(&ethpb.AttesterSlashingResponse{}, nil /*err*/)
m.validatorClient.EXPECT().DomainData(
gomock.Any(), // ctx
&ethpb.DomainRequest{Epoch: 10, Domain: []byte{1, 0, 0, 0}},
).Return(&ethpb.DomainResponse{SignatureDomain: make([]byte, 32)}, nil /*err*/)
_, sr, err := validator.getDomainAndSigningRoot(ctx, att.Data)
require.NoError(t, err)
mockProtector.AllowAttestation = true
err = validator.slashableAttestationCheck(context.Background(), att, pubKey, sr)
require.NoError(t, err)
differentSigningRoot := [32]byte{2}
err = validator.slashableAttestationCheck(context.Background(), att, pubKey, differentSigningRoot)
require.ErrorContains(t, "could not sign attestation", err)
@ -102,12 +118,12 @@ func Test_slashableAttestationCheck_UpdatesLowestSignedEpochs(t *testing.T) {
func Test_slashableAttestationCheck_OK(t *testing.T) {
config := &features.Flags{
RemoteSlasherProtection: false,
RemoteSlasherProtection: true,
}
reset := features.InitWithReset(config)
defer reset()
ctx := context.Background()
validator, _, _, finish := setup(t)
validator, mocks, _, finish := setup(t)
defer finish()
att := &ethpb.IndexedAttestation{
AttestingIndices: []uint64{1, 2},
@ -127,18 +143,24 @@ func Test_slashableAttestationCheck_OK(t *testing.T) {
}
sr := [32]byte{1}
fakePubkey := bytesutil.ToBytes48([]byte("test"))
mocks.slasherClient.EXPECT().IsSlashableAttestation(
gomock.Any(), // ctx
att,
).Return(&ethpb.AttesterSlashingResponse{}, nil /*err*/)
err := validator.slashableAttestationCheck(ctx, att, fakePubkey, sr)
require.NoError(t, err, "Expected allowed attestation not to throw error")
}
func Test_slashableAttestationCheck_GenesisEpoch(t *testing.T) {
config := &features.Flags{
RemoteSlasherProtection: false,
RemoteSlasherProtection: true,
}
reset := features.InitWithReset(config)
defer reset()
ctx := context.Background()
validator, _, _, finish := setup(t)
validator, mocks, _, finish := setup(t)
defer finish()
att := &ethpb.IndexedAttestation{
AttestingIndices: []uint64{1, 2},
@ -156,6 +178,12 @@ func Test_slashableAttestationCheck_GenesisEpoch(t *testing.T) {
},
},
}
mocks.slasherClient.EXPECT().IsSlashableAttestation(
gomock.Any(), // ctx
att,
).Return(&ethpb.AttesterSlashingResponse{}, nil /*err*/)
fakePubkey := bytesutil.ToBytes48([]byte("test"))
err := validator.slashableAttestationCheck(ctx, att, fakePubkey, [32]byte{})
require.NoError(t, err, "Expected allowed attestation not to throw error")

View File

@ -36,7 +36,6 @@ type Validator interface {
WaitForChainStart(ctx context.Context) error
WaitForSync(ctx context.Context) error
WaitForActivation(ctx context.Context, accountsChangedChan chan [][48]byte) error
SlasherReady(ctx context.Context) error
CanonicalHeadSlot(ctx context.Context) (types.Slot, error)
NextSlot() <-chan types.Slot
SlotDeadline(slot types.Slot) time.Time

View File

@ -119,20 +119,13 @@ func (v *validator) proposeBlockPhase0(ctx context.Context, slot types.Slot, pub
return
}
if err := v.preBlockSignValidations(ctx, pubKey, wrapper.WrappedPhase0BeaconBlock(b), signingRoot); err != nil {
if err := v.slashableProposalCheck(ctx, pubKey, wrapper.WrappedPhase0SignedBeaconBlock(blk), signingRoot); err != nil {
log.WithFields(
blockLogFields(pubKey, wrapper.WrappedPhase0BeaconBlock(b), nil),
).WithError(err).Error("Failed block slashing protection check")
return
}
if err := v.postBlockSignUpdate(ctx, pubKey, wrapper.WrappedPhase0SignedBeaconBlock(blk), signingRoot); err != nil {
log.WithFields(
blockLogFields(pubKey, wrapper.WrappedPhase0BeaconBlock(b), sig),
).WithError(err).Error("Failed block slashing protection check")
return
}
// Propose and broadcast block via beacon node
blkResp, err := v.validatorClient.ProposeBlock(ctx, blk)
if err != nil {
@ -252,16 +245,6 @@ func (v *validator) proposeBlockAltair(ctx context.Context, slot types.Slot, pub
return
}
if err := v.preBlockSignValidations(ctx, pubKey, wb, signingRoot); err != nil {
log.WithFields(
blockLogFields(pubKey, wb, nil),
).WithError(err).Error("Failed block slashing protection check")
if v.emitAccountMetrics {
ValidatorProposeFailVec.WithLabelValues(fmtKey).Inc()
}
return
}
wsb, err := wrapper.WrappedAltairSignedBeaconBlock(blk)
if err != nil {
log.WithError(err).Error("Failed to wrap signed block")
@ -270,9 +253,10 @@ func (v *validator) proposeBlockAltair(ctx context.Context, slot types.Slot, pub
}
return
}
if err := v.postBlockSignUpdate(ctx, pubKey, wsb, signingRoot); err != nil {
if err := v.slashableProposalCheck(ctx, pubKey, wsb, signingRoot); err != nil {
log.WithFields(
blockLogFields(pubKey, wb, sig),
blockLogFields(pubKey, wb, nil),
).WithError(err).Error("Failed block slashing protection check")
if v.emitAccountMetrics {
ValidatorProposeFailVec.WithLabelValues(fmtKey).Inc()

View File

@ -11,15 +11,15 @@ import (
"github.com/sirupsen/logrus"
)
var failedPreBlockSignLocalErr = "attempted to sign a double proposal, block rejected by local protection"
var failedPreBlockSignExternalErr = "attempted a double proposal, block rejected by remote slashing protection"
var failedPostBlockSignErr = "made a double proposal, considered slashable by remote slashing protection"
var failedBlockSignLocalErr = "attempted to sign a double proposal, block rejected by local protection"
var failedBlockSignExternalErr = "attempted a double proposal, block rejected by remote slashing protection"
func (v *validator) preBlockSignValidations(
ctx context.Context, pubKey [48]byte, blk block.BeaconBlock, signingRoot [32]byte,
func (v *validator) slashableProposalCheck(
ctx context.Context, pubKey [48]byte, signedBlock block.SignedBeaconBlock, signingRoot [32]byte,
) error {
fmtKey := fmt.Sprintf("%#x", pubKey[:])
blk := signedBlock.Block()
prevSigningRoot, proposalAtSlotExists, err := v.db.ProposalHistoryForSlot(ctx, pubKey, blk.Slot())
if err != nil {
if v.emitAccountMetrics {
@ -42,7 +42,7 @@ func (v *validator) preBlockSignValidations(
if v.emitAccountMetrics {
ValidatorProposeFailVec.WithLabelValues(fmtKey).Inc()
}
return errors.New(failedPreBlockSignLocalErr)
return errors.New(failedBlockSignLocalErr)
}
// Based on EIP3076, validator should refuse to sign any proposal with slot less
@ -56,29 +56,24 @@ func (v *validator) preBlockSignValidations(
blk.Slot(),
)
}
return nil
}
func (v *validator) postBlockSignUpdate(
ctx context.Context,
pubKey [48]byte,
blk block.SignedBeaconBlock,
signingRoot [32]byte,
) error {
fmtKey := fmt.Sprintf("%#x", pubKey[:])
if features.Get().RemoteSlasherProtection && v.protector != nil {
blockHdr, err := block.SignedBeaconBlockHeaderFromBlockInterface(blk)
if features.Get().RemoteSlasherProtection {
blockHdr, err := block.SignedBeaconBlockHeaderFromBlockInterface(signedBlock)
if err != nil {
return errors.Wrap(err, "failed to get block header from block")
}
if !v.protector.CheckBlockSafety(ctx, blockHdr) {
slashing, err := v.slashingProtectionClient.IsSlashableBlock(ctx, blockHdr)
if err != nil {
return errors.Wrap(err, "could not check if block is slashable")
}
if slashing != nil && len(slashing.ProposerSlashings) > 0 {
if v.emitAccountMetrics {
ValidatorProposeFailVecSlasher.WithLabelValues(fmtKey).Inc()
}
return errors.New(failedPostBlockSignErr)
return errors.New(failedBlockSignExternalErr)
}
}
if err := v.db.SaveProposalHistoryForSlot(ctx, pubKey, blk.Block().Slot(), signingRoot[:]); err != nil {
if err := v.db.SaveProposalHistoryForSlot(ctx, pubKey, blk.Slot(), signingRoot[:]); err != nil {
if v.emitAccountMetrics {
ValidatorProposeFailVec.WithLabelValues(fmtKey).Inc()
}

View File

@ -4,16 +4,18 @@ import (
"context"
"testing"
"github.com/golang/mock/gomock"
types "github.com/prysmaticlabs/eth2-types"
"github.com/prysmaticlabs/prysm/config/features"
"github.com/prysmaticlabs/prysm/config/params"
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/block"
"github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/wrapper"
"github.com/prysmaticlabs/prysm/testing/require"
"github.com/prysmaticlabs/prysm/testing/util"
mockSlasher "github.com/prysmaticlabs/prysm/validator/testing"
)
func TestPreBlockSignLocalValidation_PreventsLowerThanMinProposal(t *testing.T) {
func Test_slashableProposalCheck_PreventsLowerThanMinProposal(t *testing.T) {
ctx := context.Background()
validator, _, validatorKey, finish := setup(t)
defer finish()
@ -28,55 +30,64 @@ func TestPreBlockSignLocalValidation_PreventsLowerThanMinProposal(t *testing.T)
// We expect the same block with a slot lower than the lowest
// signed slot to fail validation.
block := &ethpb.BeaconBlock{
Slot: lowestSignedSlot - 1,
ProposerIndex: 0,
block := &ethpb.SignedBeaconBlock{
Block: &ethpb.BeaconBlock{
Slot: lowestSignedSlot - 1,
ProposerIndex: 0,
},
Signature: params.BeaconConfig().EmptySignature[:],
}
err = validator.preBlockSignValidations(context.Background(), pubKeyBytes, wrapper.WrappedPhase0BeaconBlock(block), [32]byte{4})
err = validator.slashableProposalCheck(context.Background(), pubKeyBytes, wrapper.WrappedPhase0SignedBeaconBlock(block), [32]byte{4})
require.ErrorContains(t, "could not sign block with slot <= lowest signed", err)
// We expect the same block with a slot equal to the lowest
// signed slot to pass validation if signing roots are equal.
block = &ethpb.BeaconBlock{
Slot: lowestSignedSlot,
ProposerIndex: 0,
block = &ethpb.SignedBeaconBlock{
Block: &ethpb.BeaconBlock{
Slot: lowestSignedSlot,
ProposerIndex: 0,
},
Signature: params.BeaconConfig().EmptySignature[:],
}
err = validator.preBlockSignValidations(context.Background(), pubKeyBytes, wrapper.WrappedPhase0BeaconBlock(block), [32]byte{1})
err = validator.slashableProposalCheck(context.Background(), pubKeyBytes, wrapper.WrappedPhase0SignedBeaconBlock(block), [32]byte{1})
require.NoError(t, err)
// We expect the same block with a slot equal to the lowest
// signed slot to fail validation if signing roots are different.
block = &ethpb.BeaconBlock{
Slot: lowestSignedSlot,
ProposerIndex: 0,
}
err = validator.preBlockSignValidations(context.Background(), pubKeyBytes, wrapper.WrappedPhase0BeaconBlock(block), [32]byte{4})
require.ErrorContains(t, failedPreBlockSignLocalErr, err)
err = validator.slashableProposalCheck(context.Background(), pubKeyBytes, wrapper.WrappedPhase0SignedBeaconBlock(block), [32]byte{4})
require.ErrorContains(t, failedBlockSignLocalErr, err)
// We expect the same block with a slot > than the lowest
// signed slot to pass validation.
block = &ethpb.BeaconBlock{
Slot: lowestSignedSlot + 1,
ProposerIndex: 0,
block = &ethpb.SignedBeaconBlock{
Block: &ethpb.BeaconBlock{
Slot: lowestSignedSlot + 1,
ProposerIndex: 0,
},
Signature: params.BeaconConfig().EmptySignature[:],
}
err = validator.preBlockSignValidations(context.Background(), pubKeyBytes, wrapper.WrappedPhase0BeaconBlock(block), [32]byte{3})
err = validator.slashableProposalCheck(context.Background(), pubKeyBytes, wrapper.WrappedPhase0SignedBeaconBlock(block), [32]byte{3})
require.NoError(t, err)
}
func TestPreBlockSignLocalValidation(t *testing.T) {
func Test_slashableProposalCheck(t *testing.T) {
ctx := context.Background()
config := &features.Flags{
RemoteSlasherProtection: false,
RemoteSlasherProtection: true,
}
reset := features.InitWithReset(config)
defer reset()
validator, _, validatorKey, finish := setup(t)
validator, mocks, validatorKey, finish := setup(t)
defer finish()
block := &ethpb.BeaconBlock{
Slot: 10,
ProposerIndex: 0,
}
blk := util.HydrateSignedBeaconBlock(&ethpb.SignedBeaconBlock{
Block: &ethpb.BeaconBlock{
Slot: 10,
ProposerIndex: 0,
},
Signature: params.BeaconConfig().EmptySignature[:],
})
pubKeyBytes := [48]byte{}
copy(pubKeyBytes[:], validatorKey.PublicKey().Marshal())
@ -90,65 +101,77 @@ func TestPreBlockSignLocalValidation(t *testing.T) {
require.NoError(t, err)
pubKey := [48]byte{}
copy(pubKey[:], validatorKey.PublicKey().Marshal())
sBlock := wrapper.WrappedPhase0SignedBeaconBlock(blk)
blockHdr, err := block.SignedBeaconBlockHeaderFromBlockInterface(sBlock)
require.NoError(t, err)
mocks.slasherClient.EXPECT().IsSlashableBlock(
gomock.Any(), // ctx
blockHdr,
).Return(&ethpb.ProposerSlashingResponse{}, nil /*err*/)
// We expect the same block sent out with the same root should not be slasahble.
err = validator.preBlockSignValidations(context.Background(), pubKey, wrapper.WrappedPhase0BeaconBlock(block), dummySigningRoot)
err = validator.slashableProposalCheck(context.Background(), pubKey, sBlock, dummySigningRoot)
require.NoError(t, err)
// We expect the same block sent out with a different signing root should be slasahble.
err = validator.preBlockSignValidations(context.Background(), pubKey, wrapper.WrappedPhase0BeaconBlock(block), [32]byte{2})
require.ErrorContains(t, failedPreBlockSignLocalErr, err)
err = validator.slashableProposalCheck(context.Background(), pubKey, sBlock, [32]byte{2})
require.ErrorContains(t, failedBlockSignLocalErr, err)
// We save a proposal at slot 11 with a nil signing root.
block.Slot = 11
err = validator.db.SaveProposalHistoryForSlot(ctx, pubKeyBytes, block.Slot, nil)
blk.Block.Slot = 11
sBlock = wrapper.WrappedPhase0SignedBeaconBlock(blk)
err = validator.db.SaveProposalHistoryForSlot(ctx, pubKeyBytes, blk.Block.Slot, nil)
require.NoError(t, err)
// We expect the same block sent out should return slashable error even
// if we had a nil signing root stored in the database.
err = validator.preBlockSignValidations(context.Background(), pubKey, wrapper.WrappedPhase0BeaconBlock(block), [32]byte{2})
require.ErrorContains(t, failedPreBlockSignLocalErr, err)
err = validator.slashableProposalCheck(context.Background(), pubKey, sBlock, [32]byte{2})
require.ErrorContains(t, failedBlockSignLocalErr, err)
// A block with a different slot for which we do not have a proposing history
// should not be failing validation.
block.Slot = 9
err = validator.preBlockSignValidations(context.Background(), pubKey, wrapper.WrappedPhase0BeaconBlock(block), [32]byte{3})
blk.Block.Slot = 9
sBlock = wrapper.WrappedPhase0SignedBeaconBlock(blk)
blockHdr, err = block.SignedBeaconBlockHeaderFromBlockInterface(sBlock)
require.NoError(t, err)
mocks.slasherClient.EXPECT().IsSlashableBlock(
gomock.Any(), // ctx
blockHdr,
).Return(&ethpb.ProposerSlashingResponse{}, nil /*err*/)
err = validator.slashableProposalCheck(context.Background(), pubKey, sBlock, [32]byte{3})
require.NoError(t, err, "Expected allowed block not to throw error")
}
func TestPreBlockSignValidation(t *testing.T) {
validator, _, validatorKey, finish := setup(t)
defer finish()
pubKey := [48]byte{}
copy(pubKey[:], validatorKey.PublicKey().Marshal())
block := util.NewBeaconBlock()
block.Block.Slot = 10
mockProtector := &mockSlasher.MockProtector{AllowBlock: false}
validator.protector = mockProtector
mockProtector.AllowBlock = true
err := validator.preBlockSignValidations(context.Background(), pubKey, wrapper.WrappedPhase0BeaconBlock(block.Block), [32]byte{2})
require.NoError(t, err, "Expected allowed block not to throw error")
}
func TestPostBlockSignUpdate(t *testing.T) {
func Test_slashableProposalCheck_RemoteProtection(t *testing.T) {
config := &features.Flags{
RemoteSlasherProtection: true,
}
reset := features.InitWithReset(config)
defer reset()
validator, _, validatorKey, finish := setup(t)
validator, m, validatorKey, finish := setup(t)
defer finish()
pubKey := [48]byte{}
copy(pubKey[:], validatorKey.PublicKey().Marshal())
emptyBlock := util.NewBeaconBlock()
emptyBlock.Block.Slot = 10
emptyBlock.Block.ProposerIndex = 0
mockProtector := &mockSlasher.MockProtector{AllowBlock: false}
validator.protector = mockProtector
err := validator.postBlockSignUpdate(context.Background(), pubKey, wrapper.WrappedPhase0SignedBeaconBlock(emptyBlock), [32]byte{})
require.ErrorContains(t, failedPostBlockSignErr, err, "Expected error when post signature update is detected as slashable")
mockProtector.AllowBlock = true
err = validator.postBlockSignUpdate(context.Background(), pubKey, wrapper.WrappedPhase0SignedBeaconBlock(emptyBlock), [32]byte{})
blk := util.NewBeaconBlock()
blk.Block.Slot = 10
sBlock := wrapper.WrappedPhase0SignedBeaconBlock(blk)
blockHdr, err := block.SignedBeaconBlockHeaderFromBlockInterface(sBlock)
require.NoError(t, err)
m.slasherClient.EXPECT().IsSlashableBlock(
gomock.Any(), // ctx
blockHdr,
).Return(&ethpb.ProposerSlashingResponse{ProposerSlashings: []*ethpb.ProposerSlashing{{}}}, nil /*err*/)
err = validator.slashableProposalCheck(context.Background(), pubKey, sBlock, [32]byte{2})
require.ErrorContains(t, failedBlockSignExternalErr, err)
m.slasherClient.EXPECT().IsSlashableBlock(
gomock.Any(), // ctx
blockHdr,
).Return(&ethpb.ProposerSlashingResponse{}, nil /*err*/)
err = validator.slashableProposalCheck(context.Background(), pubKey, sBlock, [32]byte{2})
require.NoError(t, err, "Expected allowed block not to throw error")
}

View File

@ -18,7 +18,7 @@ import (
validatorpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/validator-client"
"github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/wrapper"
"github.com/prysmaticlabs/prysm/testing/assert"
mock2 "github.com/prysmaticlabs/prysm/testing/mock"
mock "github.com/prysmaticlabs/prysm/testing/mock"
"github.com/prysmaticlabs/prysm/testing/require"
"github.com/prysmaticlabs/prysm/testing/util"
testing2 "github.com/prysmaticlabs/prysm/validator/db/testing"
@ -29,8 +29,9 @@ import (
)
type mocks struct {
validatorClient *mock2.MockBeaconNodeValidatorClient
nodeClient *mock2.MockNodeClient
validatorClient *mock.MockBeaconNodeValidatorClient
nodeClient *mock.MockNodeClient
slasherClient *mock.MockSlasherClient
signExitFunc func(context.Context, *validatorpb.SignRequest) (bls.Signature, error)
}
@ -67,8 +68,9 @@ func setupWithKey(t *testing.T, validatorKey bls.SecretKey) (*validator, *mocks,
valDB := testing2.SetupDB(t, [][48]byte{pubKey})
ctrl := gomock.NewController(t)
m := &mocks{
validatorClient: mock2.NewMockBeaconNodeValidatorClient(ctrl),
nodeClient: mock2.NewMockNodeClient(ctrl),
validatorClient: mock.NewMockBeaconNodeValidatorClient(ctrl),
nodeClient: mock.NewMockNodeClient(ctrl),
slasherClient: mock.NewMockSlasherClient(ctrl),
signExitFunc: func(ctx context.Context, req *validatorpb.SignRequest) (bls.Signature, error) {
return mockSignature{}, nil
},
@ -85,6 +87,7 @@ func setupWithKey(t *testing.T, validatorKey bls.SecretKey) (*validator, *mocks,
db: valDB,
keyManager: km,
validatorClient: m.validatorClient,
slashingProtectionClient: m.slasherClient,
graffiti: []byte{},
attLogs: make(map[[32]byte]*attSubmitted),
aggregatedSlotCommitteeIDCache: aggregatedSlotCommitteeIDCache,
@ -296,10 +299,10 @@ func TestProposeBlock_BlocksDoubleProposal(t *testing.T) {
).Return(&ethpb.ProposeResponse{BlockRoot: make([]byte, 32)}, nil /*error*/)
validator.ProposeBlock(context.Background(), slot, pubKey)
require.LogsDoNotContain(t, hook, failedPreBlockSignLocalErr)
require.LogsDoNotContain(t, hook, failedBlockSignLocalErr)
validator.ProposeBlock(context.Background(), slot, pubKey)
require.LogsContain(t, hook, failedPreBlockSignLocalErr)
require.LogsContain(t, hook, failedBlockSignLocalErr)
}
func TestProposeBlockAltair_BlocksDoubleProposal(t *testing.T) {
@ -356,10 +359,10 @@ func TestProposeBlockAltair_BlocksDoubleProposal(t *testing.T) {
).Return(&ethpb.ProposeResponse{BlockRoot: make([]byte, 32)}, nil /*error*/)
validator.ProposeBlock(context.Background(), slot, pubKey)
require.LogsDoNotContain(t, hook, failedPreBlockSignLocalErr)
require.LogsDoNotContain(t, hook, failedBlockSignLocalErr)
validator.ProposeBlock(context.Background(), slot, pubKey)
require.LogsContain(t, hook, failedPreBlockSignLocalErr)
require.LogsContain(t, hook, failedBlockSignLocalErr)
}
func TestProposeBlock_BlocksDoubleProposal_After54KEpochs(t *testing.T) {
@ -408,10 +411,10 @@ func TestProposeBlock_BlocksDoubleProposal_After54KEpochs(t *testing.T) {
).Return(&ethpb.ProposeResponse{BlockRoot: make([]byte, 32)}, nil /*error*/)
validator.ProposeBlock(context.Background(), farFuture, pubKey)
require.LogsDoNotContain(t, hook, failedPreBlockSignLocalErr)
require.LogsDoNotContain(t, hook, failedBlockSignLocalErr)
validator.ProposeBlock(context.Background(), farFuture, pubKey)
require.LogsContain(t, hook, failedPreBlockSignLocalErr)
require.LogsContain(t, hook, failedBlockSignLocalErr)
}
func TestProposeBlock_AllowsPastProposals(t *testing.T) {
@ -449,7 +452,7 @@ func TestProposeBlock_AllowsPastProposals(t *testing.T) {
).Times(2).Return(&ethpb.ProposeResponse{BlockRoot: make([]byte, 32)}, nil /*error*/)
validator.ProposeBlock(context.Background(), farAhead, pubKey)
require.LogsDoNotContain(t, hook, failedPreBlockSignLocalErr)
require.LogsDoNotContain(t, hook, failedBlockSignLocalErr)
past := params.BeaconConfig().SlotsPerEpoch.Mul(uint64(params.BeaconConfig().WeakSubjectivityPeriod - 400))
blk2 := util.NewBeaconBlock()
@ -459,7 +462,7 @@ func TestProposeBlock_AllowsPastProposals(t *testing.T) {
gomock.Any(),
).Return(blk2.Block, nil /*err*/)
validator.ProposeBlock(context.Background(), past, pubKey)
require.LogsDoNotContain(t, hook, failedPreBlockSignLocalErr)
require.LogsDoNotContain(t, hook, failedBlockSignLocalErr)
}
func TestProposeBlock_AllowsSameEpoch(t *testing.T) {
@ -497,7 +500,7 @@ func TestProposeBlock_AllowsSameEpoch(t *testing.T) {
).Times(2).Return(&ethpb.ProposeResponse{BlockRoot: make([]byte, 32)}, nil /*error*/)
validator.ProposeBlock(context.Background(), farAhead, pubKey)
require.LogsDoNotContain(t, hook, failedPreBlockSignLocalErr)
require.LogsDoNotContain(t, hook, failedBlockSignLocalErr)
blk2 := util.NewBeaconBlock()
blk2.Block.Slot = farAhead - 4
@ -507,7 +510,7 @@ func TestProposeBlock_AllowsSameEpoch(t *testing.T) {
).Return(blk2.Block, nil /*err*/)
validator.ProposeBlock(context.Background(), farAhead-4, pubKey)
require.LogsDoNotContain(t, hook, failedPreBlockSignLocalErr)
require.LogsDoNotContain(t, hook, failedBlockSignLocalErr)
}
func TestProposeBlock_BroadcastsBlock(t *testing.T) {
@ -875,7 +878,7 @@ func TestSignAltairBlock(t *testing.T) {
func TestGetGraffiti_Ok(t *testing.T) {
ctrl := gomock.NewController(t)
m := &mocks{
validatorClient: mock2.NewMockBeaconNodeValidatorClient(ctrl),
validatorClient: mock.NewMockBeaconNodeValidatorClient(ctrl),
}
pubKey := [48]byte{'a'}
tests := []struct {
@ -958,7 +961,7 @@ func TestGetGraffitiOrdered_Ok(t *testing.T) {
valDB := testing2.SetupDB(t, [][48]byte{pubKey})
ctrl := gomock.NewController(t)
m := &mocks{
validatorClient: mock2.NewMockBeaconNodeValidatorClient(ctrl),
validatorClient: mock.NewMockBeaconNodeValidatorClient(ctrl),
}
m.validatorClient.EXPECT().
ValidatorIndex(gomock.Any(), &ethpb.ValidatorIndexRequest{PublicKey: pubKey[:]}).

View File

@ -9,7 +9,6 @@ import (
"github.com/pkg/errors"
types "github.com/prysmaticlabs/eth2-types"
"github.com/prysmaticlabs/prysm/beacon-chain/core"
"github.com/prysmaticlabs/prysm/config/features"
"github.com/prysmaticlabs/prysm/config/params"
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
"github.com/prysmaticlabs/prysm/validator/client/iface"
@ -40,11 +39,6 @@ func run(ctx context.Context, v iface.Validator) {
cleanup()
log.Fatalf("Wallet is not ready: %v", err)
}
if features.Get().RemoteSlasherProtection {
if err := v.SlasherReady(ctx); err != nil {
log.Fatalf("Slasher is not ready: %v", err)
}
}
ticker := time.NewTicker(backOffPeriod)
defer ticker.Stop()

View File

@ -8,7 +8,6 @@ import (
types "github.com/prysmaticlabs/eth2-types"
"github.com/prysmaticlabs/prysm/async/event"
"github.com/prysmaticlabs/prysm/config/features"
"github.com/prysmaticlabs/prysm/testing/assert"
"github.com/prysmaticlabs/prysm/testing/require"
"github.com/prysmaticlabs/prysm/validator/client/iface"
@ -62,17 +61,6 @@ func TestCancelledContext_WaitsForActivation(t *testing.T) {
assert.Equal(t, 1, v.WaitForActivationCalled, "Expected WaitForActivation() to be called")
}
func TestCancelledContext_ChecksSlasherReady(t *testing.T) {
v := &testutil.FakeValidator{Keymanager: &mockKeymanager{accountsChangedFeed: &event.Feed{}}}
cfg := &features.Flags{
RemoteSlasherProtection: true,
}
reset := features.InitWithReset(cfg)
defer reset()
run(cancelledContext(), v)
assert.Equal(t, true, v.SlasherReadyCalled, "Expected SlasherReady() to be called")
}
func TestUpdateDuties_NextSlot(t *testing.T) {
v := &testutil.FakeValidator{Keymanager: &mockKeymanager{accountsChangedFeed: &event.Feed{}}}
ctx, cancel := context.WithCancel(context.Background())

View File

@ -27,7 +27,6 @@ import (
"github.com/prysmaticlabs/prysm/validator/graffiti"
"github.com/prysmaticlabs/prysm/validator/keymanager"
"github.com/prysmaticlabs/prysm/validator/keymanager/imported"
slashingiface "github.com/prysmaticlabs/prysm/validator/slashing-protection/iface"
"go.opencensus.io/plugin/ocgrpc"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
@ -64,7 +63,6 @@ type ValidatorService struct {
withCert string
endpoint string
validator iface.Validator
protector slashingiface.Protector
ctx context.Context
keyManager keymanager.IKeymanager
grpcHeaders []string
@ -82,7 +80,6 @@ type Config struct {
GrpcRetriesFlag uint
GrpcRetryDelay time.Duration
GrpcMaxCallRecvMsgSizeFlag int
Protector slashingiface.Protector
Endpoint string
Validator iface.Validator
ValDB db.Database
@ -112,7 +109,6 @@ func NewValidatorService(ctx context.Context, cfg *Config) (*ValidatorService, e
grpcRetries: cfg.GrpcRetriesFlag,
grpcRetryDelay: cfg.GrpcRetryDelay,
grpcHeaders: strings.Split(cfg.GrpcHeadersFlag, ","),
protector: cfg.Protector,
validator: cfg.Validator,
db: cfg.ValDB,
walletInitializedFeed: cfg.WalletInitializedFeed,
@ -188,7 +184,6 @@ func (v *ValidatorService) Start() {
attLogs: make(map[[32]byte]*attSubmitted),
domainDataCache: cache,
aggregatedSlotCommitteeIDCache: aggregatedSlotCommitteeIDCache,
protector: v.protector,
voteStats: voteStats{startEpoch: types.Epoch(^uint64(0))},
useWeb: v.useWeb,
walletInitializedFeed: v.walletInitializedFeed,

View File

@ -9,7 +9,6 @@ import (
"testing"
"github.com/bazelbuild/rules_go/go/tools/bazel"
"github.com/prysmaticlabs/prysm/config/features"
"github.com/prysmaticlabs/prysm/io/file"
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/wrapper"
@ -76,12 +75,6 @@ func setupEIP3076SpecTests(t *testing.T) []*eip3076TestCase {
}
func TestEIP3076SpecTests(t *testing.T) {
config := &features.Flags{
RemoteSlasherProtection: true,
}
reset := features.InitWithReset(config)
defer reset()
testCases := setupEIP3076SpecTests(t)
for _, tt := range testCases {
t.Run(tt.Name, func(t *testing.T) {
@ -130,22 +123,12 @@ func TestEIP3076SpecTests(t *testing.T) {
copy(signingRoot[:], signingRootBytes)
}
err = validator.preBlockSignValidations(context.Background(), pk, wrapper.WrappedPhase0BeaconBlock(b.Block), signingRoot)
err = validator.slashableProposalCheck(context.Background(), pk, wrapper.WrappedPhase0SignedBeaconBlock(b), signingRoot)
if sb.ShouldSucceed {
require.NoError(t, err)
} else {
require.NotEqual(t, nil, err, "pre validation should have failed for block")
}
// Only proceed post update if pre validation did not error.
if err == nil {
err = validator.postBlockSignUpdate(context.Background(), pk, wrapper.WrappedPhase0SignedBeaconBlock(b), signingRoot)
if sb.ShouldSucceed {
require.NoError(t, err)
} else {
require.NotEqual(t, nil, err, "post validation should have failed for block")
}
}
}
// This loops through a list of attestation signings to attempt after importing the interchange data above.

View File

@ -36,20 +36,17 @@ import (
"github.com/prysmaticlabs/prysm/validator/db/kv"
"github.com/prysmaticlabs/prysm/validator/graffiti"
"github.com/prysmaticlabs/prysm/validator/keymanager"
slashingiface "github.com/prysmaticlabs/prysm/validator/slashing-protection/iface"
"github.com/sirupsen/logrus"
"go.opencensus.io/trace"
"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/types/known/emptypb"
)
// reconnectPeriod is the frequency that we try to restart our
// slasher connection when the slasher client connection is not ready.
var reconnectPeriod = 5 * time.Second
// keyFetchPeriod is the frequency that we try to refetch validating keys
// in case no keys were fetched previously.
var keyRefetchPeriod = 30 * time.Second
var (
keyRefetchPeriod = 30 * time.Second
)
var (
msgCouldNotFetchKeys = "could not fetch validating keys"
@ -81,7 +78,7 @@ type validator struct {
keyManager keymanager.IKeymanager
beaconClient ethpb.BeaconChainClient
validatorClient ethpb.BeaconNodeValidatorClient
protector slashingiface.Protector
slashingProtectionClient ethpb.SlasherClient
db vdb.Database
graffiti []byte
voteStats voteStats
@ -224,37 +221,6 @@ func (v *validator) WaitForSync(ctx context.Context) error {
}
}
// SlasherReady checks if slasher that was configured as external protection
// is reachable.
func (v *validator) SlasherReady(ctx context.Context) error {
ctx, span := trace.StartSpan(ctx, "validator.SlasherReady")
defer span.End()
if features.Get().RemoteSlasherProtection {
err := v.protector.Status()
if err == nil {
return nil
}
ticker := time.NewTicker(reconnectPeriod)
defer ticker.Stop()
for {
select {
case <-ticker.C:
log.WithError(err).Info("Slasher connection wasn't ready. Trying again")
err = v.protector.Status()
if err != nil {
continue
}
log.Info("Slasher connection is ready")
return nil
case <-ctx.Done():
log.Debug("Context closed, exiting reconnect external protection")
return ctx.Err()
}
}
}
return nil
}
// ReceiveBlocks starts a gRPC client stream listener to obtain
// blocks from the beacon node. Upon receiving a block, the service
// broadcasts it to a feed for other usages to subscribe to.

View File

@ -52,8 +52,6 @@ go_library(
"//validator/keymanager:go_default_library",
"//validator/keymanager/imported:go_default_library",
"//validator/rpc:go_default_library",
"//validator/slashing-protection:go_default_library",
"//validator/slashing-protection/iface:go_default_library",
"//validator/web:go_default_library",
"@com_github_grpc_ecosystem_grpc_gateway_v2//runtime:go_default_library",
"@com_github_pkg_errors//:go_default_library",

View File

@ -40,8 +40,6 @@ import (
"github.com/prysmaticlabs/prysm/validator/keymanager"
"github.com/prysmaticlabs/prysm/validator/keymanager/imported"
"github.com/prysmaticlabs/prysm/validator/rpc"
slashingprotection "github.com/prysmaticlabs/prysm/validator/slashing-protection"
"github.com/prysmaticlabs/prysm/validator/slashing-protection/iface"
"github.com/prysmaticlabs/prysm/validator/web"
"github.com/sirupsen/logrus"
"github.com/urfave/cli/v2"
@ -251,9 +249,6 @@ func (c *ValidatorClient) initializeFromCLI(cliCtx *cli.Context) error {
return err
}
}
if err := c.registerSlasherService(); err != nil {
return err
}
if err := c.registerValidatorService(keyManager); err != nil {
return err
}
@ -338,9 +333,6 @@ func (c *ValidatorClient) initializeForWeb(cliCtx *cli.Context) error {
return err
}
}
if err := c.registerSlasherService(); err != nil {
return err
}
if err := c.registerValidatorService(keyManager); err != nil {
return err
}
@ -391,12 +383,6 @@ func (c *ValidatorClient) registerValidatorService(
maxCallRecvMsgSize := c.cliCtx.Int(cmd.GrpcMaxCallRecvMsgSizeFlag.Name)
grpcRetries := c.cliCtx.Uint(flags.GrpcRetriesFlag.Name)
grpcRetryDelay := c.cliCtx.Duration(flags.GrpcRetryDelayFlag.Name)
var sp *slashingprotection.Service
var protector iface.Protector
if err := c.services.FetchService(&sp); err == nil {
protector = sp
}
gStruct := &g.Graffiti{}
var err error
if c.cliCtx.IsSet(flags.GraffitiFileFlag.Name) {
@ -419,7 +405,6 @@ func (c *ValidatorClient) registerValidatorService(
GrpcRetriesFlag: grpcRetries,
GrpcRetryDelay: grpcRetryDelay,
GrpcHeadersFlag: c.cliCtx.String(flags.GrpcHeadersFlag.Name),
Protector: protector,
ValDB: c.db,
UseWeb: c.cliCtx.Bool(flags.EnableWebFlag.Name),
WalletInitializedFeed: c.walletInitialized,
@ -432,32 +417,6 @@ func (c *ValidatorClient) registerValidatorService(
return c.services.RegisterService(v)
}
func (c *ValidatorClient) registerSlasherService() error {
if !features.Get().RemoteSlasherProtection {
return nil
}
endpoint := c.cliCtx.String(flags.SlasherRPCProviderFlag.Name)
if endpoint == "" {
return errors.New("external slasher feature flag is set but no slasher endpoint is configured")
}
cert := c.cliCtx.String(flags.SlasherCertFlag.Name)
maxCallRecvMsgSize := c.cliCtx.Int(cmd.GrpcMaxCallRecvMsgSizeFlag.Name)
grpcRetries := c.cliCtx.Uint(flags.GrpcRetriesFlag.Name)
grpcRetryDelay := c.cliCtx.Duration(flags.GrpcRetryDelayFlag.Name)
sp, err := slashingprotection.NewService(c.cliCtx.Context, &slashingprotection.Config{
Endpoint: endpoint,
CertFlag: cert,
GrpcMaxCallRecvMsgSizeFlag: maxCallRecvMsgSize,
GrpcRetriesFlag: grpcRetries,
GrpcRetryDelay: grpcRetryDelay,
GrpcHeadersFlag: c.cliCtx.String(flags.GrpcHeadersFlag.Name),
})
if err != nil {
return errors.Wrap(err, "could not initialize slasher service")
}
return c.services.RegisterService(sp)
}
func (c *ValidatorClient) registerRPCService(cliCtx *cli.Context, km keymanager.IKeymanager) error {
var vs *client.ValidatorService