Skip to content

Commit

Permalink
Merge pull request #884 from lavanet/CNS-639-add-query-to-fetch-all-c…
Browse files Browse the repository at this point in the history
…onflicts-that-the-provider-is-reported

CNS-639: query for provider conflicts (reported + not voted)
  • Loading branch information
Yaroms authored Oct 15, 2023
2 parents fb05f28 + 5b0417e commit 9e3523e
Show file tree
Hide file tree
Showing 8 changed files with 791 additions and 40 deletions.
14 changes: 14 additions & 0 deletions proto/lavanet/lava/conflict/query.proto
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@ service Query {
option (google.api.http).get = "/lavanet/lava/conflict/consumer_conflicts/{consumer}";
}

// Queries a provider's conflict list (ones that the provider was reported in and ones that the provider needs to vote)
rpc ProviderConflicts(QueryProviderConflictsRequest) returns (QueryProviderConflictsResponse) {
option (google.api.http).get = "/lavanet/lava/conflict/provider_conflicts/{provider}";
}

// this line is used by starport scaffolding # 2
}

Expand Down Expand Up @@ -61,6 +66,15 @@ message QueryAllConflictVoteResponse {
cosmos.base.query.v1beta1.PageResponse pagination = 2;
}

message QueryProviderConflictsRequest {
string provider = 1;
}

message QueryProviderConflictsResponse {
repeated string reported = 1;
repeated string not_voted = 2;
}

message QueryConsumerConflictsRequest {
string consumer = 1;
}
Expand Down
1 change: 1 addition & 0 deletions scripts/cli_test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ trace lavad q protocol params >/dev/null
echo "Testing conflict q commands"
trace lavad q conflict params >/dev/null
trace lavad q conflict list-conflict-vote >/dev/null
trace lavad q conflict provider-conflicts $(lavad keys show servicer1 -a) >/dev/null
trace lavad q conflict consumer-conflicts $(lavad keys show user1 -a) >/dev/null
# trace lavad q conflict show-conflict-vote stam >/dev/null ## canot test that here

Expand Down
1 change: 1 addition & 0 deletions x/conflict/client/cli/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ func GetQueryCmd(queryRoute string) *cobra.Command {
cmd.AddCommand(CmdQueryParams())
cmd.AddCommand(CmdListConflictVote())
cmd.AddCommand(CmdShowConflictVote())
cmd.AddCommand(CmdProviderConflicts())
cmd.AddCommand(CmdConsumerConflicts())
// this line is used by starport scaffolding # 1

Expand Down
36 changes: 36 additions & 0 deletions x/conflict/client/cli/query_provider_conflicts.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package cli

import (
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/lavanet/lava/x/conflict/types"
"github.com/spf13/cobra"
)

func CmdProviderConflicts() *cobra.Command {
cmd := &cobra.Command{
Use: "provider-conflicts <provider>",
Short: "Queries a provider's conflict list (ones that the provider was reported in and ones that the provider needs to vote)",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx := client.GetClientContextFromCmd(cmd)

queryClient := types.NewQueryClient(clientCtx)

params := &types.QueryProviderConflictsRequest{
Provider: args[0],
}

res, err := queryClient.ProviderConflicts(cmd.Context(), params)
if err != nil {
return err
}

return clientCtx.PrintProto(res)
},
}

flags.AddQueryFlagsToCmd(cmd)

return cmd
}
39 changes: 39 additions & 0 deletions x/conflict/keeper/grpc_query_provider_conflicts.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package keeper

import (
"context"

sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/lavanet/lava/x/conflict/types"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
)

func (k Keeper) ProviderConflicts(c context.Context, req *types.QueryProviderConflictsRequest) (*types.QueryProviderConflictsResponse, error) {
if req == nil {
return nil, status.Error(codes.InvalidArgument, "invalid request")
}

var (
reported []string
notVoted []string
)

ctx := sdk.UnwrapSDKContext(c)
conflicts := k.GetAllConflictVote(ctx)

for _, conflict := range conflicts {
if conflict.FirstProvider.Account == req.Provider ||
conflict.SecondProvider.Account == req.Provider {
reported = append(reported, conflict.Index)
}

for _, vote := range conflict.Votes {
if vote.Address == req.Provider && vote.Result == types.NoVote {
notVoted = append(notVoted, conflict.Index)
}
}
}

return &types.QueryProviderConflictsResponse{Reported: reported, NotVoted: notVoted}, nil
}
117 changes: 117 additions & 0 deletions x/conflict/keeper/grpc_query_provider_conflicts_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
package keeper_test

