From 62effe829fb0acca361c90b47ab8463cf05bd662 Mon Sep 17 00:00:00 2001 From: rauljordan Date: Tue, 3 Mar 2020 14:10:20 -0600 Subject: [PATCH 1/3] rem slasher proto --- proto/slashing/slashing.proto | 8 +- slasher/rpc/BUILD.bazel | 20 - slasher/rpc/server.go | 201 +--------- slasher/rpc/server_test.go | 709 ---------------------------------- 4 files changed, 6 insertions(+), 932 deletions(-) delete mode 100644 slasher/rpc/server_test.go diff --git a/proto/slashing/slashing.proto b/proto/slashing/slashing.proto index 1bf086410ea4..5ffba3622b20 100644 --- a/proto/slashing/slashing.proto +++ b/proto/slashing/slashing.proto @@ -16,15 +16,9 @@ service Slasher { // was received produces a slashable event. rpc IsSlashableAttestation(ethereum.eth.v1alpha1.IndexedAttestation) returns (AttesterSlashingResponse); - // Gets ProposerSlashing container if the block header that + // Gets ProposerSlashing container if the block that // was received produces a slashable event. rpc IsSlashableBlock(ProposerSlashingRequest) returns (ProposerSlashingResponse); - - // Gets ProposerSlashingResponse container if slashing with the requested status are found in the db. - rpc ProposerSlashings(SlashingStatusRequest) returns (ProposerSlashingResponse); - - // Gets AttesterSlashingResponse container if slashing with the requested status are found in the db. - rpc AttesterSlashings(SlashingStatusRequest) returns (AttesterSlashingResponse); } // CompressedIdxAtt is an indexed attestation with the []byte data root diff --git a/slasher/rpc/BUILD.bazel b/slasher/rpc/BUILD.bazel index 83eceb73f9ca..6fe090ff44e6 100644 --- a/slasher/rpc/BUILD.bazel +++ b/slasher/rpc/BUILD.bazel @@ -6,30 +6,10 @@ go_library( importpath = "github.com/prysmaticlabs/prysm/slasher/rpc", visibility = ["//visibility:public"], deps = [ - "//beacon-chain/core/helpers:go_default_library", "//proto/slashing:go_default_library", - "//shared/hashutil:go_default_library", "//slasher/db/kv:go_default_library", - "//slasher/db/types:go_default_library", - "//slasher/detection/attestations:go_default_library", - "@com_github_gogo_protobuf//proto:go_default_library", "@com_github_pkg_errors//:go_default_library", "@com_github_prysmaticlabs_ethereumapis//eth/v1alpha1:go_default_library", - "@com_github_sirupsen_logrus//:go_default_library", - ], -) - -go_test( - name = "go_default_test", - srcs = ["server_test.go"], - embed = [":go_default_library"], - deps = [ - "//proto/slashing:go_default_library", - "//shared/params:go_default_library", - "//slasher/db/testing:go_default_library", - "//slasher/db/types:go_default_library", - "@com_github_gogo_protobuf//proto:go_default_library", - "@com_github_prysmaticlabs_ethereumapis//eth/v1alpha1:go_default_library", ], ) diff --git a/slasher/rpc/server.go b/slasher/rpc/server.go index 76604339c8c8..a6b5a55b570f 100644 --- a/slasher/rpc/server.go +++ b/slasher/rpc/server.go @@ -2,19 +2,11 @@ package rpc import ( "context" - "fmt" - "sync" - "github.com/gogo/protobuf/proto" "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/hashutil" "github.com/prysmaticlabs/prysm/slasher/db/kv" - "github.com/prysmaticlabs/prysm/slasher/db/types" - "github.com/prysmaticlabs/prysm/slasher/detection/attestations" - log "github.com/sirupsen/logrus" ) // Server defines a server implementation of the gRPC Slasher service, @@ -27,194 +19,11 @@ type Server struct { // 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) { - //TODO(#3133): add signature validation - if req.Data == nil { - return nil, fmt.Errorf("cant hash nil data in indexed attestation") - } - if err := ss.SlasherDB.SaveIndexedAttestation(ctx, req); err != nil { - return nil, err - } - indices := req.AttestingIndices - root, err := hashutil.HashProto(req.Data) - if err != nil { - return nil, err - } - attSlashingResp := &slashpb.AttesterSlashingResponse{} - attSlashings := make(chan []*ethpb.AttesterSlashing, len(indices)) - errorChans := make(chan error, len(indices)) - var wg sync.WaitGroup - lastIdx := int64(-1) - for _, idx := range indices { - if int64(idx) <= lastIdx { - return nil, fmt.Errorf("indexed attestation contains repeated or non sorted ids") - } - wg.Add(1) - go func(idx uint64, root [32]byte, req *ethpb.IndexedAttestation) { - atts, err := ss.SlasherDB.DoubleVotes(ctx, idx, root[:], req) - if err != nil { - errorChans <- err - wg.Done() - return - } - if atts != nil && len(atts) > 0 { - attSlashings <- atts - } - atts, err = ss.DetectSurroundVotes(ctx, idx, req) - if err != nil { - errorChans <- err - wg.Done() - return - } - if atts != nil && len(atts) > 0 { - attSlashings <- atts - } - wg.Done() - return - }(idx, root, req) - } - wg.Wait() - close(errorChans) - close(attSlashings) - for e := range errorChans { - if err != nil { - err = fmt.Errorf(err.Error() + " : " + e.Error()) - continue - } - err = e - } - for atts := range attSlashings { - attSlashingResp.AttesterSlashing = append(attSlashingResp.AttesterSlashing, atts...) - } - return attSlashingResp, err + return nil, errors.New("unimplemented") } -// UpdateSpanMaps updates and load all span maps from db. -func (ss *Server) UpdateSpanMaps(ctx context.Context, req *ethpb.IndexedAttestation) error { - indices := req.AttestingIndices - lastIdx := int64(-1) - var wg sync.WaitGroup - er := make(chan error, len(indices)) - for _, idx := range indices { - if int64(idx) <= lastIdx { - er <- fmt.Errorf("indexed attestation contains repeated or non sorted ids") - } - wg.Add(1) - go func(i uint64) { - spanMap, err := ss.SlasherDB.ValidatorSpansMap(ctx, i) - if err != nil { - er <- err - wg.Done() - return - } - if req.Data == nil { - log.Trace("Got indexed attestation with no data") - wg.Done() - return - } - spanMap, _, err = attestations.DetectAndUpdateSpans(ctx, spanMap, req) - if err != nil { - er <- err - wg.Done() - return - } - if err := ss.SlasherDB.SaveValidatorSpansMap(ctx, i, spanMap); err != nil { - er <- err - wg.Done() - return - } - }(idx) - wg.Wait() - } - close(er) - for e := range er { - log.Errorf("Got error while trying to update span maps: %v", e) - } - return nil -} - -// IsSlashableBlock returns a proposer slashing if the block header submitted is -// a slashable proposal. -func (ss *Server) IsSlashableBlock(ctx context.Context, psr *slashpb.ProposerSlashingRequest) (*slashpb.ProposerSlashingResponse, error) { - //TODO(#3133): add signature validation - epoch := helpers.SlotToEpoch(psr.BlockHeader.Header.Slot) - blockHeaders, err := ss.SlasherDB.BlockHeaders(ctx, epoch, psr.ValidatorIndex) - if err != nil { - return nil, errors.Wrap(err, "slasher service error while trying to retrieve blocks") - } - pSlashingsResponse := &slashpb.ProposerSlashingResponse{} - presentInDb := false - for _, bh := range blockHeaders { - if proto.Equal(bh, psr.BlockHeader) { - presentInDb = true - continue - } - pSlashingsResponse.ProposerSlashing = append(pSlashingsResponse.ProposerSlashing, ðpb.ProposerSlashing{ProposerIndex: psr.ValidatorIndex, Header_1: psr.BlockHeader, Header_2: bh}) - } - if len(pSlashingsResponse.ProposerSlashing) == 0 && !presentInDb { - err = ss.SlasherDB.SaveBlockHeader(ctx, epoch, psr.ValidatorIndex, psr.BlockHeader) - if err != nil { - return nil, err - } - } - return pSlashingsResponse, nil -} - -// ProposerSlashings returns proposer slashings if slashing with the requested status are found in the db. -func (ss *Server) ProposerSlashings(ctx context.Context, st *slashpb.SlashingStatusRequest) (*slashpb.ProposerSlashingResponse, error) { - pSlashingsResponse := &slashpb.ProposerSlashingResponse{} - var err error - pSlashingsResponse.ProposerSlashing, err = ss.SlasherDB.ProposalSlashingsByStatus(ctx, types.SlashingStatus(st.Status)) - if err != nil { - return nil, err - } - return pSlashingsResponse, nil -} - -// AttesterSlashings returns attester slashings if slashing with the requested status are found in the db. -func (ss *Server) AttesterSlashings(ctx context.Context, st *slashpb.SlashingStatusRequest) (*slashpb.AttesterSlashingResponse, error) { - aSlashingsResponse := &slashpb.AttesterSlashingResponse{} - var err error - aSlashingsResponse.AttesterSlashing, err = ss.SlasherDB.AttesterSlashings(ctx, types.SlashingStatus(st.Status)) - if err != nil { - return nil, err - } - return aSlashingsResponse, nil -} - -// DetectSurroundVotes is a method used to return the attestation that were detected -// by min max surround detection method. -func (ss *Server) DetectSurroundVotes(ctx context.Context, validatorIdx uint64, req *ethpb.IndexedAttestation) ([]*ethpb.AttesterSlashing, error) { - spanMap, err := ss.SlasherDB.ValidatorSpansMap(ctx, validatorIdx) - if err != nil { - return nil, errors.Wrap(err, "failed to get validator spans map") - } - spanMap, slashableEpoch, err := attestations.DetectAndUpdateSpans(ctx, spanMap, req) - if err != nil { - return nil, errors.Wrap(err, "failed to update spans") - } - if err := ss.SlasherDB.SaveValidatorSpansMap(ctx, validatorIdx, spanMap); err != nil { - return nil, errors.Wrap(err, "failed to save validator spans map") - } - - var as []*ethpb.AttesterSlashing - if slashableEpoch > 0 { - atts, err := ss.SlasherDB.IdxAttsForTargetFromID(ctx, slashableEpoch, validatorIdx) - if err != nil { - return nil, err - } - for _, ia := range atts { - if ia.Data == nil { - continue - } - surrounding := ia.Data.Source.Epoch < req.Data.Source.Epoch && ia.Data.Target.Epoch > req.Data.Target.Epoch - surrounded := ia.Data.Source.Epoch > req.Data.Source.Epoch && ia.Data.Target.Epoch < req.Data.Target.Epoch - if surrounding || surrounded { - as = append(as, ðpb.AttesterSlashing{ - Attestation_1: req, - Attestation_2: ia, - }) - } - } - } - return as, nil +// IsSlashableBlock returns an proposer slashing if the block submitted +// is a double proposal. +func (ss *Server) IsSlashableBlock(ctx context.Context, req *ethpb.BeaconBlock) (*slashpb.ProposerSlashingResponse, error) { + return nil, errors.New("unimplemented") } diff --git a/slasher/rpc/server_test.go b/slasher/rpc/server_test.go deleted file mode 100644 index 6cb1447acea1..000000000000 --- a/slasher/rpc/server_test.go +++ /dev/null @@ -1,709 +0,0 @@ -package rpc - -import ( - "context" - "strconv" - "testing" - - "github.com/gogo/protobuf/proto" - ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1" - slashpb "github.com/prysmaticlabs/prysm/proto/slashing" - "github.com/prysmaticlabs/prysm/shared/params" - testDB "github.com/prysmaticlabs/prysm/slasher/db/testing" - "github.com/prysmaticlabs/prysm/slasher/db/types" -) - -func TestServer_IsSlashableBlock(t *testing.T) { - t.Skip("undergoing slasher redesign") - db := testDB.SetupSlasherDB(t, false) - defer testDB.TeardownSlasherDB(t, db) - ctx := context.Background() - slasherServer := &Server{ - SlasherDB: db, - } - psr := &slashpb.ProposerSlashingRequest{ - BlockHeader: ðpb.SignedBeaconBlockHeader{ - Header: ðpb.BeaconBlockHeader{ - Slot: 1, - StateRoot: []byte("A"), - }, - }, - ValidatorIndex: 1, - } - psr2 := &slashpb.ProposerSlashingRequest{ - BlockHeader: ðpb.SignedBeaconBlockHeader{ - Header: ðpb.BeaconBlockHeader{ - Slot: 1, - StateRoot: []byte("B"), - }, - }, - ValidatorIndex: 1, - } - - if _, err := slasherServer.IsSlashableBlock(ctx, psr); err != nil { - t.Errorf("Could not call RPC method: %v", err) - } - sr, err := slasherServer.IsSlashableBlock(ctx, psr2) - if err != nil { - t.Errorf("Could not call RPC method: %v", err) - } - want := ðpb.ProposerSlashing{ - ProposerIndex: psr.ValidatorIndex, - Header_1: psr2.BlockHeader, - Header_2: psr.BlockHeader, - } - - if len(sr.ProposerSlashing) != 1 { - t.Errorf("Should return 1 slashing proof: %v", sr) - } - if !proto.Equal(sr.ProposerSlashing[0], want) { - t.Errorf("wanted slashing proof: %v got: %v", want, sr.ProposerSlashing[0]) - - } - -} - -func TestServer_IsNotSlashableBlock(t *testing.T) { - t.Skip("undergoing slasher redesign") - db := testDB.SetupSlasherDB(t, false) - defer testDB.TeardownSlasherDB(t, db) - - slasherServer := &Server{ - SlasherDB: db, - } - psr := &slashpb.ProposerSlashingRequest{ - BlockHeader: ðpb.SignedBeaconBlockHeader{ - Header: ðpb.BeaconBlockHeader{ - Slot: 1, - StateRoot: []byte("A"), - }, - }, - ValidatorIndex: 1, - } - psr2 := &slashpb.ProposerSlashingRequest{ - BlockHeader: ðpb.SignedBeaconBlockHeader{ - Header: ðpb.BeaconBlockHeader{ - Slot: 65, - StateRoot: []byte("B"), - }, - }, - ValidatorIndex: 1, - } - ctx := context.Background() - - if _, err := slasherServer.IsSlashableBlock(ctx, psr); err != nil { - t.Errorf("Could not call RPC method: %v", err) - } - sr, err := slasherServer.IsSlashableBlock(ctx, psr2) - if err != nil { - t.Errorf("Could not call RPC method: %v", err) - } - - if len(sr.ProposerSlashing) != 0 { - t.Errorf("Should return 0 slashing proof: %v", sr) - } - -} - -func TestServer_DoubleBlock(t *testing.T) { - t.Skip("undergoing slasher redesign") - db := testDB.SetupSlasherDB(t, false) - defer testDB.TeardownSlasherDB(t, db) - ctx := context.Background() - slasherServer := &Server{ - ctx: ctx, - SlasherDB: db, - } - psr := &slashpb.ProposerSlashingRequest{ - BlockHeader: ðpb.SignedBeaconBlockHeader{ - Header: ðpb.BeaconBlockHeader{ - Slot: 1, - StateRoot: []byte("A"), - }, - }, - ValidatorIndex: 1, - } - - if _, err := slasherServer.IsSlashableBlock(ctx, psr); err != nil { - t.Errorf("Could not call RPC method: %v", err) - } - sr, err := slasherServer.IsSlashableBlock(ctx, psr) - if err != nil { - t.Errorf("Could not call RPC method: %v", err) - } - - if len(sr.ProposerSlashing) != 0 { - t.Errorf("Should return 0 slashing proof: %v", sr) - } - -} - -func TestServer_SameSlotSlashable(t *testing.T) { - t.Skip("undergoing slasher redesign") - db := testDB.SetupSlasherDB(t, false) - defer testDB.TeardownSlasherDB(t, db) - ctx := context.Background() - - slasherServer := &Server{ - ctx: ctx, - SlasherDB: db, - } - psr := &slashpb.ProposerSlashingRequest{ - BlockHeader: ðpb.SignedBeaconBlockHeader{ - Header: ðpb.BeaconBlockHeader{ - Slot: 1, - StateRoot: []byte("A"), - }, - }, - ValidatorIndex: 1, - } - psr2 := &slashpb.ProposerSlashingRequest{ - BlockHeader: ðpb.SignedBeaconBlockHeader{ - Header: ðpb.BeaconBlockHeader{ - Slot: 1, - StateRoot: []byte("B"), - }, - }, - ValidatorIndex: 1, - } - want := ðpb.ProposerSlashing{ - ProposerIndex: psr.ValidatorIndex, - Header_1: psr2.BlockHeader, - Header_2: psr.BlockHeader, - } - - if _, err := slasherServer.IsSlashableBlock(ctx, psr); err != nil { - t.Errorf("Could not call RPC method: %v", err) - } - sr, err := slasherServer.IsSlashableBlock(ctx, psr2) - if err != nil { - t.Errorf("Could not call RPC method: %v", err) - } - - if len(sr.ProposerSlashing) != 1 { - t.Errorf("Should return 1 slashing proof: %v", sr) - } - if !proto.Equal(sr.ProposerSlashing[0], want) { - t.Errorf("wanted slashing proof: %v got: %v", want, sr.ProposerSlashing[0]) - - } - if err := slasherServer.SlasherDB.SaveProposerSlashing(ctx, types.Active, sr.ProposerSlashing[0]); err != nil { - t.Errorf("Could not call db method: %v", err) - } - if sr, err = slasherServer.ProposerSlashings(ctx, &slashpb.SlashingStatusRequest{Status: slashpb.SlashingStatusRequest_Active}); err != nil { - t.Errorf("Could not call RPC method: %v", err) - } - ar, err := slasherServer.AttesterSlashings(ctx, &slashpb.SlashingStatusRequest{Status: slashpb.SlashingStatusRequest_Active}) - if err != nil { - t.Errorf("Could not call RPC method: %v", err) - } - if len(ar.AttesterSlashing) > 0 { - t.Errorf("Attester slashings with status 'active' should not be present in testDB.") - } - emptySlashingResponse, err := slasherServer.ProposerSlashings(ctx, &slashpb.SlashingStatusRequest{Status: slashpb.SlashingStatusRequest_Included}) - if err != nil { - t.Errorf("Could not call RPC method: %v", err) - } - if len(emptySlashingResponse.ProposerSlashing) > 0 { - t.Error("Proposer slashings with status 'included' should not be present in db") - } - if !proto.Equal(sr.ProposerSlashing[0], want) { - t.Errorf("Wanted slashing proof: %v got: %v", want, sr.ProposerSlashing[0]) - } -} - -func TestServer_SlashDoubleAttestation(t *testing.T) { - t.Skip("undergoing slasher redesign") - db := testDB.SetupSlasherDB(t, false) - defer testDB.TeardownSlasherDB(t, db) - ctx := context.Background() - - slasherServer := &Server{ - ctx: ctx, - SlasherDB: db, - } - ia1 := ðpb.IndexedAttestation{ - AttestingIndices: []uint64{0}, - Signature: []byte("sig2"), - Data: ðpb.AttestationData{ - Slot: 3*params.BeaconConfig().SlotsPerEpoch + 1, - CommitteeIndex: 0, - BeaconBlockRoot: []byte("block1"), - Source: ðpb.Checkpoint{Epoch: 2}, - Target: ðpb.Checkpoint{Epoch: 3}, - }, - } - ia2 := ðpb.IndexedAttestation{ - AttestingIndices: []uint64{0}, - Signature: []byte("sig1"), - Data: ðpb.AttestationData{ - Slot: 3*params.BeaconConfig().SlotsPerEpoch + 1, - CommitteeIndex: 0, - BeaconBlockRoot: []byte("block2"), - Source: ðpb.Checkpoint{Epoch: 2}, - Target: ðpb.Checkpoint{Epoch: 3}, - }, - } - want := ðpb.AttesterSlashing{ - Attestation_1: ia2, - Attestation_2: ia1, - } - - if _, err := slasherServer.IsSlashableAttestation(ctx, ia1); err != nil { - t.Errorf("Could not call RPC method: %v", err) - } - sr, err := slasherServer.IsSlashableAttestation(ctx, ia2) - if err != nil { - t.Errorf("Could not call RPC method: %v", err) - } - - if len(sr.AttesterSlashing) != 1 { - t.Errorf("Should return 1 slashing proof: %v", sr) - } - if !proto.Equal(sr.AttesterSlashing[0], want) { - t.Errorf("Wanted slashing proof: %v got: %v", want, sr.AttesterSlashing[0]) - - } -} - -func TestServer_SlashTripleAttestation(t *testing.T) { - t.Skip("undergoing slasher redesign") - db := testDB.SetupSlasherDB(t, false) - defer testDB.TeardownSlasherDB(t, db) - ctx := context.Background() - slasherServer := &Server{ - ctx: ctx, - SlasherDB: db, - } - ia1 := ðpb.IndexedAttestation{ - AttestingIndices: []uint64{0}, - Signature: []byte("sig1"), - Data: ðpb.AttestationData{ - Slot: 3*params.BeaconConfig().SlotsPerEpoch + 1, - CommitteeIndex: 0, - BeaconBlockRoot: []byte("block1"), - Source: ðpb.Checkpoint{Epoch: 2}, - Target: ðpb.Checkpoint{Epoch: 3}, - }, - } - ia2 := ðpb.IndexedAttestation{ - AttestingIndices: []uint64{0}, - Signature: []byte("sig2"), - Data: ðpb.AttestationData{ - Slot: 3*params.BeaconConfig().SlotsPerEpoch + 1, - CommitteeIndex: 0, - BeaconBlockRoot: []byte("block2"), - Source: ðpb.Checkpoint{Epoch: 2}, - Target: ðpb.Checkpoint{Epoch: 3}, - }, - } - ia3 := ðpb.IndexedAttestation{ - AttestingIndices: []uint64{0}, - Signature: []byte("sig3"), - Data: ðpb.AttestationData{ - Slot: 3*params.BeaconConfig().SlotsPerEpoch + 1, - CommitteeIndex: 0, - BeaconBlockRoot: []byte("block3"), - Source: ðpb.Checkpoint{Epoch: 2}, - Target: ðpb.Checkpoint{Epoch: 3}, - }, - } - want1 := ðpb.AttesterSlashing{ - Attestation_1: ia3, - Attestation_2: ia1, - } - want2 := ðpb.AttesterSlashing{ - Attestation_1: ia3, - Attestation_2: ia2, - } - - if _, err := slasherServer.IsSlashableAttestation(ctx, ia1); err != nil { - t.Errorf("Could not call RPC method: %v", err) - } - _, err := slasherServer.IsSlashableAttestation(ctx, ia2) - if err != nil { - t.Errorf("Could not call RPC method: %v", err) - } - sr, err := slasherServer.IsSlashableAttestation(ctx, ia3) - if err != nil { - t.Errorf("Could not call RPC method: %v", err) - } - if len(sr.AttesterSlashing) != 2 { - t.Errorf("Should return 1 slashing proof: %v", sr) - } - if !proto.Equal(sr.AttesterSlashing[0], want1) { - t.Errorf("Wanted slashing proof: %v got: %v", want1, sr.AttesterSlashing[0]) - - } - if !proto.Equal(sr.AttesterSlashing[1], want2) { - t.Errorf("Wanted slashing proof: %v got: %v", want2, sr.AttesterSlashing[0]) - - } -} - -func TestServer_DontSlashSameAttestation(t *testing.T) { - t.Skip("undergoing slasher redesign") - db := testDB.SetupSlasherDB(t, false) - defer testDB.TeardownSlasherDB(t, db) - ctx := context.Background() - slasherServer := &Server{ - ctx: ctx, - SlasherDB: db, - } - ia1 := ðpb.IndexedAttestation{ - AttestingIndices: []uint64{0}, - Signature: []byte("sig1"), - Data: ðpb.AttestationData{ - Slot: 3*params.BeaconConfig().SlotsPerEpoch + 1, - CommitteeIndex: 0, - BeaconBlockRoot: []byte("block1"), - Source: ðpb.Checkpoint{Epoch: 2}, - Target: ðpb.Checkpoint{Epoch: 3}, - }, - } - - if _, err := slasherServer.IsSlashableAttestation(ctx, ia1); err != nil { - t.Errorf("Could not call RPC method: %v", err) - } - sr, err := slasherServer.IsSlashableAttestation(ctx, ia1) - if err != nil { - t.Errorf("Could not call RPC method: %v", err) - } - - if len(sr.AttesterSlashing) != 0 { - t.Errorf("Should not return slashing proof for same attestation: %v", sr) - } -} - -func TestServer_DontSlashDifferentTargetAttestation(t *testing.T) { - t.Skip("undergoing slasher redesign") - db := testDB.SetupSlasherDB(t, false) - defer testDB.TeardownSlasherDB(t, db) - ctx := context.Background() - slasherServer := &Server{ - ctx: ctx, - SlasherDB: db, - } - ia1 := ðpb.IndexedAttestation{ - AttestingIndices: []uint64{0}, - Signature: []byte("sig2"), - Data: ðpb.AttestationData{ - Slot: 3*params.BeaconConfig().SlotsPerEpoch + 1, - CommitteeIndex: 0, - BeaconBlockRoot: []byte("block1"), - Source: ðpb.Checkpoint{Epoch: 2}, - Target: ðpb.Checkpoint{Epoch: 3}, - }, - } - ia2 := ðpb.IndexedAttestation{ - AttestingIndices: []uint64{0}, - Signature: []byte("sig1"), - Data: ðpb.AttestationData{ - Slot: 4*params.BeaconConfig().SlotsPerEpoch + 1, - CommitteeIndex: 0, - BeaconBlockRoot: []byte("block2"), - Source: ðpb.Checkpoint{Epoch: 3}, - Target: ðpb.Checkpoint{Epoch: 4}, - }, - } - - if _, err := slasherServer.IsSlashableAttestation(ctx, ia1); err != nil { - t.Errorf("Could not call RPC method: %v", err) - } - sr, err := slasherServer.IsSlashableAttestation(ctx, ia2) - if err != nil { - t.Errorf("Could not call RPC method: %v", err) - } - - if len(sr.AttesterSlashing) != 0 { - t.Errorf("Should not return slashing proof for different epoch attestation: %v", sr) - } -} - -func TestServer_DontSlashSameAttestationData(t *testing.T) { - t.Skip("undergoing slasher redesign") - db := testDB.SetupSlasherDB(t, false) - defer testDB.TeardownSlasherDB(t, db) - ctx := context.Background() - slasherServer := &Server{ - ctx: ctx, - SlasherDB: db, - } - ad := ðpb.AttestationData{ - Slot: 3*params.BeaconConfig().SlotsPerEpoch + 1, - CommitteeIndex: 0, - BeaconBlockRoot: []byte("block1"), - Source: ðpb.Checkpoint{Epoch: 2}, - Target: ðpb.Checkpoint{Epoch: 3}, - } - ia1 := ðpb.IndexedAttestation{ - AttestingIndices: []uint64{0}, - Signature: []byte("sig2"), - Data: ad, - } - ia2 := ðpb.IndexedAttestation{ - AttestingIndices: []uint64{0}, - Signature: []byte("sig1"), - Data: ad, - } - - if _, err := slasherServer.IsSlashableAttestation(ctx, ia1); err != nil { - t.Errorf("Could not call RPC method: %v", err) - } - sr, err := slasherServer.IsSlashableAttestation(ctx, ia2) - if err != nil { - t.Errorf("Could not call RPC method: %v", err) - } - - if len(sr.AttesterSlashing) != 0 { - t.Errorf("Should not return slashing proof for same data: %v", sr) - } -} - -func TestServer_SlashSurroundedAttestation(t *testing.T) { - t.Skip("undergoing slasher redesign") - db := testDB.SetupSlasherDB(t, false) - defer testDB.TeardownSlasherDB(t, db) - ctx := context.Background() - slasherServer := &Server{ - ctx: ctx, - SlasherDB: db, - } - ia1 := ðpb.IndexedAttestation{ - AttestingIndices: []uint64{0}, - Signature: []byte("sig2"), - Data: ðpb.AttestationData{ - Slot: 4*params.BeaconConfig().SlotsPerEpoch + 1, - CommitteeIndex: 0, - BeaconBlockRoot: []byte("block1"), - Source: ðpb.Checkpoint{Epoch: 1}, - Target: ðpb.Checkpoint{Epoch: 4}, - }, - } - ia2 := ðpb.IndexedAttestation{ - AttestingIndices: []uint64{0}, - Signature: []byte("sig1"), - Data: ðpb.AttestationData{ - Slot: 4*params.BeaconConfig().SlotsPerEpoch + 1, - CommitteeIndex: 0, - BeaconBlockRoot: []byte("block2"), - Source: ðpb.Checkpoint{Epoch: 2}, - Target: ðpb.Checkpoint{Epoch: 3}, - }, - } - want := ðpb.AttesterSlashing{ - Attestation_1: ia2, - Attestation_2: ia1, - } - - if _, err := slasherServer.IsSlashableAttestation(ctx, ia1); err != nil { - t.Errorf("Could not call RPC method: %v", err) - } - sr, err := slasherServer.IsSlashableAttestation(ctx, ia2) - if err != nil { - t.Errorf("Could not call RPC method: %v", err) - } - if len(sr.AttesterSlashing) != 1 { - t.Fatalf("Should return 1 slashing proof: %v", sr.AttesterSlashing) - } - if !proto.Equal(sr.AttesterSlashing[0], want) { - t.Errorf("Wanted slashing proof: %v got: %v", want, sr.AttesterSlashing[0]) - - } -} - -func TestServer_SlashSurroundAttestation(t *testing.T) { - t.Skip("undergoing slasher redesign") - db := testDB.SetupSlasherDB(t, false) - defer testDB.TeardownSlasherDB(t, db) - ctx := context.Background() - slasherServer := &Server{ - ctx: ctx, - SlasherDB: db, - } - ia1 := ðpb.IndexedAttestation{ - AttestingIndices: []uint64{0}, - Signature: []byte("sig2"), - Data: ðpb.AttestationData{ - Slot: 4*params.BeaconConfig().SlotsPerEpoch + 1, - CommitteeIndex: 0, - BeaconBlockRoot: []byte("block1"), - Source: ðpb.Checkpoint{Epoch: 2}, - Target: ðpb.Checkpoint{Epoch: 3}, - }, - } - ia2 := ðpb.IndexedAttestation{ - AttestingIndices: []uint64{0}, - Signature: []byte("sig1"), - Data: ðpb.AttestationData{ - Slot: 4*params.BeaconConfig().SlotsPerEpoch + 1, - CommitteeIndex: 0, - BeaconBlockRoot: []byte("block2"), - Source: ðpb.Checkpoint{Epoch: 1}, - Target: ðpb.Checkpoint{Epoch: 4}, - }, - } - want := ðpb.AttesterSlashing{ - Attestation_1: ia2, - Attestation_2: ia1, - } - - if _, err := slasherServer.IsSlashableAttestation(ctx, ia1); err != nil { - t.Errorf("Could not call RPC method: %v", err) - } - sr, err := slasherServer.IsSlashableAttestation(ctx, ia2) - if err != nil { - t.Errorf("Could not call RPC method: %v", err) - } - if len(sr.AttesterSlashing) != 1 { - t.Fatalf("Should return 1 slashing proof: %v", sr.AttesterSlashing) - } - if !proto.Equal(sr.AttesterSlashing[0], want) { - t.Errorf("Wanted slashing proof: %v got: %v", want, sr.AttesterSlashing[0]) - - } - if err := slasherServer.SlasherDB.SaveAttesterSlashing(ctx, types.Active, sr.AttesterSlashing[0]); err != nil { - t.Errorf("Could not call db method: %v", err) - } - pr, err := slasherServer.ProposerSlashings(ctx, &slashpb.SlashingStatusRequest{Status: slashpb.SlashingStatusRequest_Active}) - if err != nil { - t.Errorf("Could not call RPC method: %v", err) - } - if len(pr.ProposerSlashing) > 0 { - t.Errorf("Attester slashings with status 'active' should not be present in testDB.") - } - if sr, err = slasherServer.AttesterSlashings(ctx, &slashpb.SlashingStatusRequest{Status: slashpb.SlashingStatusRequest_Active}); err != nil { - t.Errorf("Could not call RPC method: %v", err) - } - emptySlashingResponse, err := slasherServer.AttesterSlashings(ctx, &slashpb.SlashingStatusRequest{Status: slashpb.SlashingStatusRequest_Included}) - if err != nil { - t.Errorf("Could not call RPC method: %v", err) - } - if len(emptySlashingResponse.AttesterSlashing) > 0 { - t.Error("Attester slashings with status 'included' should not be present in db") - } - if !proto.Equal(sr.AttesterSlashing[0], want) { - t.Errorf("Wanted slashing proof: %v got: %v", want, sr.AttesterSlashing[0]) - } -} - -func TestServer_DontSlashValidAttestations(t *testing.T) { - t.Skip("undergoing slasher redesign") - db := testDB.SetupSlasherDB(t, false) - defer testDB.TeardownSlasherDB(t, db) - ctx := context.Background() - slasherServer := &Server{ - ctx: ctx, - SlasherDB: db, - } - ia1 := ðpb.IndexedAttestation{ - AttestingIndices: []uint64{0}, - Signature: []byte("sig2"), - Data: ðpb.AttestationData{ - Slot: 5*params.BeaconConfig().SlotsPerEpoch + 1, - CommitteeIndex: 0, - BeaconBlockRoot: []byte("block1"), - Source: ðpb.Checkpoint{Epoch: 2}, - Target: ðpb.Checkpoint{Epoch: 4}, - }, - } - ia2 := ðpb.IndexedAttestation{ - AttestingIndices: []uint64{0}, - Signature: []byte("sig1"), - Data: ðpb.AttestationData{ - Slot: 5*params.BeaconConfig().SlotsPerEpoch + 1, - CommitteeIndex: 0, - BeaconBlockRoot: []byte("block2"), - Source: ðpb.Checkpoint{Epoch: 3}, - Target: ðpb.Checkpoint{Epoch: 5}, - }, - } - - if _, err := slasherServer.IsSlashableAttestation(ctx, ia1); err != nil { - t.Errorf("Could not call RPC method: %v", err) - } - sr, err := slasherServer.IsSlashableAttestation(ctx, ia2) - if err != nil { - t.Errorf("Could not call RPC method: %v", err) - } - if len(sr.AttesterSlashing) != 0 { - t.Errorf("Should not return slashing proof for same data: %v", sr) - } -} - -func TestServer_Store_100_Attestations(t *testing.T) { - t.Skip("undergoing slasher redesign") - db := testDB.SetupSlasherDB(t, false) - defer testDB.TeardownSlasherDB(t, db) - ctx := context.Background() - slasherServer := &Server{ - ctx: ctx, - SlasherDB: db, - } - var cb []uint64 - for i := uint64(0); i < 100; i++ { - cb = append(cb, i) - } - ia1 := ðpb.IndexedAttestation{ - AttestingIndices: cb, - Data: ðpb.AttestationData{ - CommitteeIndex: 0, - BeaconBlockRoot: make([]byte, 32), - Source: ðpb.Checkpoint{Epoch: 2}, - Target: ðpb.Checkpoint{Epoch: 4}, - }, - } - for i := uint64(0); i < 100; i++ { - ia1.Data.Target.Epoch = i + 1 - ia1.Data.Source.Epoch = i - t.Logf("In Loop: %d", i) - ia1.Data.Slot = (i + 1) * params.BeaconConfig().SlotsPerEpoch - root := []byte(strconv.Itoa(int(i))) - ia1.Data.BeaconBlockRoot = append(root, ia1.Data.BeaconBlockRoot[len(root):]...) - if _, err := slasherServer.IsSlashableAttestation(ctx, ia1); err != nil { - t.Errorf("Could not call RPC method: %v", err) - } - } - - s, err := db.Size() - if err != nil { - t.Error(err) - } - t.Logf("DB size is: %d", s) -} - -func BenchmarkCheckAttestations(b *testing.B) { - db := testDB.SetupSlasherDB(b, true) - defer testDB.TeardownSlasherDB(b, db) - context := context.Background() - - slasherServer := &Server{ - ctx: context, - SlasherDB: db, - } - var cb []uint64 - for i := uint64(0); i < 100; i++ { - cb = append(cb, i) - } - ia1 := ðpb.IndexedAttestation{ - AttestingIndices: cb, - Signature: make([]byte, 96), - Data: ðpb.AttestationData{ - CommitteeIndex: 0, - BeaconBlockRoot: make([]byte, 32), - Source: ðpb.Checkpoint{Epoch: 2}, - Target: ðpb.Checkpoint{Epoch: 4}, - }, - } - b.ResetTimer() - for i := uint64(0); i < uint64(b.N); i++ { - ia1.Data.Target.Epoch = i + 1 - ia1.Data.Source.Epoch = i - ia1.Data.Slot = (i + 1) * params.BeaconConfig().SlotsPerEpoch - root := []byte(strconv.Itoa(int(i))) - ia1.Data.BeaconBlockRoot = append(root, ia1.Data.BeaconBlockRoot[len(root):]...) - if _, err := slasherServer.IsSlashableAttestation(context, ia1); err != nil { - b.Errorf("Could not call RPC method: %v", err) - } - } -} From bc4f9d4d3d1017e26260288f84b2ddd7b77aaa60 Mon Sep 17 00:00:00 2001 From: rauljordan Date: Wed, 11 Mar 2020 10:58:47 -0500 Subject: [PATCH 2/3] included new ssz bzl rule --- WORKSPACE | 7 +++++++ tools/ssz.bzl | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) create mode 100644 tools/ssz.bzl diff --git a/WORKSPACE b/WORKSPACE index 28a09120d362..db18f14627f1 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -1591,3 +1591,10 @@ go_repository( sum = "h1:J1gHJRNFEk7NdiaPQQqAvxEy+7hhCsVv3uzduWybmqY=", version = "v0.0.0-20200302201340-8c54356e12c9", ) + +go_repository( + name = "com_github_ferranbt_fastssz", + importpath = "github.com/ferranbt/fastssz", + sum = "h1:oUQredbOIzWIMmeGR9dTLzSi4DqRVwxrPzSDiLJBp4Q=", + version = "v0.0.0-20200310214500-3283b9706406", +) diff --git a/tools/ssz.bzl b/tools/ssz.bzl new file mode 100644 index 000000000000..ed8ae72cd855 --- /dev/null +++ b/tools/ssz.bzl @@ -0,0 +1,46 @@ +load( + "@io_bazel_rules_go//go:def.bzl", + "GoLibrary", +) + +def _ssz_go_proto_library_impl(ctx): + go_proto = ctx.attr.go_proto + + generated_pb_go_files = go_proto[OutputGroupInfo].go_generated_srcs + + # Run the tool on the generated files + package_path = generated_pb_go_files.to_list()[0].dirname + output = ctx.outputs.out + args = [ + "--output=%s" % output.path, + "--path=%s" % package_path, + ] + if len(ctx.attr.objs) > 0: + args += ["--objs=%s" % ",".join(ctx.attr.objs)] + ctx.actions.run( + executable = ctx.executable.sszgen, + progress_message = "Generating ssz marshal and unmarshal functions", + inputs = generated_pb_go_files, + arguments = args, + outputs = [output], + ) + +""" +A rule that extends a go_proto_library rule with generated ssz marshal functions. +TODO: Update this documentation before merge. +""" +ssz_gen_marshal = rule( + implementation = _ssz_go_proto_library_impl, + attrs = { + "go_proto": attr.label(providers = [GoLibrary]), + "sszgen": attr.label( + default = Label("@com_github_ferranbt_fastssz//sszgen:sszgen"), + executable = True, + cfg = "host", + ), + "objs": attr.string_list(), + }, + outputs = {"out": "generated.ssz.go"}, +) + +SSZ_DEPS = ["@com_github_ferranbt_fastssz//:go_default_library"] \ No newline at end of file From 21d42d77aad7c8645fa6b3cd45cfba9458fbee57 Mon Sep 17 00:00:00 2001 From: Raul Jordan Date: Wed, 11 Mar 2020 14:34:57 -0500 Subject: [PATCH 3/3] Update tools/ssz.bzl Co-Authored-By: Preston Van Loon --- tools/ssz.bzl | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/tools/ssz.bzl b/tools/ssz.bzl index ed8ae72cd855..783f7447f0ef 100644 --- a/tools/ssz.bzl +++ b/tools/ssz.bzl @@ -26,8 +26,32 @@ def _ssz_go_proto_library_impl(ctx): ) """ -A rule that extends a go_proto_library rule with generated ssz marshal functions. -TODO: Update this documentation before merge. +A rule that uses the generated pb.go files from a go_proto_library target to generate SSZ marshal +and unmarshal functions as pointer receivers on the specified objects. To use this rule, provide a +go_proto_library target and specify the structs to generate methods in the "objs" field. Lastly, +include your new target as a source for the go_library that embeds the go_proto_library. + +Example: +go_proto_library( + name = "example_go_proto", + ... +) + +ssz_gen_marshal( + name = "ssz_generated_sources", + go_proto = ":example_go_proto", + objs = [ # omit this field to generate for all structs in the package. + "AddressBook", + "Person", + ], +) + +go_library( + name = "go_default_library", + srcs = [":ssz_generated_sources"], + embed = [":example_go_proto"], + deps = SSZ_DEPS, +) """ ssz_gen_marshal = rule( implementation = _ssz_go_proto_library_impl, @@ -43,4 +67,4 @@ ssz_gen_marshal = rule( outputs = {"out": "generated.ssz.go"}, ) -SSZ_DEPS = ["@com_github_ferranbt_fastssz//:go_default_library"] \ No newline at end of file +SSZ_DEPS = ["@com_github_ferranbt_fastssz//:go_default_library"]