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

Feat/add query limit #597

Merged
merged 4 commits into from
Mar 12, 2024
Merged
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
1 change: 1 addition & 0 deletions docs/proto/logic.md
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,7 @@ QueryServiceAskRequest is request type for the QueryService/Ask RPC method.
| ----- | ---- | ----- | ----------- |
| `program` | [string](#string) | | program is the logic program to be queried. |
| `query` | [string](#string) | | query is the query string to be executed. |
| `limit` | [string](#string) | | limit specifies the maximum number of solutions to be returned. This field is governed by max_result_count, which defines the upper limit of results that may be requested per query. If this field is not explicitly set, a default value of 1 is applied. |
ccamel marked this conversation as resolved.
Show resolved Hide resolved

<a name="logic.v1beta2.QueryServiceAskResponse"></a>

Expand Down
8 changes: 8 additions & 0 deletions proto/logic/v1beta2/query.proto
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,14 @@ message QueryServiceAskRequest {
string program = 1 [(gogoproto.moretags) = "yaml:\"program\",omitempty"];
// query is the query string to be executed.
string query = 2 [(gogoproto.moretags) = "yaml:\"query\",omitempty"];
// limit specifies the maximum number of solutions to be returned. This field is governed by
// max_result_count, which defines the upper limit of results that may be requested per query.
// If this field is not explicitly set, a default value of 1 is applied.
string limit = 3 [
(gogoproto.moretags) = "yaml:\"limit\",omitempty",
(gogoproto.customtype) = "cosmossdk.io/math.Uint",
(gogoproto.nullable) = true
];
}

// QueryServiceAskResponse is response type for the QueryService/Ask RPC method.
Expand Down
1 change: 0 additions & 1 deletion proto/logic/v1beta2/types.proto
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ message Answer {
bool has_more = 2 [(gogoproto.moretags) = "yaml:\"has_more\",omitempty"];
// variables represent all the variables in the query.
repeated string variables = 3 [
(gogoproto.nullable) = false,
(gogoproto.moretags) = "yaml:\"variables\",omitempty"
];
// results represent all the results of the query.
Expand Down
7 changes: 6 additions & 1 deletion x/logic/keeper/grpc_query_ask.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,18 @@ import (
goctx "context"

errorsmod "cosmossdk.io/errors"
sdkmath "cosmossdk.io/math"
storetypes "cosmossdk.io/store/types"

sdk "github.com/cosmos/cosmos-sdk/types"

"github.com/okp4/okp4d/v7/x/logic/meter"
"github.com/okp4/okp4d/v7/x/logic/types"
"github.com/okp4/okp4d/v7/x/logic/util"
)

var defaultLimits = sdkmath.OneUint()

func (k Keeper) Ask(ctx goctx.Context, req *types.QueryServiceAskRequest) (response *types.QueryServiceAskResponse, err error) {
sdkCtx := sdk.UnwrapSDKContext(ctx)

Expand Down Expand Up @@ -43,7 +47,8 @@ func (k Keeper) Ask(ctx goctx.Context, req *types.QueryServiceAskRequest) (respo
return k.execute(
sdkCtx,
req.Program,
req.Query)
req.Query,
util.DerefOrDefault(req.Limit, defaultLimits))
}

// withGasMeter returns a new context with a gas meter that has the given limit.
Expand Down
63 changes: 50 additions & 13 deletions x/logic/keeper/grpc_query_ask_test.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//nolint:gocognit
package keeper_test

import (
Expand Down Expand Up @@ -33,6 +34,7 @@ func TestGRPCAsk(t *testing.T) {
program string
query string
limit int
maxResultCount int
predicateBlacklist []string
maxGas uint64
predicateCosts map[string]uint64
Expand Down Expand Up @@ -83,9 +85,22 @@ func TestGRPCAsk(t *testing.T) {
},
},
{
program: "father(bob, alice). father(bob, john).",
query: "father(bob, X).",
limit: 5,
program: "father(bob, alice). father(bob, john).",
query: "father(bob, X).",
maxResultCount: 5,
expectedAnswer: &types.Answer{
HasMore: true,
Variables: []string{"X"},
Results: []types.Result{{Substitutions: []types.Substitution{{
Variable: "X", Expression: "alice",
}}}},
},
},
{
program: "father(bob, alice). father(bob, john).",
query: "father(bob, X).",
limit: 2,
maxResultCount: 5,
expectedAnswer: &types.Answer{
Variables: []string{"X"},
Results: []types.Result{{Substitutions: []types.Substitution{{
Expand All @@ -95,6 +110,19 @@ func TestGRPCAsk(t *testing.T) {
}}}},
},
},
{
program: "father(bob, alice). father(bob, john).",
query: "father(bob, X).",
limit: 2,
maxResultCount: 1,
expectedAnswer: &types.Answer{
HasMore: true,
Variables: []string{"X"},
Results: []types.Result{{Substitutions: []types.Substitution{{
Variable: "X", Expression: "alice",
}}}},
},
},
{
query: "block_height(X).",
expectedAnswer: &types.Answer{
Expand Down Expand Up @@ -204,8 +232,8 @@ foo(a2).
foo(a3) :- throw(error(resource_error(foo))).
foo(a4).
`,
query: `foo(X).`,
limit: 1,
query: `foo(X).`,
maxResultCount: 1,
expectedAnswer: &types.Answer{
HasMore: true,
Variables: []string{"X"},
Expand All @@ -221,8 +249,9 @@ foo(a2).
foo(a3) :- throw(error(resource_error(foo))).
foo(a4).
`,
query: `foo(X).`,
limit: 2,
query: `foo(X).`,
limit: 2,
maxResultCount: 3,
expectedAnswer: &types.Answer{
HasMore: true,
Variables: []string{"X"},
Expand All @@ -239,8 +268,9 @@ foo(a2).
foo(a3) :- throw(error(resource_error(foo))).
foo(a4).
`,
query: `foo(X).`,
limit: 3,
query: `foo(X).`,
limit: 5,
maxResultCount: 3,
expectedAnswer: &types.Answer{
Variables: []string{"X"},
Results: []types.Result{
Expand All @@ -257,8 +287,9 @@ foo(a2).
foo(a3) :- throw(error(resource_error(foo))).
foo(a4).
`,
query: `foo(X).`,
limit: 5,
query: `foo(X).`,
limit: 5,
maxResultCount: 5,
expectedAnswer: &types.Answer{
Variables: []string{"X"},
Results: []types.Result{
Expand Down Expand Up @@ -295,9 +326,9 @@ foo(a4).
return fsProvider
},
)
limit := sdkmath.NewUint(uint64(lo.If(tc.limit == 0, 1).Else(tc.limit)))
maxResultCount := sdkmath.NewUint(uint64(lo.If(tc.maxResultCount == 0, 1).Else(tc.maxResultCount)))
params := types.DefaultParams()
params.Limits.MaxResultCount = &limit
params.Limits.MaxResultCount = &maxResultCount
if tc.predicateBlacklist != nil {
params.Interpreter.PredicatesFilter.Blacklist = tc.predicateBlacklist
}
Expand Down Expand Up @@ -326,9 +357,15 @@ foo(a4).

queryClient := types.NewQueryServiceClient(queryHelper)

var limit *sdkmath.Uint
if tc.limit != 0 {
v := sdkmath.NewUint(uint64(tc.limit))
limit = &v
}
query := types.QueryServiceAskRequest{
Program: tc.program,
Query: tc.query,
Limit: limit,
}

Convey("when the grpc query ask is called", func() {
Expand Down
4 changes: 2 additions & 2 deletions x/logic/keeper/interpreter.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ func (k Keeper) enhanceContext(ctx context.Context) context.Context {
return sdkCtx
}

func (k Keeper) execute(ctx context.Context, program, query string) (*types.QueryServiceAskResponse, error) {
func (k Keeper) execute(ctx context.Context, program, query string, limit sdkmath.Uint) (*types.QueryServiceAskResponse, error) {
ctx = k.enhanceContext(ctx)
sdkCtx := sdk.UnwrapSDKContext(ctx)
limits := k.limits(sdkCtx)
Expand All @@ -53,7 +53,7 @@ func (k Keeper) execute(ctx context.Context, program, query string) (*types.Quer
return nil, errorsmod.Wrapf(types.InvalidArgument, "error compiling query: %v", err.Error())
}

answer, err := k.queryInterpreter(ctx, i, query, *limits.MaxResultCount)
answer, err := k.queryInterpreter(ctx, i, query, sdkmath.MinUint(limit, *limits.MaxResultCount))
if err != nil {
return nil, errorsmod.Wrapf(types.InvalidArgument, "error executing query: %v", err.Error())
}
Expand Down
126 changes: 93 additions & 33 deletions x/logic/types/query.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading