Skip to content

Commit

Permalink
feat(poolmanager): v2 SpotPrice query with 36 decimals (backport #6488)
Browse files Browse the repository at this point in the history
  • Loading branch information
p0mvn committed Sep 27, 2023
1 parent 7e39261 commit 916fbc2
Show file tree
Hide file tree
Showing 19 changed files with 1,083 additions and 22 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Features

* [#6416](https://github.com/osmosis-labs/osmosis/pull/6416) feat[CL]: add num initialized ticks query
* [#6488](https://github.com/osmosis-labs/osmosis/pull/6488) v2 SpotPrice CLI and GRPC query with 36 decimals in poolmanager
* [#6535](https://github.com/osmosis-labs/osmosis/pull/6535) makefile: add target that tidies all submodules at once

### API Breaks
Expand Down
19 changes: 16 additions & 3 deletions cmd/querygen/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import (
"github.com/osmosis-labs/osmosis/v19/cmd/querygen/templates"
)

const V2 = "v2"

var grpcTemplate template.Template

func main() {
Expand All @@ -31,7 +33,11 @@ func main() {
}

func parseTemplates() error {
grpcTemplatePtr, err := template.ParseFiles("cmd/querygen/templates/grpc_template.tmpl")
// Create a function to upper case the version suffix if it exists.
funcMap := template.FuncMap{
"ToUpper": strings.ToUpper,
}
grpcTemplatePtr, err := template.New("grpc_template.tmpl").Funcs(funcMap).ParseFiles("cmd/querygen/templates/grpc_template.tmpl")
if err != nil {
return err
}
Expand Down Expand Up @@ -74,16 +80,23 @@ func codegenQueryYml(filepath string) error {
func codegenGrpcPackage(queryYml templates.QueryYml) error {
grpcTemplateData := templates.GrpcTemplateFromQueryYml(queryYml)

// If proto path contains v2 then add folder and template
// suffix to properly package the files.
grpcTemplateData.VersionSuffix = ""
if strings.Contains(grpcTemplateData.ProtoPath, V2) {
grpcTemplateData.VersionSuffix = V2
}

// create directory
fsClientPath := templates.ParseFilePathFromImportPath(grpcTemplateData.ClientPath)
if err := os.MkdirAll(fsClientPath+"/grpc", os.ModePerm); err != nil {
if err := os.MkdirAll(fsClientPath+"/grpc"+grpcTemplateData.VersionSuffix, os.ModePerm); err != nil {
// ignore directory already exists error
if !errors.Is(err, os.ErrExist) {
return err
}
}
// generate file
f, err := os.Create(fsClientPath + "/grpc/grpc_query.go")
f, err := os.Create(fsClientPath + "/grpc" + grpcTemplateData.VersionSuffix + "/grpc_query.go")
if err != nil {
return err
}
Expand Down
7 changes: 4 additions & 3 deletions cmd/querygen/templates/grpcTemplate.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ package templates
import "sort"

type GrpcTemplate struct {
ProtoPath string
ClientPath string
Queries []GrpcQuery
ProtoPath string
ClientPath string
Queries []GrpcQuery
VersionSuffix string
}

type GrpcQuery struct {
Expand Down
17 changes: 9 additions & 8 deletions cmd/querygen/templates/grpc_template.tmpl
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
package grpc
{{ $version := .VersionSuffix }}
package grpc{{$version}}

// THIS FILE IS GENERATED CODE, DO NOT EDIT
// SOURCE AT `{{.ProtoPath}}`
Expand All @@ -11,25 +12,25 @@ import (

sdk "github.com/cosmos/cosmos-sdk/types"
"{{.ClientPath}}"
"{{.ClientPath}}/queryproto"
"{{.ClientPath}}/queryproto{{$version}}"
)

type Querier struct {
Q client.Querier
Q client.Querier{{ $version | ToUpper }}
}

var _ queryproto.QueryServer = Querier{}
var _ queryproto{{$version}}.QueryServer = Querier{}

{{range .Queries -}}

func (q Querier) {{.QueryName}}(grpcCtx context.Context,
req *queryproto.{{.QueryName}}Request,
) ({{ if .Response }}{{.Response}}{{else}}*queryproto.{{.QueryName}}Response{{end}}, error) {
func (q Querier) {{.QueryName}}{{ $version | ToUpper }}(grpcCtx context.Context,
req *queryproto{{$version}}.{{.QueryName}}Request,
) ({{ if .Response }}{{.Response}}{{else}}*queryproto{{$version}}.{{.QueryName}}Response{{end}}, error) {
if req == nil {
return nil, status.Error(codes.InvalidArgument, "empty request")
}
ctx := sdk.UnwrapSDKContext(grpcCtx)
return q.Q.{{.QueryName}}(ctx, *req)
return q.Q.{{.QueryName}}{{ $version | ToUpper }}(ctx, *req)
}

{{end -}}
44 changes: 44 additions & 0 deletions proto/osmosis/poolmanager/v2/query.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
syntax = "proto3";
package osmosis.poolmanager.v2;

import "gogoproto/gogo.proto";

import "google/api/annotations.proto";
import "google/protobuf/any.proto";
import "cosmos_proto/cosmos.proto";
import "google/protobuf/timestamp.proto";

option go_package = "github.com/osmosis-labs/osmosis/v19/x/poolmanager/client/queryprotov2";

service Query {
// SpotPriceV2 defines a gRPC query handler that returns the spot price given
// a base denomination and a quote denomination.
// The returned spot price has 36 decimal places. However, some of
// modules perform sig fig rounding so most of the rightmost decimals can be
// zeroes.
rpc SpotPriceV2(SpotPriceRequest) returns (SpotPriceResponse) {
option (google.api.http).get =
"/osmosis/poolmanager/v2/pools/{pool_id}/prices";
}
}

// SpotPriceRequest defines the gRPC request structure for a SpotPrice
// query.
message SpotPriceRequest {
uint64 pool_id = 1 [ (gogoproto.moretags) = "yaml:\"pool_id\"" ];
string base_asset_denom = 2
[ (gogoproto.moretags) = "yaml:\"base_asset_denom\"" ];
string quote_asset_denom = 3
[ (gogoproto.moretags) = "yaml:\"quote_asset_denom\"" ];
}

// SpotPriceResponse defines the gRPC response structure for a SpotPrice
// query.
message SpotPriceResponse {
// String of the BigDec. Ex) 10.203uatom
string spot_price = 1 [
(gogoproto.customtype) = "github.com/osmosis-labs/osmosis/osmomath.BigDec",
(gogoproto.moretags) = "yaml:\"spot_price\"",
(gogoproto.nullable) = false
];
}
10 changes: 10 additions & 0 deletions proto/osmosis/poolmanager/v2/query.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
keeper:
path: "github.com/osmosis-labs/osmosis/v19/x/poolmanager"
struct: "Keeper"
client_path: "github.com/osmosis-labs/osmosis/v19/x/poolmanager/client"
queries:
SpotPrice:
proto_wrapper:
query_func: "k.RouteCalculateSpotPrice"
cli:
cmd: "SpotPrice"
3 changes: 2 additions & 1 deletion x/concentrated-liquidity/client/grpc/grpc_query.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
package grpc

package grpc

// THIS FILE IS GENERATED CODE, DO NOT EDIT
// SOURCE AT `proto/osmosis/concentrated-liquidity/query.yml`
Expand Down
3 changes: 2 additions & 1 deletion x/cosmwasmpool/client/grpc/grpc_query.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
package grpc

package grpc

// THIS FILE IS GENERATED CODE, DO NOT EDIT
// SOURCE AT `proto/osmosis/cosmwasmpool/v1beta1/query.yml`
Expand Down
3 changes: 2 additions & 1 deletion x/downtime-detector/client/grpc/grpc_query.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
package grpc

package grpc

// THIS FILE IS GENERATED CODE, DO NOT EDIT
// SOURCE AT `proto/osmosis/downtime-detector/v1beta1/query.yml`
Expand Down
3 changes: 2 additions & 1 deletion x/ibc-rate-limit/client/grpc/grpc_query.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
package grpc

package grpc

// THIS FILE IS GENERATED CODE, DO NOT EDIT
// SOURCE AT `proto/osmosis/ibc-rate-limit/v1beta1/query.yml`
Expand Down
12 changes: 12 additions & 0 deletions x/poolmanager/client/cli/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (

"github.com/osmosis-labs/osmosis/osmoutils/osmocli"
"github.com/osmosis-labs/osmosis/v19/x/poolmanager/client/queryproto"
"github.com/osmosis-labs/osmosis/v19/x/poolmanager/client/queryprotov2"
"github.com/osmosis-labs/osmosis/v19/x/poolmanager/types"
)

Expand All @@ -29,6 +30,7 @@ func GetQueryCmd() *cobra.Command {
osmocli.AddQueryCmd(cmd, queryproto.NewQueryClient, GetCmdTotalPoolLiquidity)
osmocli.AddQueryCmd(cmd, queryproto.NewQueryClient, GetCmdAllPools)
osmocli.AddQueryCmd(cmd, queryproto.NewQueryClient, GetCmdPool)
osmocli.AddQueryCmd(cmd, queryprotov2.NewQueryClient, GetCmdSpotPriceV2)
cmd.AddCommand(
osmocli.GetParams[*queryproto.ParamsRequest](
types.ModuleName, queryproto.NewQueryClient),
Expand Down Expand Up @@ -103,6 +105,16 @@ func GetCmdSpotPrice() (*osmocli.QueryDescriptor, *queryproto.SpotPriceRequest)
}, &queryproto.SpotPriceRequest{}
}

func GetCmdSpotPriceV2() (*osmocli.QueryDescriptor, *queryprotov2.SpotPriceRequest) {
return &osmocli.QueryDescriptor{
Use: "spot-price-v2",
Short: "Query spot-price with 36 decimals",
Long: `Query spot-price with 36 decimals
{{.CommandPrefix}} spot-price-v2 1 uosmo ibc/27394FB092D2ECCD56123C74F36E4C1F926001CEADA9CA97EA622B25F41E5EB2
`,
}, &queryprotov2.SpotPriceRequest{}
}

func EstimateSwapExactAmountInParseArgs(args []string, fs *flag.FlagSet) (proto.Message, error) {
poolID, err := strconv.Atoi(args[0])
if err != nil {
Expand Down
3 changes: 2 additions & 1 deletion x/poolmanager/client/grpc/grpc_query.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
package grpc

package grpc

// THIS FILE IS GENERATED CODE, DO NOT EDIT
// SOURCE AT `proto/osmosis/poolmanager/v1beta1/query.yml`
Expand Down
33 changes: 33 additions & 0 deletions x/poolmanager/client/grpcv2/grpc_query.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@

package grpcv2

// THIS FILE IS GENERATED CODE, DO NOT EDIT
// SOURCE AT `proto/osmosis/poolmanager/v2/query.yml`

import (
context "context"

"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"

sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/osmosis-labs/osmosis/v19/x/poolmanager/client"
"github.com/osmosis-labs/osmosis/v19/x/poolmanager/client/queryprotov2"
)

type Querier struct {
Q client.QuerierV2
}

var _ queryprotov2.QueryServer = Querier{}

func (q Querier) SpotPriceV2(grpcCtx context.Context,
req *queryprotov2.SpotPriceRequest,
) (*queryprotov2.SpotPriceResponse, error) {
if req == nil {
return nil, status.Error(codes.InvalidArgument, "empty request")
}
ctx := sdk.UnwrapSDKContext(grpcCtx)
return q.Q.SpotPriceV2(ctx, *req)
}

34 changes: 33 additions & 1 deletion x/poolmanager/client/query_proto_wrap.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (

"github.com/osmosis-labs/osmosis/v19/x/poolmanager"
"github.com/osmosis-labs/osmosis/v19/x/poolmanager/client/queryproto"
"github.com/osmosis-labs/osmosis/v19/x/poolmanager/client/queryprotov2"
"github.com/osmosis-labs/osmosis/v19/x/poolmanager/types"
)

Expand All @@ -22,6 +23,16 @@ func NewQuerier(k poolmanager.Keeper) Querier {
return Querier{k}
}

// QuerierV2 defines a wrapper around the x/poolmanager keeper providing gRPC method
// handlers for v2 queries.
type QuerierV2 struct {
K poolmanager.Keeper
}

func NewV2Querier(k poolmanager.Keeper) QuerierV2 {
return QuerierV2{K: k}
}

func (q Querier) Params(ctx sdk.Context,
req queryproto.ParamsRequest,
) (*queryproto.ParamsResponse, error) {
Expand Down Expand Up @@ -203,7 +214,7 @@ func (q Querier) AllPools(ctx sdk.Context, req queryproto.AllPoolsRequest) (*que
}, nil
}

// SpotPrice returns the spot price of the pool with the given quote and base asset denoms.
// SpotPrice returns the spot price of the pool with the given quote and base asset denoms. 18 decimals.
func (q Querier) SpotPrice(ctx sdk.Context, req queryproto.SpotPriceRequest) (*queryproto.SpotPriceResponse, error) {
if req.BaseAssetDenom == "" {
return nil, status.Error(codes.InvalidArgument, "invalid base asset denom")
Expand All @@ -225,6 +236,27 @@ func (q Querier) SpotPrice(ctx sdk.Context, req queryproto.SpotPriceRequest) (*q
}, err
}

// SpotPriceV2 returns the spot price of the pool with the given quote and base asset denoms. 36 decimals.
func (q QuerierV2) SpotPriceV2(ctx sdk.Context, req queryprotov2.SpotPriceRequest) (*queryprotov2.SpotPriceResponse, error) {
if req.BaseAssetDenom == "" {
return nil, status.Error(codes.InvalidArgument, "invalid base asset denom")
}

if req.QuoteAssetDenom == "" {
return nil, status.Error(codes.InvalidArgument, "invalid quote asset denom")
}

sp, err := q.K.RouteCalculateSpotPrice(ctx, req.PoolId, req.QuoteAssetDenom, req.BaseAssetDenom)
if err != nil {
return nil, status.Error(codes.Internal, err.Error())
}

return &queryprotov2.SpotPriceResponse{
// Note: that this is a BigDec yielding 36 decimals.
SpotPrice: sp,
}, err
}

// TotalPoolLiquidity returns the total liquidity of the pool.
func (q Querier) TotalPoolLiquidity(ctx sdk.Context, req queryproto.TotalPoolLiquidityRequest) (*queryproto.TotalPoolLiquidityResponse, error) {
if req.PoolId == 0 {
Expand Down
Loading

0 comments on commit 916fbc2

Please sign in to comment.