Skip to content

Commit

Permalink
feat(perp): query position and margin (#477)
Browse files Browse the repository at this point in the history
* skeleton

* reserve assets

* proto

* reserve asset

* remove reserve asset

* fix

* Fix type casting on perp queryServer

* add a test

* clean up

* clean up

* lint

* remove trader margin query

* Update x/perp/keeper/grpc_query_test.go

Co-authored-by: Walter White <[email protected]>

* fix

* Update x/perp/keeper/grpc_query_test.go

Co-authored-by: Walter White <[email protected]>

* fixes

* proto-gen

* fix

Co-authored-by: Walter White <[email protected]>
Co-authored-by: Mat-Cosmos <[email protected]>
Co-authored-by: Walter White <[email protected]>
  • Loading branch information
4 people authored May 24, 2022
1 parent ebf5b56 commit 3413950
Show file tree
Hide file tree
Showing 11 changed files with 742 additions and 22 deletions.
25 changes: 25 additions & 0 deletions INSTALL.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,4 +78,29 @@ A. If after steps 1-4 you don't have the `nibid` command, your go/bin directory

```bash
export PATH=$PATH:$(go env GOPATH)/bin
```

B. New commands you've made on the `nibid` doesn't show up. Your `nibid` probably just isn't updated again after the code changes, to recompile nibid run `make install` in the root

## Contributing

The code for `nibid` is located in the `/cmd/nibid` folder.

In addition to the commands available within that folder, `nibid` pulls in cli subcommands from the modules e.g. `/x/perps/cli`

After updating the code run

```bash
make build
make install
```

To see all the commands available just add `--help` to the end.

Example:
```bash
nibid --help
nibid query --help
nibid tx --help
nibid query perp --help
```
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,12 @@ Recommended minimum specs:

On a fresh clone of the repo, simply run `make localnet` and open another terminal.

### Generate the protobufs

```bash
make proto-gen
```

# Linter

We use the [golangci-lint](https://golangci-lint.run/) linter. Install it and run
Expand Down
17 changes: 17 additions & 0 deletions proto/perp/v1/query.proto
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ service Query {
option (google.api.http).get = "/nibiru/perp/params";
}

rpc TraderPosition(QueryTraderPositionRequest) returns (QueryTraderPositionResponse) {
option (google.api.http).get = "/nibiru/perp/trader_position";
}
}

// ---------------------------------------- Params
Expand All @@ -28,4 +31,18 @@ message QueryParamsResponse {
Params params = 1 [(gogoproto.nullable) = false];
}

// ---------------------------------------- TraderPosition

/* QueryTraderPositionRequest is the request type for the position of the
x/perp module account. */
message QueryTraderPositionRequest {
string token_pair = 1;
bytes trader = 4[
(gogoproto.casttype) = "github.com/cosmos/cosmos-sdk/types.AccAddress"];
}

message QueryTraderPositionResponse {
Position position = 1;
}

// ---------------------------------------- OtherQuery
11 changes: 11 additions & 0 deletions x/perp/README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
# Perp Design

## cli commands

To see the list of query and transaction commands:

```bash
nibid tx perp --help
nibid query perp --help
```

cli code is within `/perp/client/cli`

## Perp Data Structures

#### type Position (on a virtual pool)
Expand Down
40 changes: 40 additions & 0 deletions x/perp/client/cli/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ func GetQueryCmd() *cobra.Command {

cmds := []*cobra.Command{
CmdQueryParams(),
CmdQueryPosition(),
}
for _, cmd := range cmds {
perpQueryCmd.AddCommand(cmd)
Expand Down Expand Up @@ -70,6 +71,45 @@ func CmdQueryParams() *cobra.Command {
return cmd
}

// sample token-pair: btc:nusd
func CmdQueryPosition() *cobra.Command {
cmd := &cobra.Command{
Use: "trader-position [trader] [token-pair]",
Short: "trader's position for a given token pair/vpool",
Args: cobra.ExactArgs(2),
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx, err := client.GetClientTxContext(cmd)
if err != nil {
return err
}

queryClient := types.NewQueryClient(clientCtx)

trader := args[0]
tokenPair, err := common.NewTokenPairFromStr(args[1])
if err != nil {
return err
}

res, err := queryClient.TraderPosition(
context.Background(), &types.QueryTraderPositionRequest{
Trader: sdk.AccAddress(trader),
TokenPair: tokenPair.String(),
},
)
if err != nil {
return err
}

return clientCtx.PrintProto(res)
},
}

flags.AddQueryFlagsToCmd(cmd)

return cmd
}

// ---------------------------------------------------------------------------
// TxCmd
// ---------------------------------------------------------------------------
Expand Down
40 changes: 40 additions & 0 deletions x/perp/keeper/grpc_query.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package keeper

import (
"context"

sdk "github.com/cosmos/cosmos-sdk/types"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"

"github.com/NibiruChain/nibiru/x/common"
"github.com/NibiruChain/nibiru/x/perp/types"
)

type queryServer struct {
Keeper
}

func NewQuerier(k Keeper) queryServer {
return queryServer{Keeper: k}
}

var _ types.QueryServer = queryServer{}

func (q queryServer) TraderPosition(
goCtx context.Context, req *types.QueryTraderPositionRequest,
) (*types.QueryTraderPositionResponse, error) {
if req == nil {
return nil, status.Error(codes.InvalidArgument, "invalid request")
}

ctx := sdk.UnwrapSDKContext(goCtx)
position, err := q.Keeper.Positions().Get(ctx, common.TokenPair(req.TokenPair), req.Trader)
if err != nil {
return nil, err
}

return &types.QueryTraderPositionResponse{
Position: position,
}, nil
}
53 changes: 53 additions & 0 deletions x/perp/keeper/grpc_query_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package keeper_test

import (
"fmt"
"testing"

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

"github.com/NibiruChain/nibiru/x/common"
"github.com/NibiruChain/nibiru/x/perp/keeper"
"github.com/NibiruChain/nibiru/x/perp/types"
"github.com/NibiruChain/nibiru/x/testutil"
"github.com/NibiruChain/nibiru/x/testutil/sample"
)

func TestQueryPosition_Ok(t *testing.T) {
t.Log("initialize keeper")
nibiruApp, ctx := testutil.NewNibiruApp(true)
perpKeeper := &nibiruApp.PerpKeeper

queryServer := keeper.NewQuerier(*perpKeeper)

trader := sample.AccAddress()
vpoolPair, err := common.NewTokenPairFromStr("btc:nusd")
require.NoError(t, err)

oldPosition := &types.Position{
TraderAddress: trader,
Pair: vpoolPair.String(),
Size_: sdk.NewDec(10),
OpenNotional: sdk.NewDec(10),
Margin: sdk.NewDec(1),
}

perpKeeper.SetPosition(
ctx, vpoolPair, trader, oldPosition)

res, err := queryServer.TraderPosition(
sdk.WrapSDKContext(ctx),
&types.QueryTraderPositionRequest{
Trader: trader,
TokenPair: vpoolPair.String(),
},
)
fmt.Println("res:", res)
require.NoError(t, err)

assert.Equal(t, oldPosition.TraderAddress, res.Position.TraderAddress)
assert.Equal(t, oldPosition.Pair, res.Position.Pair)
assert.Equal(t, oldPosition.Size_, res.Position.Size_)
}
2 changes: 0 additions & 2 deletions x/perp/keeper/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@ import (
"github.com/NibiruChain/nibiru/x/perp/types"
)

var _ types.QueryServer = Keeper{}

func (k Keeper) Params(
goCtx context.Context, req *types.QueryParamsRequest,
) (*types.QueryParamsResponse, error) {
Expand Down
2 changes: 1 addition & 1 deletion x/perp/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ func (am AppModule) LegacyQuerierHandler(legacyQuerierCdc *codec.LegacyAmino) sd
// RegisterServices registers a GRPC query service to respond to the
// module-specific GRPC queries.
func (am AppModule) RegisterServices(cfg module.Configurator) {
types.RegisterQueryServer(cfg.QueryServer(), am.keeper)
types.RegisterQueryServer(cfg.QueryServer(), keeper.NewQuerier(am.keeper))
types.RegisterMsgServer(cfg.MsgServer(), keeper.NewMsgServerImpl(am.keeper))
}

Expand Down
Loading

0 comments on commit 3413950

Please sign in to comment.