import (
"strconv"
"testing"

sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/stretchr/testify/require"

keepertest "github.com/lavanet/lava/testutil/keeper"
"github.com/lavanet/lava/x/conflict/types"
)

// Prevent strconv unused error
var _ = strconv.IntSize

func TestProviderConflicts(t *testing.T) {
keeper, ctx := keepertest.ConflictKeeper(t)
wctx := sdk.WrapSDKContext(ctx)
msgs := createNConflictVote(keeper, ctx, 7)

const (
FIRST_PROVIDER = 0
SECOND_PROVIDER = 1
NONE_OF_THE_PROVIDERS = 2
NOT_VOTED = 3
VOTED = 4
PROVIDER_REPORTED_AND_NOT_VOTED = 5
PROVIDER_REPORTED_AND_VOTED = 6
)

var providers []string
for i := range msgs {
providers = append(providers, "p"+strconv.Itoa(i))
}

for i, msg := range msgs {
switch i {
case FIRST_PROVIDER:
msg.FirstProvider.Account = providers[FIRST_PROVIDER]
case SECOND_PROVIDER:
msg.SecondProvider.Account = providers[SECOND_PROVIDER]
case NONE_OF_THE_PROVIDERS:
msg.FirstProvider.Account = providers[NONE_OF_THE_PROVIDERS]
msg.SecondProvider.Account = providers[NONE_OF_THE_PROVIDERS]
case NOT_VOTED:
msg.Votes = append(msg.Votes, types.Vote{Address: providers[NOT_VOTED], Result: types.NoVote})
case VOTED:
msg.Votes = append(msg.Votes, types.Vote{Address: providers[VOTED], Result: types.Provider0})
case PROVIDER_REPORTED_AND_NOT_VOTED:
msg.FirstProvider.Account = providers[PROVIDER_REPORTED_AND_NOT_VOTED]
msg.Votes = append(msg.Votes, types.Vote{Address: providers[PROVIDER_REPORTED_AND_NOT_VOTED], Result: types.NoVote})
case PROVIDER_REPORTED_AND_VOTED:
msg.FirstProvider.Account = providers[PROVIDER_REPORTED_AND_VOTED]
msg.Votes = append(msg.Votes, types.Vote{Address: providers[PROVIDER_REPORTED_AND_VOTED], Result: types.Provider0})
}

keeper.SetConflictVote(ctx, msg)
}

for _, tc := range []struct {
desc string
provider string
expectedReported []string
expectedNotVoted []string
}{
{
desc: "First provider",
provider: providers[FIRST_PROVIDER],
expectedReported: []string{strconv.Itoa(FIRST_PROVIDER)},
expectedNotVoted: []string{},
},
{
desc: "Second provider",
provider: providers[SECOND_PROVIDER],
expectedReported: []string{strconv.Itoa(SECOND_PROVIDER)},
expectedNotVoted: []string{},
},
{
desc: "None of the providers",
provider: "dummy",
expectedReported: []string{},
expectedNotVoted: []string{},
},
{
desc: "Not voted",
provider: providers[NOT_VOTED],
expectedReported: []string{},
expectedNotVoted: []string{strconv.Itoa(NOT_VOTED)},
},
{
desc: "Voted",
provider: providers[VOTED],
expectedReported: []string{},
expectedNotVoted: []string{},
},
{
desc: "Provider reported and not voted",
provider: providers[PROVIDER_REPORTED_AND_NOT_VOTED],
expectedReported: []string{strconv.Itoa(PROVIDER_REPORTED_AND_NOT_VOTED)},
expectedNotVoted: []string{strconv.Itoa(PROVIDER_REPORTED_AND_NOT_VOTED)},
},
{
desc: "First Provider and voted",
provider: providers[PROVIDER_REPORTED_AND_VOTED],
expectedReported: []string{strconv.Itoa(PROVIDER_REPORTED_AND_VOTED)},
expectedNotVoted: []string{},
},
} {
t.Run(tc.desc, func(t *testing.T) {
res, err := keeper.ProviderConflicts(wctx, &types.QueryProviderConflictsRequest{Provider: tc.provider})
require.Nil(t, err)
require.ElementsMatch(t, res.NotVoted, tc.expectedNotVoted)
require.ElementsMatch(t, res.Reported, tc.expectedReported)
})
}
}
Loading

0 comments on commit 9e3523e

Please sign in to comment.