Skip to content

Commit

Permalink
is slashable attestation endpoint implementation (#5209)
Browse files Browse the repository at this point in the history
* is slashable attestation endpoint implementation
* fix todo
* comment
* Merge refs/heads/master into is_slashable_attestation
* Merge refs/heads/master into is_slashable_attestation
* Merge refs/heads/master into is_slashable_attestation
* Update slasher/rpc/server.go
* Update slasher/rpc/server.go
* Update slasher/rpc/service.go
  • Loading branch information
shayzluf committed Mar 26, 2020
1 parent cdac3d6 commit 93e68db
Show file tree
Hide file tree
Showing 6 changed files with 118 additions and 20 deletions.
5 changes: 5 additions & 0 deletions slasher/detection/detect.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,11 @@ func (ds *Service) DetectAttesterSlashings(
return slashingList, nil
}

// UpdateSpans passthrough function that updates span maps given an indexed attestation.
func (ds *Service) UpdateSpans(ctx context.Context, att *ethpb.IndexedAttestation) error {
return ds.minMaxSpanDetector.UpdateSpans(ctx, att)
}

// detectDoubleVote cross references the passed in attestation with the bloom filter maintained
// for every epoch for the validator in order to determine if it is a double vote.
func (ds *Service) detectDoubleVote(
Expand Down
9 changes: 5 additions & 4 deletions slasher/node/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -214,10 +214,11 @@ func (s *SlasherNode) registerRPCService(ctx *cli.Context) error {
cert := ctx.String(flags.CertFlag.Name)
key := ctx.String(flags.KeyFlag.Name)
rpcService := rpc.NewService(context.Background(), &rpc.Config{
Port: port,
CertFlag: cert,
KeyFlag: key,
Detector: detectionService,
Port: port,
CertFlag: cert,
KeyFlag: key,
Detector: detectionService,
SlasherDB: s.db,
})

return s.services.RegisterService(rpcService)
Expand Down
12 changes: 11 additions & 1 deletion slasher/rpc/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ go_library(
deps = [
"//proto/slashing:go_default_library",
"//shared/traceutil:go_default_library",
"//slasher/db:go_default_library",
"//slasher/detection:go_default_library",
"@com_github_grpc_ecosystem_go_grpc_middleware//:go_default_library",
"@com_github_grpc_ecosystem_go_grpc_middleware//recovery:go_default_library",
Expand All @@ -20,9 +21,12 @@ go_library(
"@com_github_prysmaticlabs_ethereumapis//eth/v1alpha1:go_default_library",
"@com_github_sirupsen_logrus//:go_default_library",
"@io_opencensus_go//plugin/ocgrpc:go_default_library",
"@io_opencensus_go//trace:go_default_library",
"@org_golang_google_grpc//:go_default_library",
"@org_golang_google_grpc//codes:go_default_library",
"@org_golang_google_grpc//credentials:go_default_library",
"@org_golang_google_grpc//reflection:go_default_library",
"@org_golang_google_grpc//status:go_default_library",
],
)

Expand Down Expand Up @@ -52,10 +56,16 @@ go_test(

go_test(
name = "go_default_test",
srcs = ["service_test.go"],
srcs = [
"server_test.go",
"service_test.go",
],
embed = [":go_default_library"],
deps = [
"//shared/testutil:go_default_library",
"//slasher/db/testing:go_default_library",
"//slasher/detection:go_default_library",
"@com_github_prysmaticlabs_ethereumapis//eth/v1alpha1:go_default_library",
"@com_github_sirupsen_logrus//:go_default_library",
"@com_github_sirupsen_logrus//hooks/test:go_default_library",
],
Expand Down
30 changes: 27 additions & 3 deletions slasher/rpc/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,47 @@ package rpc
import (
"context"

"github.com/prysmaticlabs/prysm/slasher/db"
log "github.com/sirupsen/logrus"
"github.com/pkg/errors"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
slashpb "github.com/prysmaticlabs/prysm/proto/slashing"
"github.com/prysmaticlabs/prysm/slasher/detection"
"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
ctx context.Context
detector *detection.Service
slasherDB db.Database
}

// 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) {
return nil, errors.New("unimplemented")
ctx, span := trace.StartSpan(ctx, "detection.IsSlashableAttestation")
defer span.End()
//TODO(#5189) add signature validation to prevent DOS attack on the endpoint.
if err := ss.slasherDB.SaveIndexedAttestation(ctx, req); err != nil {
log.WithError(err).Error("Could not save indexed attestation")
return nil, status.Errorf(codes.Internal, "Could not save indexed attestation: %v: %v", req, err)
}
slashings, err := ss.detector.DetectAttesterSlashings(ctx, req)
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not detect attester slashings for attestation: %v: %v", req, err)
}
if len(slashings) < 1 {
if err := ss.detector.UpdateSpans(ctx, req); err != nil {
log.WithError(err).Error("Could not update spans")
}
}
return &slashpb.AttesterSlashingResponse{
AttesterSlashing: slashings,
}, nil
}

// IsSlashableBlock returns an proposer slashing if the block submitted
Expand Down
53 changes: 53 additions & 0 deletions slasher/rpc/server_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package rpc

import (
"context"
"testing"

ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
testDB "github.com/prysmaticlabs/prysm/slasher/db/testing"
"github.com/prysmaticlabs/prysm/slasher/detection"
)

func Test_DetectionFlow(t *testing.T) {
db := testDB.SetupSlasherDB(t, false)
defer testDB.TeardownSlasherDB(t, db)

savedAttestation := &ethpb.IndexedAttestation{
AttestingIndices: []uint64{3},
Data: &ethpb.AttestationData{
Source: &ethpb.Checkpoint{Epoch: 3},
Target: &ethpb.Checkpoint{Epoch: 4},
},
Signature: []byte{1, 2},
}
incomingAtt := &ethpb.IndexedAttestation{
AttestingIndices: []uint64{3},
Data: &ethpb.AttestationData{
Source: &ethpb.Checkpoint{Epoch: 2},
Target: &ethpb.Checkpoint{Epoch: 4},
},
Signature: []byte{1, 2},
}
cfg := &detection.Config{
SlasherDB: db,
}
ctx := context.Background()
ds := detection.NewDetectionService(ctx, cfg)
server := Server{ctx: ctx, detector: ds, slasherDB: db}
slashings, err := server.IsSlashableAttestation(ctx, savedAttestation)
if err != nil {
t.Fatalf("got error while trying to detect slashing: %v", err)
}
if len(slashings.AttesterSlashing) != 0 {
t.Fatalf("Found slashings while no slashing should have been found on first attestation: %v slashing found: %v", savedAttestation, slashings)
}

slashing, err := server.IsSlashableAttestation(ctx, incomingAtt)
if err != nil {
t.Fatalf("got error while trying to detect slashing: %v", err)
}
if len(slashing.AttesterSlashing) != 1 {
t.Fatalf("only one slashing should have been found. got: %v", len(slashing.AttesterSlashing))
}
}
29 changes: 17 additions & 12 deletions slasher/rpc/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"fmt"
"net"

"github.com/prysmaticlabs/prysm/slasher/db"
middleware "github.com/grpc-ecosystem/go-grpc-middleware"
recovery "github.com/grpc-ecosystem/go-grpc-middleware/recovery"
grpc_opentracing "github.com/grpc-ecosystem/go-grpc-middleware/tracing/opentracing"
Expand All @@ -29,30 +30,33 @@ type Service struct {
detector *detection.Service
listener net.Listener
grpcServer *grpc.Server
slasherDB db.Database
withCert string
withKey string
credentialError error
}

// Config options for the slasher node RPC server.
type Config struct {
Host string
Port string
CertFlag string
KeyFlag string
Detector *detection.Service
Host string
Port string
CertFlag string
KeyFlag string
Detector *detection.Service
SlasherDB db.Database
}

// NewService instantiates a new RPC service instance that will
// be registered into a running beacon node.
func NewService(ctx context.Context, cfg *Config) *Service {
ctx, cancel := context.WithCancel(ctx)
return &Service{
ctx: ctx,
cancel: cancel,
host: cfg.Host,
port: cfg.Port,
detector: cfg.Detector,
ctx: ctx,
cancel: cancel,
host: cfg.Host,
port: cfg.Port,
detector: cfg.Detector,
slasherDB: cfg.SlasherDB,
}
}

Expand Down Expand Up @@ -99,8 +103,9 @@ func (s *Service) Start() {
s.grpcServer = grpc.NewServer(opts...)

slasherServer := &Server{
ctx: s.ctx,
detector: s.detector,
ctx: s.ctx,
detector: s.detector,
slasherDB: s.slasherDB,
}
slashpb.RegisterSlasherServer(s.grpcServer, slasherServer)

Expand Down

0 comments on commit 93e68db

Please sign in to comment.