From 13cdb835910bf763f6e2d2d75767842c2e6ada7f Mon Sep 17 00:00:00 2001 From: Raul Jordan Date: Wed, 29 Sep 2021 16:25:45 -0500 Subject: [PATCH] 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> --- beacon-chain/core/blocks/BUILD.bazel | 2 +- hack/update-mockgen.sh | 5 +- testing/mock/BUILD.bazel | 1 + testing/mock/slasher_client_mock.go | 97 ++++++++++++ validator/client/BUILD.bazel | 2 +- validator/client/attest_protect.go | 8 +- validator/client/attest_protect_test.go | 52 +++++-- validator/client/iface/validator.go | 1 - validator/client/propose.go | 24 +-- validator/client/propose_protect.go | 35 ++--- validator/client/propose_protect_test.go | 147 ++++++++++-------- validator/client/propose_test.go | 37 +++-- validator/client/runner.go | 6 - validator/client/runner_test.go | 12 -- validator/client/service.go | 5 - .../slashing_protection_interchange_test.go | 19 +-- validator/client/validator.go | 42 +---- validator/node/BUILD.bazel | 2 - validator/node/node.go | 41 ----- 19 files changed, 278 insertions(+), 260 deletions(-) create mode 100644 testing/mock/slasher_client_mock.go diff --git a/beacon-chain/core/blocks/BUILD.bazel b/beacon-chain/core/blocks/BUILD.bazel index 8e8547306..c921a24a3 100644 --- a/beacon-chain/core/blocks/BUILD.bazel +++ b/beacon-chain/core/blocks/BUILD.bazel @@ -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", diff --git a/hack/update-mockgen.sh b/hack/update-mockgen.sh index c84fbad04..8d7e5b3fc 100755 --- a/hack/update-mockgen.sh +++ b/hack/update-mockgen.sh @@ -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/." + diff --git a/testing/mock/BUILD.bazel b/testing/mock/BUILD.bazel index 224159376..ed0cd34a6 100644 --- a/testing/mock/BUILD.bazel +++ b/testing/mock/BUILD.bazel @@ -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"], diff --git a/testing/mock/slasher_client_mock.go b/testing/mock/slasher_client_mock.go new file mode 100644 index 000000000..01af5c4c0 --- /dev/null +++ b/testing/mock/slasher_client_mock.go @@ -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...) +} diff --git a/validator/client/BUILD.bazel b/validator/client/BUILD.bazel index d84599372..ed96b55a6 100644 --- a/validator/client/BUILD.bazel +++ b/validator/client/BUILD.bazel @@ -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", diff --git a/validator/client/attest_protect.go b/validator/client/attest_protect.go index 7763c706d..5c7a2bf8a 100644 --- a/validator/client/attest_protect.go +++ b/validator/client/attest_protect.go @@ -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() } diff --git a/validator/client/attest_protect_test.go b/validator/client/attest_protect_test.go index d5d6b07b5..724bd19a8 100644 --- a/validator/client/attest_protect_test.go +++ b/validator/client/attest_protect_test.go @@ -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(ðpb.AttesterSlashingResponse{AttesterSlashings: []*ethpb.AttesterSlashing{{ + Attestation_1: ðpb.IndexedAttestation{}, + Attestation_2: ðpb.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(ðpb.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(ðpb.AttesterSlashingResponse{}, nil /*err*/) + m.validatorClient.EXPECT().DomainData( gomock.Any(), // ctx ðpb.DomainRequest{Epoch: 10, Domain: []byte{1, 0, 0, 0}}, ).Return(ðpb.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 := ðpb.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(ðpb.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 := ðpb.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(ðpb.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") diff --git a/validator/client/iface/validator.go b/validator/client/iface/validator.go index 198999e87..1f46b0e45 100644 --- a/validator/client/iface/validator.go +++ b/validator/client/iface/validator.go @@ -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 diff --git a/validator/client/propose.go b/validator/client/propose.go index ac67486c6..d9c37b1eb 100644 --- a/validator/client/propose.go +++ b/validator/client/propose.go @@ -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() diff --git a/validator/client/propose_protect.go b/validator/client/propose_protect.go index 1c742285f..662f617fe 100644 --- a/validator/client/propose_protect.go +++ b/validator/client/propose_protect.go @@ -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() } diff --git a/validator/client/propose_protect_test.go b/validator/client/propose_protect_test.go index 05bb0aa28..e2cd1ac96 100644 --- a/validator/client/propose_protect_test.go +++ b/validator/client/propose_protect_test.go @@ -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 := ðpb.BeaconBlock{ - Slot: lowestSignedSlot - 1, - ProposerIndex: 0, + block := ðpb.SignedBeaconBlock{ + Block: ðpb.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 = ðpb.BeaconBlock{ - Slot: lowestSignedSlot, - ProposerIndex: 0, + block = ðpb.SignedBeaconBlock{ + Block: ðpb.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 = ðpb.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 = ðpb.BeaconBlock{ - Slot: lowestSignedSlot + 1, - ProposerIndex: 0, + block = ðpb.SignedBeaconBlock{ + Block: ðpb.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 := ðpb.BeaconBlock{ - Slot: 10, - ProposerIndex: 0, - } + blk := util.HydrateSignedBeaconBlock(ðpb.SignedBeaconBlock{ + Block: ðpb.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(ðpb.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(ðpb.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(ðpb.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(ðpb.ProposerSlashingResponse{}, nil /*err*/) + + err = validator.slashableProposalCheck(context.Background(), pubKey, sBlock, [32]byte{2}) require.NoError(t, err, "Expected allowed block not to throw error") } diff --git a/validator/client/propose_test.go b/validator/client/propose_test.go index 1fb18c5e5..b3902476d 100644 --- a/validator/client/propose_test.go +++ b/validator/client/propose_test.go @@ -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(ðpb.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(ðpb.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(ðpb.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(ðpb.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(ðpb.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(), ðpb.ValidatorIndexRequest{PublicKey: pubKey[:]}). diff --git a/validator/client/runner.go b/validator/client/runner.go index 13f6a1add..03f6fd502 100644 --- a/validator/client/runner.go +++ b/validator/client/runner.go @@ -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() diff --git a/validator/client/runner_test.go b/validator/client/runner_test.go index 6abe12d98..5775093f7 100644 --- a/validator/client/runner_test.go +++ b/validator/client/runner_test.go @@ -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()) diff --git a/validator/client/service.go b/validator/client/service.go index e7083c438..15778b751 100644 --- a/validator/client/service.go +++ b/validator/client/service.go @@ -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, diff --git a/validator/client/slashing_protection_interchange_test.go b/validator/client/slashing_protection_interchange_test.go index a5ae48b78..7df157bb9 100644 --- a/validator/client/slashing_protection_interchange_test.go +++ b/validator/client/slashing_protection_interchange_test.go @@ -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. diff --git a/validator/client/validator.go b/validator/client/validator.go index 275370ebd..fe5004d54 100644 --- a/validator/client/validator.go +++ b/validator/client/validator.go @@ -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. diff --git a/validator/node/BUILD.bazel b/validator/node/BUILD.bazel index 7a1407762..002ee914d 100644 --- a/validator/node/BUILD.bazel +++ b/validator/node/BUILD.bazel @@ -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", diff --git a/validator/node/node.go b/validator/node/node.go index 5377904f0..6596725ad 100644 --- a/validator/node/node.go +++ b/validator/node/node.go @@ -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