prysm-pulse/slasher/rpc/server.go

206 lines
6.8 KiB
Go
Raw Normal View History

package rpc
import (
"context"
"sync"
Double vote detection (#4049) * first version of the watchtower api * service files * Begin work on grpc server * More changes to server * REnames and mock setup * working test * merge * double propose detection test * nishant review * todo change * gaz * fix service * gaz * remove unused import * gaz * resolve circular dependency * resolve circular dependency 2nd try * remove package * fix package * fix test * added tests * gaz * remove status check * gaz * remove context * remove context * change var name * moved to rpc dir * gaz * remove server code * gaz * slasher server * visibility change * pb * service update * gaz * slasher grpc server * making it work * setup db and start * gaz * service flags fixes * grpc service running * go imports * remove new initializer * gaz * remove feature flags * change back SetupSlasherDB * fix SetupSlasherDB calls * define err * fix bad merge * fix test * fix imports * fix imports * fix imports * add cancel * comment stop * fix cancel issue * remove unneeded code * bring back bad merge that removed TODO * remove use of epoch as am input * fixed slasher to be runable again * wait for channel close * gaz * small test * flags fix * fix flag order * double vote detection * remove source epoch from indexed attestation indices * change server method to receive indexed attestation * start implementation * double vote detection * proto * pb * fir comment * nishant review * import fix * Update slasher/db/indexed_attestations.go Co-Authored-By: terence tsao <terence@prysmaticlabs.com> * terence feedback
2019-11-20 05:14:50 +00:00
"github.com/pkg/errors"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
slashpb "github.com/prysmaticlabs/prysm/proto/slashing"
"github.com/prysmaticlabs/prysm/shared/attestationutil"
"github.com/prysmaticlabs/prysm/shared/bls"
"github.com/prysmaticlabs/prysm/shared/p2putils"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/slasher/beaconclient"
"github.com/prysmaticlabs/prysm/slasher/db"
"github.com/prysmaticlabs/prysm/slasher/detection"
"github.com/sirupsen/logrus"
"go.opencensus.io/trace"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
)
// Server defines a server implementation of the gRPC Slasher service,
// providing RPC endpoints for retrieving slashing proofs for malicious validators.
type Server struct {
ctx context.Context
detector *detection.Service
slasherDB db.Database
beaconClient *beaconclient.Service
attestationLock sync.Mutex
proposeLock sync.Mutex
}
// IsSlashableAttestation returns an attester slashing if the attestation submitted
// is a slashable vote.
func (ss *Server) IsSlashableAttestation(ctx context.Context, req *ethpb.IndexedAttestation) (*slashpb.AttesterSlashingResponse, error) {
ctx, span := trace.StartSpan(ctx, "detection.IsSlashableAttestation")
defer span.End()
log.WithFields(logrus.Fields{
"slot": req.Data.Slot,
"indices": req.AttestingIndices,
}).Debug("Received attestation via RPC")
if req == nil {
return nil, status.Error(codes.InvalidArgument, "nil request provided")
}
if req.Data == nil {
return nil, status.Error(codes.InvalidArgument, "nil request data provided")
}
if req.Data.Target == nil {
return nil, status.Error(codes.InvalidArgument, "nil request data target provided")
}
if req.Data.Source == nil {
return nil, status.Error(codes.InvalidArgument, "nil request data source provided")
}
if req.Signature == nil {
return nil, status.Error(codes.InvalidArgument, "nil signature provided")
}
err := attestationutil.IsValidAttestationIndices(ctx, req)
if err != nil {
return nil, err
}
gvr, err := ss.beaconClient.GenesisValidatorsRoot(ctx)
if err != nil {
return nil, err
}
fork, err := p2putils.Fork(req.Data.Target.Epoch)
if err != nil {
return nil, err
}
domain, err := helpers.Domain(fork, req.Data.Target.Epoch, params.BeaconConfig().DomainBeaconAttester, gvr)
if err != nil {
return nil, err
}
indices := req.AttestingIndices
pkMap, err := ss.beaconClient.FindOrGetPublicKeys(ctx, indices)
if err != nil {
return nil, err
}
pubkeys := []bls.PublicKey{}
for _, pkBytes := range pkMap {
pk, err := bls.PublicKeyFromBytes(pkBytes)
if err != nil {
return nil, errors.Wrap(err, "could not deserialize validator public key")
}
pubkeys = append(pubkeys, pk)
}
err = attestationutil.VerifyIndexedAttestationSig(ctx, req, pubkeys, domain)
if err != nil {
No sig slasher rpc (#6174) * detect slashable attestations and blocks without db update * lint fixes * fix mock * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * preston feedback * Merge branch 'no_sig_slasher_rpc' of github.com:prysmaticlabs/prysm into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * nishant and ivan feedback * Merge branch 'no_sig_slasher_rpc' of github.com:prysmaticlabs/prysm into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Apply suggestions from code review
2020-06-11 18:50:12 +00:00
log.WithError(err).Error("failed to verify indexed attestation signature")
return nil, status.Errorf(codes.Internal, "could not verify indexed attestation signature: %v: %v", req, err)
}
ss.attestationLock.Lock()
defer ss.attestationLock.Unlock()
slashings, err := ss.detector.DetectAttesterSlashings(ctx, req)
if err != nil {
No sig slasher rpc (#6174) * detect slashable attestations and blocks without db update * lint fixes * fix mock * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * preston feedback * Merge branch 'no_sig_slasher_rpc' of github.com:prysmaticlabs/prysm into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * nishant and ivan feedback * Merge branch 'no_sig_slasher_rpc' of github.com:prysmaticlabs/prysm into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Apply suggestions from code review
2020-06-11 18:50:12 +00:00
return nil, status.Errorf(codes.Internal, "could not detect attester slashings for attestation: %v: %v", req, err)
}
if len(slashings) < 1 {
if err := ss.slasherDB.SaveIndexedAttestation(ctx, req); err != nil {
log.WithError(err).Error("Could not save indexed attestation")
No sig slasher rpc (#6174) * detect slashable attestations and blocks without db update * lint fixes * fix mock * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * preston feedback * Merge branch 'no_sig_slasher_rpc' of github.com:prysmaticlabs/prysm into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * nishant and ivan feedback * Merge branch 'no_sig_slasher_rpc' of github.com:prysmaticlabs/prysm into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Apply suggestions from code review
2020-06-11 18:50:12 +00:00
return nil, status.Errorf(codes.Internal, "could not save indexed attestation: %v: %v", req, err)
}
if err := ss.detector.UpdateSpans(ctx, req); err != nil {
No sig slasher rpc (#6174) * detect slashable attestations and blocks without db update * lint fixes * fix mock * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * preston feedback * Merge branch 'no_sig_slasher_rpc' of github.com:prysmaticlabs/prysm into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * nishant and ivan feedback * Merge branch 'no_sig_slasher_rpc' of github.com:prysmaticlabs/prysm into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Apply suggestions from code review
2020-06-11 18:50:12 +00:00
log.WithError(err).Error("could not update spans")
return nil, status.Errorf(codes.Internal, "failed to update spans: %v: %v", req, err)
}
}
return &slashpb.AttesterSlashingResponse{
AttesterSlashing: slashings,
}, nil
}
// IsSlashableBlock returns an proposer slashing if the block submitted
// is a double proposal.
func (ss *Server) IsSlashableBlock(ctx context.Context, req *ethpb.SignedBeaconBlockHeader) (*slashpb.ProposerSlashingResponse, error) {
ctx, span := trace.StartSpan(ctx, "detection.IsSlashableBlock")
defer span.End()
log.WithFields(logrus.Fields{
"slot": req.Header.Slot,
"proposer_index": req.Header.ProposerIndex,
}).Info("Received block via RPC")
if req == nil {
return nil, status.Error(codes.InvalidArgument, "nil request provided")
}
if req.Header == nil {
return nil, status.Error(codes.InvalidArgument, "nil header provided")
}
if req.Signature == nil {
return nil, status.Error(codes.InvalidArgument, "nil signature provided")
}
gvr, err := ss.beaconClient.GenesisValidatorsRoot(ctx)
if err != nil {
return nil, err
}
blockEpoch := helpers.SlotToEpoch(req.Header.Slot)
fork, err := p2putils.Fork(blockEpoch)
if err != nil {
return nil, err
}
domain, err := helpers.Domain(fork, blockEpoch, params.BeaconConfig().DomainBeaconProposer, gvr)
if err != nil {
return nil, err
}
pkMap, err := ss.beaconClient.FindOrGetPublicKeys(ctx, []uint64{req.Header.ProposerIndex})
if err != nil {
return nil, err
}
if err := helpers.VerifyBlockHeaderSigningRoot(
req.Header,
pkMap[req.Header.ProposerIndex],
req.Signature, domain); err != nil {
return nil, err
}
ss.proposeLock.Lock()
defer ss.proposeLock.Unlock()
slashing, err := ss.detector.DetectDoubleProposals(ctx, req)
if err != nil {
No sig slasher rpc (#6174) * detect slashable attestations and blocks without db update * lint fixes * fix mock * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * preston feedback * Merge branch 'no_sig_slasher_rpc' of github.com:prysmaticlabs/prysm into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * nishant and ivan feedback * Merge branch 'no_sig_slasher_rpc' of github.com:prysmaticlabs/prysm into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Apply suggestions from code review
2020-06-11 18:50:12 +00:00
return nil, status.Errorf(codes.Internal, "could not detect proposer slashing for block: %v: %v", req, err)
}
psr := &slashpb.ProposerSlashingResponse{}
if slashing != nil {
psr = &slashpb.ProposerSlashingResponse{
ProposerSlashing: []*ethpb.ProposerSlashing{slashing},
}
}
return psr, nil
Add surround check to endpoint (#4065) * first version of the watchtower api * service files * Begin work on grpc server * More changes to server * REnames and mock setup * working test * merge * double propose detection test * nishant review * todo change * gaz * fix service * gaz * remove unused import * gaz * resolve circular dependency * resolve circular dependency 2nd try * remove package * fix package * fix test * added tests * gaz * remove status check * gaz * remove context * remove context * change var name * moved to rpc dir * gaz * remove server code * gaz * slasher server * visibility change * pb * service update * gaz * slasher grpc server * making it work * setup db and start * gaz * service flags fixes * grpc service running * go imports * remove new initializer * gaz * remove feature flags * change back SetupSlasherDB * fix SetupSlasherDB calls * define err * fix bad merge * fix test * fix imports * fix imports * fix imports * add cancel * comment stop * fix cancel issue * remove unneeded code * bring back bad merge that removed TODO * remove use of epoch as am input * fixed slasher to be runable again * wait for channel close * gaz * small test * flags fix * fix flag order * double vote detection * remove source epoch from indexed attestation indices * change server method to receive indexed attestation * start implementation * double vote detection * proto * pb * fir comment * add surround detection and retrieval to endpoint * nishant review * import fix * fix miss order * fix detection 0 case added tests * terence review
2019-11-21 07:11:23 +00:00
}
No sig slasher rpc (#6174) * detect slashable attestations and blocks without db update * lint fixes * fix mock * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * preston feedback * Merge branch 'no_sig_slasher_rpc' of github.com:prysmaticlabs/prysm into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * nishant and ivan feedback * Merge branch 'no_sig_slasher_rpc' of github.com:prysmaticlabs/prysm into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Merge refs/heads/master into no_sig_slasher_rpc * Apply suggestions from code review
2020-06-11 18:50:12 +00:00
// IsSlashableAttestationNoUpdate returns true if the attestation submitted
// is a slashable vote (no db update is being done).
func (ss *Server) IsSlashableAttestationNoUpdate(ctx context.Context, req *ethpb.IndexedAttestation) (*slashpb.Slashable, error) {
sl := &slashpb.Slashable{}
slashings, err := ss.detector.DetectAttesterSlashings(ctx, req)
if err != nil {
return sl, status.Errorf(codes.Internal, "could not detect attester slashings for attestation: %v: %v", req, err)
}
if len(slashings) < 1 {
return sl, nil
}
sl.Slashable = true
return sl, nil
}
// IsSlashableBlockNoUpdate returns true if the block submitted
// is slashable (no db update is being done).
func (ss *Server) IsSlashableBlockNoUpdate(ctx context.Context, req *ethpb.BeaconBlockHeader) (*slashpb.Slashable, error) {
sl := &slashpb.Slashable{}
slash, err := ss.detector.DetectDoubleProposeNoUpdate(ctx, req)
if err != nil {
return sl, status.Errorf(codes.Internal, "could not detect proposer slashing for block: %v: %v", req, err)
}
sl.Slashable = slash
return sl, nil
}