Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Merged by Bors] - malfeasance2: update GRPC API #6557

Closed
wants to merge 9 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 33 additions & 3 deletions api/grpcserver/activation_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@ import (
"google.golang.org/grpc/status"
"google.golang.org/protobuf/types/known/emptypb"

"github.com/spacemeshos/go-spacemesh/codec"
"github.com/spacemeshos/go-spacemesh/common/types"
"github.com/spacemeshos/go-spacemesh/events"
"github.com/spacemeshos/go-spacemesh/malfeasance/wire"
"github.com/spacemeshos/go-spacemesh/sql"
)

Expand Down Expand Up @@ -75,7 +76,6 @@ func (s *activationService) Get(ctx context.Context, request *pb.GetRequest) (*p
proof, err := s.atxProvider.MalfeasanceProof(atx.SmesherID)
if err != nil && !errors.Is(err, sql.ErrNotFound) {
ctxzap.Error(ctx, "failed to get malfeasance proof",
zap.Stringer("smesher", atx.SmesherID),
zap.Stringer("smesher", atx.SmesherID),
zap.Stringer("id", atxId),
zap.Error(err),
Expand All @@ -86,7 +86,7 @@ func (s *activationService) Get(ctx context.Context, request *pb.GetRequest) (*p
Atx: convertActivation(atx, prev),
}
if proof != nil {
resp.MalfeasanceProof = events.ToMalfeasancePB(atx.SmesherID, proof, false)
resp.MalfeasanceProof = toMalfeasancePB(atx.SmesherID, proof, false)
}
return resp, nil
}
Expand Down Expand Up @@ -117,3 +117,33 @@ func (s *activationService) Highest(ctx context.Context, req *emptypb.Empty) (*p
Atx: convertActivation(atx, prev),
}, nil
}

func toMalfeasancePB(nodeID types.NodeID, proof []byte, includeProof bool) *pb.MalfeasanceProof {
mp := &wire.MalfeasanceProof{}
if err := codec.Decode(proof, mp); err != nil {
return &pb.MalfeasanceProof{}
}
kind := pb.MalfeasanceProof_MALFEASANCE_UNSPECIFIED
switch mp.Proof.Type {
case wire.MultipleATXs:
kind = pb.MalfeasanceProof_MALFEASANCE_ATX
case wire.MultipleBallots:
kind = pb.MalfeasanceProof_MALFEASANCE_BALLOT
case wire.HareEquivocation:
kind = pb.MalfeasanceProof_MALFEASANCE_HARE
case wire.InvalidPostIndex:
kind = pb.MalfeasanceProof_MALFEASANCE_POST_INDEX
case wire.InvalidPrevATX:
kind = pb.MalfeasanceProof_MALFEASANCE_INCORRECT_PREV_ATX
}
result := &pb.MalfeasanceProof{
SmesherId: &pb.SmesherId{Id: nodeID.Bytes()},
Layer: &pb.LayerNumber{Number: mp.Layer.Uint32()},
Kind: kind,
DebugInfo: wire.MalfeasanceInfo(nodeID, mp),
}
if includeProof {
result.Proof = proof
}
return result
}
40 changes: 19 additions & 21 deletions api/grpcserver/activation_service_test.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package grpcserver_test
package grpcserver

import (
"context"
Expand All @@ -13,19 +13,17 @@ import (
"google.golang.org/grpc/status"
"google.golang.org/protobuf/types/known/emptypb"

"github.com/spacemeshos/go-spacemesh/api/grpcserver"
"github.com/spacemeshos/go-spacemesh/codec"
"github.com/spacemeshos/go-spacemesh/common/types"
"github.com/spacemeshos/go-spacemesh/events"
"github.com/spacemeshos/go-spacemesh/sql"
"github.com/spacemeshos/go-spacemesh/sql/statesql"
)

func Test_Highest_ReturnsGoldenAtxOnError(t *testing.T) {
ctrl := gomock.NewController(t)
atxProvider := grpcserver.NewMockatxProvider(ctrl)
atxProvider := NewMockatxProvider(ctrl)
goldenAtx := types.ATXID{2, 3, 4}
activationService := grpcserver.NewActivationService(atxProvider, goldenAtx)
activationService := NewActivationService(atxProvider, goldenAtx)

atxProvider.EXPECT().MaxHeightAtx().Return(types.EmptyATXID, errors.New("blah"))
response, err := activationService.Highest(context.Background(), &emptypb.Empty{})
Expand All @@ -41,9 +39,9 @@ func Test_Highest_ReturnsGoldenAtxOnError(t *testing.T) {

func Test_Highest_ReturnsMaxTickHeight(t *testing.T) {
ctrl := gomock.NewController(t)
atxProvider := grpcserver.NewMockatxProvider(ctrl)
atxProvider := NewMockatxProvider(ctrl)
goldenAtx := types.ATXID{2, 3, 4}
activationService := grpcserver.NewActivationService(atxProvider, goldenAtx)
activationService := NewActivationService(atxProvider, goldenAtx)

previous := types.RandomATXID()
atx := types.ActivationTx{
Expand Down Expand Up @@ -71,8 +69,8 @@ func Test_Highest_ReturnsMaxTickHeight(t *testing.T) {

func TestGet_RejectInvalidAtxID(t *testing.T) {
ctrl := gomock.NewController(t)
atxProvider := grpcserver.NewMockatxProvider(ctrl)
activationService := grpcserver.NewActivationService(atxProvider, types.ATXID{1})
atxProvider := NewMockatxProvider(ctrl)
activationService := NewActivationService(atxProvider, types.ATXID{1})

_, err := activationService.Get(context.Background(), &pb.GetRequest{Id: []byte{1, 2, 3}})
require.Error(t, err)
Expand All @@ -81,8 +79,8 @@ func TestGet_RejectInvalidAtxID(t *testing.T) {

func TestGet_AtxNotPresent(t *testing.T) {
ctrl := gomock.NewController(t)
atxProvider := grpcserver.NewMockatxProvider(ctrl)
activationService := grpcserver.NewActivationService(atxProvider, types.ATXID{1})
atxProvider := NewMockatxProvider(ctrl)
activationService := NewActivationService(atxProvider, types.ATXID{1})

id := types.RandomATXID()
atxProvider.EXPECT().GetAtx(id).Return(nil, nil)
Expand All @@ -94,8 +92,8 @@ func TestGet_AtxNotPresent(t *testing.T) {

func TestGet_AtxProviderReturnsFailure(t *testing.T) {
ctrl := gomock.NewController(t)
atxProvider := grpcserver.NewMockatxProvider(ctrl)
activationService := grpcserver.NewActivationService(atxProvider, types.ATXID{1})
atxProvider := NewMockatxProvider(ctrl)
activationService := NewActivationService(atxProvider, types.ATXID{1})

id := types.RandomATXID()
atxProvider.EXPECT().GetAtx(id).Return(&types.ActivationTx{}, errors.New(""))
Expand All @@ -107,8 +105,8 @@ func TestGet_AtxProviderReturnsFailure(t *testing.T) {

func TestGet_AtxProviderFailsObtainPreviousAtxs(t *testing.T) {
ctrl := gomock.NewController(t)
atxProvider := grpcserver.NewMockatxProvider(ctrl)
activationService := grpcserver.NewActivationService(atxProvider, types.ATXID{1})
atxProvider := NewMockatxProvider(ctrl)
activationService := NewActivationService(atxProvider, types.ATXID{1})

id := types.RandomATXID()
atxProvider.EXPECT().GetAtx(id).Return(&types.ActivationTx{}, nil)
Expand All @@ -121,8 +119,8 @@ func TestGet_AtxProviderFailsObtainPreviousAtxs(t *testing.T) {

func TestGet_HappyPath(t *testing.T) {
ctrl := gomock.NewController(t)
atxProvider := grpcserver.NewMockatxProvider(ctrl)
activationService := grpcserver.NewActivationService(atxProvider, types.ATXID{1})
atxProvider := NewMockatxProvider(ctrl)
activationService := NewActivationService(atxProvider, types.ATXID{1})

previous := []types.ATXID{types.RandomATXID(), types.RandomATXID()}
id := types.RandomATXID()
Expand Down Expand Up @@ -155,10 +153,10 @@ func TestGet_HappyPath(t *testing.T) {

func TestGet_IdentityCanceled(t *testing.T) {
ctrl := gomock.NewController(t)
atxProvider := grpcserver.NewMockatxProvider(ctrl)
activationService := grpcserver.NewActivationService(atxProvider, types.ATXID{1})
atxProvider := NewMockatxProvider(ctrl)
activationService := NewActivationService(atxProvider, types.ATXID{1})

smesher, proof := grpcserver.BallotMalfeasance(t, statesql.InMemoryTest(t))
smesher, proof := BallotMalfeasance(t, statesql.InMemoryTest(t))
previous := types.RandomATXID()
id := types.RandomATXID()
atx := types.ActivationTx{
Expand All @@ -185,5 +183,5 @@ func TestGet_IdentityCanceled(t *testing.T) {
require.Equal(t, previous.Bytes(), response.Atx.PreviousAtxs[0].Id)
require.Equal(t, atx.NumUnits, response.Atx.NumUnits)
require.Equal(t, atx.Sequence, response.Atx.Sequence)
require.Equal(t, events.ToMalfeasancePB(smesher, codec.MustEncode(proof), false), response.MalfeasanceProof)
require.Equal(t, toMalfeasancePB(smesher, codec.MustEncode(proof), false), response.MalfeasanceProof)
}
2 changes: 1 addition & 1 deletion api/grpcserver/debug_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ func castEventProposal(ev *events.EventProposal) *pb.Proposal {
for _, el := range ev.Proposal.Ballot.EligibilityProofs {
proposal.Eligibilities = append(proposal.Eligibilities, &pb.Eligibility{
J: el.J,
Signature: el.Sig[:],
Signature: el.Sig.Bytes(),
})
}
return proposal
Expand Down
19 changes: 13 additions & 6 deletions api/grpcserver/mesh_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -615,7 +615,7 @@ func (s *MeshService) MalfeasanceQuery(
return nil, status.Error(codes.Internal, err.Error())
}
return &pb.MalfeasanceResponse{
Proof: events.ToMalfeasancePB(id, proof, req.IncludeProof),
Proof: toMalfeasancePB(id, proof, req.IncludeProof),
}, nil
}

Expand All @@ -627,7 +627,7 @@ func (s *MeshService) MalfeasanceStream(
if sub == nil {
return status.Errorf(codes.FailedPrecondition, "event reporting is not enabled")
}
eventch, fullch := consumeEvents[events.EventMalfeasance](stream.Context(), sub)
eventCh, fullCh := consumeEvents[events.EventMalfeasance](stream.Context(), sub)
if err := stream.SendHeader(metadata.MD{}); err != nil {
return status.Errorf(codes.Unavailable, "can't send header")
}
Expand All @@ -639,7 +639,7 @@ func (s *MeshService) MalfeasanceStream(
return nil
default:
res := &pb.MalfeasanceStreamResponse{
Proof: events.ToMalfeasancePB(id, proof, req.IncludeProof),
Proof: toMalfeasancePB(id, proof, req.IncludeProof),
}
return stream.Send(res)
}
Expand All @@ -651,11 +651,18 @@ func (s *MeshService) MalfeasanceStream(
select {
case <-stream.Context().Done():
return nil
case <-fullch:
case <-fullCh:
return status.Errorf(codes.Canceled, "buffer is full")
case ev := <-eventch:
case ev := <-eventCh:
proof, err := s.cdb.MalfeasanceProof(ev.Smesher)
if err != nil {
return status.Error(
codes.Internal,
fmt.Errorf("load malfeasance proof for %s: %w", ev.Smesher.ShortString(), err).Error(),
)
}
if err := stream.Send(&pb.MalfeasanceStreamResponse{
Proof: events.ToMalfeasancePB(ev.Smesher, ev.Proof, req.IncludeProof),
Proof: toMalfeasancePB(ev.Smesher, proof, req.IncludeProof),
}); err != nil {
return status.Error(codes.Internal, fmt.Errorf("send to stream: %w", err).Error())
}
Expand Down
10 changes: 5 additions & 5 deletions api/grpcserver/mesh_service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ func TestMeshService_MalfeasanceQuery(t *testing.T) {
require.Equal(t, nodeID, types.BytesToNodeID(resp.Proof.SmesherId.Id))
require.EqualValues(t, layer, resp.Proof.Layer.Number)
require.Equal(t, pb.MalfeasanceProof_MALFEASANCE_BALLOT, resp.Proof.Kind)
require.Equal(t, events.ToMalfeasancePB(nodeID, codec.MustEncode(proof), true), resp.Proof)
require.Equal(t, toMalfeasancePB(nodeID, codec.MustEncode(proof), true), resp.Proof)
require.NotEmpty(t, resp.Proof.Proof)
var got wire.MalfeasanceProof
require.NoError(t, codec.Decode(resp.Proof.Proof, &got))
Expand Down Expand Up @@ -251,16 +251,16 @@ func TestMeshService_MalfeasanceStream(t *testing.T) {

id, proof := AtxMalfeasance(t, db)
proofBytes := codec.MustEncode(proof)
events.ReportMalfeasance(id, proofBytes)
events.ReportMalfeasance(id)
resp, err := stream.Recv()
require.NoError(t, err)
require.Equal(t, events.ToMalfeasancePB(id, proofBytes, false), resp.Proof)
require.Equal(t, toMalfeasancePB(id, proofBytes, false), resp.Proof)
id, proof = BallotMalfeasance(t, db)
proofBytes = codec.MustEncode(proof)
events.ReportMalfeasance(id, proofBytes)
events.ReportMalfeasance(id)
resp, err = stream.Recv()
require.NoError(t, err)
require.Equal(t, events.ToMalfeasancePB(id, proofBytes, false), resp.Proof)
require.Equal(t, toMalfeasancePB(id, proofBytes, false), resp.Proof)
}

type MeshAPIMockInstrumented struct {
Expand Down
8 changes: 7 additions & 1 deletion api/grpcserver/v2alpha1/interface.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
package v2alpha1

import (
"context"

"github.com/spacemeshos/go-spacemesh/common/types"
)

//go:generate mockgen -typed -package=v2alpha1 -destination=./mocks.go -source=./interface.go

type malfeasanceInfo interface {
Info(data []byte) (map[string]string, error)
Info(ctx context.Context, nodeID types.NodeID) (map[string]string, error)
}
Loading
Loading