Skip to content

Commit

Permalink
feat: implement grpc ask service
Browse files Browse the repository at this point in the history
  • Loading branch information
ccamel committed Jan 9, 2023
1 parent c4693bb commit cab9522
Showing 1 changed file with 111 additions and 4 deletions.
115 changes: 111 additions & 4 deletions x/logic/keeper/grpc_query_ask.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,119 @@
package keeper

import (
"context"
goctx "context"
"math"

sdkerrors "cosmossdk.io/errors"
sdkmath "cosmossdk.io/math"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/ichiban/prolog"
"github.com/okp4/okp4d/x/logic/context"
"github.com/okp4/okp4d/x/logic/interpreter"
"github.com/okp4/okp4d/x/logic/types"
"github.com/okp4/okp4d/x/logic/util"
)

func (k Keeper) Ask(ctx context.Context, request *types.QueryServiceAskRequest) (*types.QueryServiceAskResponse, error) {
// TODO implement me
panic("implement me")
func (k Keeper) Ask(ctx goctx.Context, req *types.QueryServiceAskRequest) (*types.QueryServiceAskResponse, error) {
if req == nil {
return nil, sdkerrors.Wrap(types.InvalidArgument, "request is nil")
}

limits := k.getLimits(ctx)
if err := checkLimits(req, limits); err != nil {
return nil, err
}

return k.execute(ctx, req)
}

// withLimitContext returns a context with the limits configured for the module.
func (k Keeper) withLimitContext(ctx goctx.Context) (goctx.Context, context.IncrementCountByFunc) {
limits := k.getLimits(ctx)

maxGas := util.DerefOrDefault(limits.MaxGas, sdkmath.NewUint(math.MaxInt64))

return context.WithLimit(ctx, maxGas.Uint64())
}

func (k Keeper) getLimits(ctx goctx.Context) types.Limits {
params := k.GetParams(sdk.UnwrapSDKContext(ctx))
return params.GetLimits()
}

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

i, limitContext, err := k.newInterpreter(goctx)
if err != nil {
return nil, sdkerrors.Wrapf(types.Internal, "error creating interpreter: %v", err.Error())
}

if err := i.ExecContext(limitContext, req.GetProgram()); err != nil {
return nil, sdkerrors.Wrapf(types.InvalidArgument, "error compiling query: %v", err.Error())
}

sols, err := i.QueryContext(limitContext, req.GetQuery())
if err != nil {
return nil, sdkerrors.Wrapf(types.InvalidArgument, "error executing query: %v", err.Error())
}
defer func() {
_ = sols.Close()
}()

success := false
limits := k.getLimits(sdkCtx)
var variables []string
results := make([]types.Result, 0)
for nb := sdkmath.ZeroUint(); nb.LT(*limits.MaxResultCount) && sols.Next(); nb = nb.Incr() {
success = true

m := types.TermResults{}
if err := sols.Scan(m); err != nil {
return nil, sdkerrors.Wrapf(types.Internal, "error scanning solution: %v", err.Error())
}

if nb.IsZero() {
variables = m.ToVariables()
}

results = append(results, types.Result{Substitutions: m.ToSubstitutions()})
}

return &types.QueryServiceAskResponse{
Height: uint64(sdkCtx.BlockHeight()),
GasUsed: sdkCtx.GasMeter().GasConsumed(),
Answer: &types.Answer{
Success: success,
HasMore: sols.Next(),
Variables: variables,
Results: results,
},
}, nil
}

func checkLimits(request *types.QueryServiceAskRequest, limits types.Limits) error {
size := sdkmath.NewUint(uint64(len(request.GetQuery())))
limit := util.DerefOrDefault(limits.MaxSize, sdkmath.NewUint(math.MaxInt64))
if size.GT(limit) {
return sdkerrors.Wrapf(types.LimitExceeded, "query: %d > MaxSize: %d", size, limit)
}

return nil
}

// newInterpreter creates a new interpreter with the limits configured for the module, and initialized with the
// interpreter's module settings.
func (k Keeper) newInterpreter(ctx goctx.Context) (*prolog.Interpreter, goctx.Context, error) {
params := k.GetParams(sdk.UnwrapSDKContext(ctx))
interpreterParams := params.GetInterpreter()
limitContext, inc := k.withLimitContext(ctx)

interpreted, err := interpreter.NewInstrumentedInterpreter(
limitContext,
util.NonZeroOrDefault(interpreterParams.GetRegisteredPredicates(), interpreter.RegistryNames),
util.NonZeroOrDefault(interpreterParams.GetBootstrap(), interpreter.Bootstrap()),
inc)

return interpreted, limitContext, err
}

0 comments on commit cab9522

Please sign in to comment.