Skip to content

Commit

Permalink
Merge pull request #221 from irisnet/zhiqiang/refactor-coinswap-grpc
Browse files Browse the repository at this point in the history
Refactor coinswap module grpc
  • Loading branch information
zhangyelong committed Aug 19, 2021
2 parents ce9657b + b299e3e commit 45d2438
Show file tree
Hide file tree
Showing 10 changed files with 1,172 additions and 256 deletions.
73 changes: 47 additions & 26 deletions modules/coinswap/client/rest/grpc_query_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ import (
"testing"
"time"

"github.com/tidwall/gjson"

"github.com/gogo/protobuf/proto"
"github.com/stretchr/testify/suite"

Expand Down Expand Up @@ -173,12 +171,16 @@ func (s *IntegrationTestSuite) TestCoinswap() {
s.Require().Equal("399985965", coins.AmountOf(sdk.DefaultBondDenom).String())
s.Require().Equal("1000", coins.AmountOf(lptDenom).String())

url := fmt.Sprintf("%s/coinswap/liquidities/%s", baseURL, lptDenom)
queryPoolResponse := proto.Message(&coinswaptypes.QueryPoolResponse{})
url := fmt.Sprintf("%s/irismod/coinswap/pools/%s", baseURL, lptDenom)
resp, err := rest.GetRequest(url)
s.Require().NoError(err)
s.Require().Equal("1000", gjson.Get(string(resp), "result.standard.amount").String())
s.Require().Equal("1000", gjson.Get(string(resp), "result.token.amount").String())
s.Require().Equal("1000", gjson.Get(string(resp), "result.liquidity.amount").String())
s.Require().NoError(clientCtx.JSONMarshaler.UnmarshalJSON(resp, queryPoolResponse))

queryPool := queryPoolResponse.(*coinswaptypes.QueryPoolResponse)
s.Require().Equal("1000", queryPool.Pool.Standard.Amount.String())
s.Require().Equal("1000", queryPool.Pool.Token.Amount.String())
s.Require().Equal("1000", queryPool.Pool.Lpt.Amount.String())

// test add liquidity (poor exist)
status, err = clientCtx.Client.Status(context.Background())
Expand Down Expand Up @@ -235,12 +237,14 @@ func (s *IntegrationTestSuite) TestCoinswap() {
s.Require().Equal("399983955", coins.AmountOf(sdk.DefaultBondDenom).String())
s.Require().Equal("3000", coins.AmountOf(lptDenom).String())

url = fmt.Sprintf("%s/coinswap/liquidities/%s", baseURL, lptDenom)
url = fmt.Sprintf("%s/irismod/coinswap/pools/%s", baseURL, lptDenom)
resp, err = rest.GetRequest(url)
s.Require().NoError(err)
s.Require().Equal("3000", gjson.Get(string(resp), "result.standard.amount").String())
s.Require().Equal("3001", gjson.Get(string(resp), "result.token.amount").String())
s.Require().Equal("3000", gjson.Get(string(resp), "result.liquidity.amount").String())
s.Require().NoError(clientCtx.JSONMarshaler.UnmarshalJSON(resp, queryPoolResponse))

s.Require().Equal("3000", queryPool.Pool.Standard.Amount.String())
s.Require().Equal("3001", queryPool.Pool.Token.Amount.String())
s.Require().Equal("3000", queryPool.Pool.Lpt.Amount.String())

// test sell order
msgSellOrder := &coinswaptypes.MsgSwapOrder{
Expand Down Expand Up @@ -297,12 +301,14 @@ func (s *IntegrationTestSuite) TestCoinswap() {
s.Require().Equal("399984693", coins.AmountOf(sdk.DefaultBondDenom).String())
s.Require().Equal("3000", coins.AmountOf(lptDenom).String())

url = fmt.Sprintf("%s/coinswap/liquidities/%s", baseURL, lptDenom)
url = fmt.Sprintf("%s/irismod/coinswap/pools/%s", baseURL, lptDenom)
resp, err = rest.GetRequest(url)
s.Require().NoError(err)
s.Require().Equal("2252", gjson.Get(string(resp), "result.standard.amount").String())
s.Require().Equal("4001", gjson.Get(string(resp), "result.token.amount").String())
s.Require().Equal("3000", gjson.Get(string(resp), "result.liquidity.amount").String())
s.Require().NoError(clientCtx.JSONMarshaler.UnmarshalJSON(resp, queryPoolResponse))

s.Require().Equal("2252", queryPool.Pool.Standard.Amount.String())
s.Require().Equal("4001", queryPool.Pool.Token.Amount.String())
s.Require().Equal("3000", queryPool.Pool.Lpt.Amount.String())

// test buy order
msgBuyOrder := &coinswaptypes.MsgSwapOrder{
Expand Down Expand Up @@ -359,12 +365,14 @@ func (s *IntegrationTestSuite) TestCoinswap() {
s.Require().Equal("399983930", coins.AmountOf(sdk.DefaultBondDenom).String())
s.Require().Equal("3000", coins.AmountOf(lptDenom).String())

url = fmt.Sprintf("%s/coinswap/liquidities/%s", baseURL, lptDenom)
url = fmt.Sprintf("%s/irismod/coinswap/pools/%s", baseURL, lptDenom)
resp, err = rest.GetRequest(url)
s.Require().NoError(err)
s.Require().Equal("3005", gjson.Get(string(resp), "result.standard.amount").String())
s.Require().Equal("3001", gjson.Get(string(resp), "result.token.amount").String())
s.Require().Equal("3000", gjson.Get(string(resp), "result.liquidity.amount").String())
s.Require().NoError(clientCtx.JSONMarshaler.UnmarshalJSON(resp, queryPoolResponse))

s.Require().Equal("3005", queryPool.Pool.Standard.Amount.String())
s.Require().Equal("3001", queryPool.Pool.Token.Amount.String())
s.Require().Equal("3000", queryPool.Pool.Lpt.Amount.String())

// Test remove liquidity (remove part)
msgRemoveLiquidity := &coinswaptypes.MsgRemoveLiquidity{
Expand Down Expand Up @@ -416,12 +424,14 @@ func (s *IntegrationTestSuite) TestCoinswap() {
s.Require().Equal("399985923", coins.AmountOf(sdk.DefaultBondDenom).String())
s.Require().Equal("1000", coins.AmountOf(lptDenom).String())

url = fmt.Sprintf("%s/coinswap/liquidities/%s", baseURL, lptDenom)
url = fmt.Sprintf("%s/irismod/coinswap/pools/%s", baseURL, lptDenom)
resp, err = rest.GetRequest(url)
s.Require().NoError(err)
s.Require().Equal("1002", gjson.Get(string(resp), "result.standard.amount").String())
s.Require().Equal("1001", gjson.Get(string(resp), "result.token.amount").String())
s.Require().Equal("1000", gjson.Get(string(resp), "result.liquidity.amount").String())
s.Require().NoError(clientCtx.JSONMarshaler.UnmarshalJSON(resp, queryPoolResponse))

s.Require().Equal("1002", queryPool.Pool.Standard.Amount.String())
s.Require().Equal("1001", queryPool.Pool.Token.Amount.String())
s.Require().Equal("1000", queryPool.Pool.Lpt.Amount.String())

// Test remove liquidity (remove all)
msgRemoveLiquidity = &coinswaptypes.MsgRemoveLiquidity{
Expand Down Expand Up @@ -473,10 +483,21 @@ func (s *IntegrationTestSuite) TestCoinswap() {
s.Require().Equal("399986915", coins.AmountOf(sdk.DefaultBondDenom).String())
s.Require().Equal("0", coins.AmountOf(lptDenom).String())

url = fmt.Sprintf("%s/coinswap/liquidities/%s", baseURL, lptDenom)
url = fmt.Sprintf("%s/irismod/coinswap/pools/%s", baseURL, lptDenom)
resp, err = rest.GetRequest(url)
s.Require().NoError(err)
s.Require().Equal("0", gjson.Get(string(resp), "result.standard.amount").String())
s.Require().Equal("0", gjson.Get(string(resp), "result.token.amount").String())
s.Require().Equal("0", gjson.Get(string(resp), "result.liquidity.amount").String())
s.Require().NoError(clientCtx.JSONMarshaler.UnmarshalJSON(resp, queryPoolResponse))

s.Require().Equal("0", queryPool.Pool.Standard.Amount.String())
s.Require().Equal("0", queryPool.Pool.Token.Amount.String())
s.Require().Equal("0", queryPool.Pool.Lpt.Amount.String())

queryPoolsResponse := proto.Message(&coinswaptypes.QueryPoolsResponse{})
url = fmt.Sprintf("%s/irismod/coinswap/pools", baseURL)
resp, err = rest.GetRequest(url)
s.Require().NoError(err)
s.Require().NoError(clientCtx.JSONMarshaler.UnmarshalJSON(resp, queryPoolsResponse))

queryPools := queryPoolsResponse.(*coinswaptypes.QueryPoolsResponse)
s.Require().Len(queryPools.Pools, 1)
}
12 changes: 6 additions & 6 deletions modules/coinswap/client/rest/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@ import (
)

func registerQueryRoutes(cliCtx client.Context, r *mux.Router) {
// query liquidity
r.HandleFunc(fmt.Sprintf("/%s/liquidities/{%s}", types.ModuleName, RestPoolID), queryLiquidityHandlerFn(cliCtx)).Methods("GET")
// query pool
r.HandleFunc(fmt.Sprintf("/%s/pools/{%s}", types.ModuleName, RestPoolID), queryPoolsHandlerFn(cliCtx)).Methods("GET")
}

// HTTP request handler to query liquidity information.
func queryLiquidityHandlerFn(cliCtx client.Context) http.HandlerFunc {
func queryPoolsHandlerFn(cliCtx client.Context) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
denom := vars[RestPoolID]
Expand All @@ -28,8 +28,8 @@ func queryLiquidityHandlerFn(cliCtx client.Context) http.HandlerFunc {
return
}

params := types.QueryLiquidityParams{
Denom: denom,
params := types.QueryPoolParams{
LptDenom: denom,
}

bz, err := cliCtx.LegacyAmino.MarshalJSON(params)
Expand All @@ -38,7 +38,7 @@ func queryLiquidityHandlerFn(cliCtx client.Context) http.HandlerFunc {
return
}

route := fmt.Sprintf("custom/%s/%s", types.QuerierRoute, types.QueryLiquidity)
route := fmt.Sprintf("custom/%s/%s", types.QuerierRoute, types.QueryPool)
res, height, err := cliCtx.QueryWithData(route, bz)
if err != nil {
rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
Expand Down
78 changes: 61 additions & 17 deletions modules/coinswap/keeper/grpc_query.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,43 +6,87 @@ import (
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"

"github.com/cosmos/cosmos-sdk/store/prefix"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
"github.com/cosmos/cosmos-sdk/types/query"

"github.com/irisnet/irismod/modules/coinswap/types"
)

var _ types.QueryServer = Keeper{}

// Liquidity returns the liquidity pool information of the denom
func (k Keeper) Liquidity(c context.Context, req *types.QueryLiquidityRequest) (*types.QueryLiquidityResponse, error) {
// Pool returns the liquidity pool information of the denom
func (k Keeper) Pool(c context.Context, req *types.QueryPoolRequest) (*types.QueryPoolResponse, error) {
if req == nil {
return nil, status.Errorf(codes.InvalidArgument, "empty request")
}

ctx := sdk.UnwrapSDKContext(c)
pool, exists := k.GetPoolByLptDenom(ctx, req.Denom)
pool, exists := k.GetPoolByLptDenom(ctx, req.LptDenom)
if !exists {
return nil, sdkerrors.Wrapf(types.ErrReservePoolNotExists, "liquidity pool token: %s", req.Denom)
return nil, sdkerrors.Wrapf(types.ErrReservePoolNotExists, "liquidity pool token: %s", req.LptDenom)
}

standardDenom := k.GetStandardDenom(ctx)
reservePool, err := k.GetPoolBalancesByLptDenom(ctx, pool.LptDenom)
balances, err := k.GetPoolBalancesByLptDenom(ctx, pool.LptDenom)
if err != nil {
return nil, err
}

standard := sdk.NewCoin(standardDenom, reservePool.AmountOf(standardDenom))
token := sdk.NewCoin(pool.CounterpartyDenom, reservePool.AmountOf(pool.CounterpartyDenom))
liquidity := sdk.NewCoin(pool.LptDenom, k.bk.GetSupply(ctx).GetTotal().AmountOf(pool.LptDenom))

swapParams := k.GetParams(ctx)
fee := swapParams.Fee.String()
res := types.QueryLiquidityResponse{
Standard: standard,
Token: token,
Liquidity: liquidity,
Fee: fee,
supply := k.bk.GetSupply(ctx)
standard := sdk.NewCoin(pool.StandardDenom, balances.AmountOf(pool.StandardDenom))
token := sdk.NewCoin(pool.CounterpartyDenom, balances.AmountOf(pool.CounterpartyDenom))
liquidity := sdk.NewCoin(pool.LptDenom, supply.GetTotal().AmountOf(pool.LptDenom))
params := k.GetParams(ctx)
res := types.QueryPoolResponse{
Pool: types.PoolInfo{
Id: pool.Id,
EscrowAddress: pool.EscrowAddress,
Standard: standard,
Token: token,
Lpt: liquidity,
Fee: params.Fee.String(),
},
}
return &res, nil
}

func (k Keeper) Pools(c context.Context, req *types.QueryPoolsRequest) (*types.QueryPoolsResponse, error) {
if req == nil {
return nil, status.Errorf(codes.InvalidArgument, "empty request")
}
ctx := sdk.UnwrapSDKContext(c)
supply := k.bk.GetSupply(ctx).GetTotal()
params := k.GetParams(ctx)

var pools []types.PoolInfo

store := ctx.KVStore(k.storeKey)
nftStore := prefix.NewStore(store, []byte(types.KeyPool))
pageRes, err := query.Paginate(nftStore, req.Pagination, func(key []byte, value []byte) error {
var pool types.Pool
k.cdc.MustUnmarshalBinaryBare(value, &pool)

balances, err := k.GetPoolBalancesByLptDenom(ctx, pool.LptDenom)
if err != nil {
return err
}

pools = append(pools, types.PoolInfo{
Id: pool.Id,
EscrowAddress: pool.EscrowAddress,
Standard: sdk.NewCoin(pool.StandardDenom, balances.AmountOf(pool.StandardDenom)),
Token: sdk.NewCoin(pool.CounterpartyDenom, balances.AmountOf(pool.CounterpartyDenom)),
Lpt: sdk.NewCoin(pool.LptDenom, supply.AmountOf(pool.LptDenom)),
Fee: params.Fee.String(),
})
return nil
})
if err != nil {
return nil, err
}
return &types.QueryPoolsResponse{
Pagination: pageRes,
Pools: pools,
}, nil
}
34 changes: 8 additions & 26 deletions modules/coinswap/keeper/querier.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,48 +14,30 @@ import (
func NewQuerier(k Keeper, legacyQuerierCdc *codec.LegacyAmino) sdk.Querier {
return func(ctx sdk.Context, path []string, req abci.RequestQuery) (res []byte, err error) {
switch path[0] {
case types.QueryLiquidity:
return queryLiquidity(ctx, req, k, legacyQuerierCdc)
case types.QueryPool:
return queryPool(ctx, req, k, legacyQuerierCdc)
default:
return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unknown query path: %s", path[0])
}
}
}

// queryLiquidity returns the total liquidity available for the provided denomination
// queryPool returns the total liquidity available for the provided denomination
// upon success or an error if the query fails.
func queryLiquidity(ctx sdk.Context, req abci.RequestQuery, k Keeper, legacyQuerierCdc *codec.LegacyAmino) ([]byte, error) {
var params types.QueryLiquidityParams
func queryPool(ctx sdk.Context, req abci.RequestQuery, k Keeper, legacyQuerierCdc *codec.LegacyAmino) ([]byte, error) {
var params types.QueryPoolParams

if err := legacyQuerierCdc.UnmarshalJSON(req.Data, &params); err != nil {
return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error())
}

pool, exists := k.GetPoolByLptDenom(ctx, params.Denom)
if !exists {
return nil, sdkerrors.Wrapf(types.ErrReservePoolNotExists, "liquidity pool token: %s", params.Denom)
}

standardDenom := k.GetStandardDenom(ctx)
reservePool, err := k.GetPoolBalancesByLptDenom(ctx, pool.LptDenom)
c := sdk.WrapSDKContext(ctx)
response, err := k.Pool(c, &types.QueryPoolRequest{LptDenom: params.LptDenom})
if err != nil {
return nil, err
}

standard := sdk.NewCoin(standardDenom, reservePool.AmountOf(standardDenom))
token := sdk.NewCoin(pool.CounterpartyDenom, reservePool.AmountOf(pool.CounterpartyDenom))
liquidity := sdk.NewCoin(pool.LptDenom, k.bk.GetSupply(ctx).GetTotal().AmountOf(pool.LptDenom))

swapParams := k.GetParams(ctx)
fee := swapParams.Fee.String()
res := types.QueryLiquidityResponse{
Standard: standard,
Token: token,
Liquidity: liquidity,
Fee: fee,
}

bz, errRes := codec.MarshalJSONIndent(legacyQuerierCdc, res)
bz, errRes := codec.MarshalJSONIndent(legacyQuerierCdc, response)
if errRes != nil {
return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error())
}
Expand Down
16 changes: 8 additions & 8 deletions modules/coinswap/keeper/querier_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,23 +41,23 @@ func (suite *TestSuite) TestNewQuerier() {

// test queryLiquidity

bz, errRes := legacyAmino.MarshalJSON(types.QueryLiquidityParams{Denom: lptCoin.Denom})
bz, errRes := legacyAmino.MarshalJSON(types.QueryPoolParams{LptDenom: lptCoin.Denom})
suite.NoError(errRes)

req.Path = fmt.Sprintf("custom/%s/%s", types.QuerierRoute, types.QueryLiquidity)
req.Path = fmt.Sprintf("custom/%s/%s", types.QuerierRoute, types.QueryPool)
req.Data = bz

res, err = querier(suite.ctx, []string{types.QueryLiquidity}, req)
res, err = querier(suite.ctx, []string{types.QueryPool}, req)
suite.NoError(err)

var respone types.QueryLiquidityResponse
var respone types.QueryPoolResponse
errRes = suite.app.LegacyAmino().UnmarshalJSON(res, &respone)
suite.NoError(errRes)
standard := sdk.NewCoin(denomStandard, standardAmt)
token := sdk.NewCoin(denomBTC, btcAmt)
liquidity := sdk.NewCoin(lptCoin.Denom, standardAmt)
suite.Equal(standard, respone.Standard)
suite.Equal(token, respone.Token)
suite.Equal(liquidity, respone.Liquidity)
suite.Equal(suite.app.CoinswapKeeper.GetParams(suite.ctx).Fee.String(), respone.Fee)
suite.Equal(standard, respone.Pool.Standard)
suite.Equal(token, respone.Pool.Token)
suite.Equal(liquidity, respone.Pool.Lpt)
suite.Equal(suite.app.CoinswapKeeper.GetParams(suite.ctx).Fee.String(), respone.Pool.Fee)
}
12 changes: 7 additions & 5 deletions modules/coinswap/types/querier.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package types

const (
// QueryLiquidity is the liquidity query endpoint supported by the coinswap querier
QueryLiquidity = "liquidity"
// QueryPool is the liquidity query endpoint supported by the coinswap querier
QueryPool = "pool"
// QueryPools is the liquidity query endpoint supported by the coinswap querier
QueryPools = "pools"
)

// QueryLiquidityParams is the query parameters for 'custom/swap/liquidity'
type QueryLiquidityParams struct {
Denom string `json:"denom" yaml:"denom"` // same as uniDenom
// QueryPoolParams is the query parameters for 'custom/swap/liquidity'
type QueryPoolParams struct {
LptDenom string `json:"lpt-denom" yaml:"lpt-denom"` // same as uniDenom
}
Loading

0 comments on commit 45d2438

Please sign in to comment.