Skip to content

Commit

Permalink
feat: switch the client for alerts from rpc to grpc for updated kava …
Browse files Browse the repository at this point in the history
…version
  • Loading branch information
boodyvo committed Sep 23, 2024
1 parent 2e2d612 commit daae21b
Show file tree
Hide file tree
Showing 17 changed files with 1,509 additions and 588 deletions.
2 changes: 1 addition & 1 deletion alerts/auctions/calc.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ func CalculateTotalAuctionsUSDValue(data *AuctionData) (sdk.Dec, error) {

// calculateUSDValue calculates the USD value of a given Coin and AssetInfo
func CalculateUSDValue(coin sdk.Coin, assetInfo AssetInfo) sdk.Dec {
return coin.Amount.ToDec().Quo(assetInfo.ConversionFactor.ToDec()).Mul(assetInfo.Price)
return coin.Amount.ToLegacyDec().Quo(assetInfo.ConversionFactor.ToLegacyDec()).Mul(assetInfo.Price)
}

func CheckInefficientAuctions(data *AuctionData, thresholdUSD, thresholdRatio sdk.Dec, thresholdTime time.Duration) ([]auctiontypes.Auction, error) {
Expand Down
40 changes: 19 additions & 21 deletions alerts/auctions/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,13 @@ package auctions
import (
"context"
"errors"
"fmt"

"github.com/cometbft/cometbft/libs/bytes"
rpcclient "github.com/cometbft/cometbft/rpc/client"
"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
auctiontypes "github.com/kava-labs/kava/x/auction/types"
cdptypes "github.com/kava-labs/kava/x/cdp/types"
hardtypes "github.com/kava-labs/kava/x/hard/types"
pricefeedtypes "github.com/kava-labs/kava/x/pricefeed/types"
"github.com/tendermint/tendermint/libs/bytes"
rpcclient "github.com/tendermint/tendermint/rpc/client"
)

const (
Expand All @@ -25,15 +22,6 @@ type InfoResponse struct {
LatestHeight int64 `json:"latest_height" yaml:"latest_height"`
}

// AuctionClient defines the expected client interface for interacting with auctions
type AuctionClient interface {
GetInfo() (*InfoResponse, error)
GetPrices(height int64) (pricefeedtypes.CurrentPrices, error)
GetAuctions(height int64) ([]auctiontypes.Auction, error)
GetMarkets(height int64) (cdptypes.CollateralParams, error)
GetMoneyMarkets(height int64) (hardtypes.MoneyMarkets, error)
}

// RpcAuctionClient defines a client for interacting with auctions via rpc
type RpcAuctionClient struct {
rpc RpcClient
Expand Down Expand Up @@ -66,15 +54,16 @@ func (c *RpcAuctionClient) GetInfo() (*InfoResponse, error) {
}

// GetPrices gets the current prices for markets
func (c *RpcAuctionClient) GetPrices(height int64) (pricefeedtypes.CurrentPrices, error) {
path := fmt.Sprintf("custom/%s/%s", pricefeedtypes.QuerierRoute, pricefeedtypes.QueryPrices)
func (c *RpcAuctionClient) GetPrices(height int64) (pricefeedtypes.CurrentPriceResponses, error) {
//path := fmt.Sprintf("custom/%s/%s", pricefeedtypes.QuerierRoute, pricefeedtypes.QueryPrices)
path := ""

data, err := c.abciQuery(path, bytes.HexBytes{}, height)
if err != nil {
return nil, err
}

var currentPrices pricefeedtypes.CurrentPrices
var currentPrices pricefeedtypes.CurrentPriceResponses
err = c.cdc.UnmarshalJSON(data, &currentPrices)
if err != nil {
return nil, err
Expand All @@ -85,7 +74,8 @@ func (c *RpcAuctionClient) GetPrices(height int64) (pricefeedtypes.CurrentPrices

// GetMarkets gets an array of collateral params for each collateral type
func (c *RpcAuctionClient) GetMarkets(height int64) (cdptypes.CollateralParams, error) {
path := fmt.Sprintf("custom/%s/%s", cdptypes.QuerierRoute, cdptypes.QueryGetParams)
//path := fmt.Sprintf("custom/%s/%s", cdptypes.QuerierRoute, cdptypes.QueryGetParams)
path := ""

data, err := c.abciQuery(path, bytes.HexBytes{}, height)
if err != nil {
Expand All @@ -103,7 +93,12 @@ func (c *RpcAuctionClient) GetMarkets(height int64) (cdptypes.CollateralParams,

// GetMoneyMarkets gets an array of money markets for each asset
func (c *RpcAuctionClient) GetMoneyMarkets(height int64) (hardtypes.MoneyMarkets, error) {
path := fmt.Sprintf("custom/%s/%s", hardtypes.QuerierRoute, hardtypes.QueryGetParams)
//path := fmt.Sprintf("custom/%s/%s", hardtypes.QuerierRoute, hardtypes.QueryGetParams)
path := ""
// https://rpc.app.infra.kava.io/custom/hard/params?height=11624954
// https://rpc.app.infra.kava.io/kava/hard/v1beta1/params?height=11624954
// https://rpc.app.infra.kava.io/cosmos/base/tendermint/v1beta1/abci_query?path=%22custom/hard/params%22&data=null&height=11624954

data, err := c.abciQuery(path, bytes.HexBytes{}, height)
if err != nil {
return nil, err
Expand All @@ -119,13 +114,16 @@ func (c *RpcAuctionClient) GetMoneyMarkets(height int64) (hardtypes.MoneyMarkets

// GetAuctions gets all the currently running auctions
func (c *RpcAuctionClient) GetAuctions(height int64) ([]auctiontypes.Auction, error) {
path := fmt.Sprintf("custom/%s/%s", auctiontypes.QuerierRoute, auctiontypes.QueryGetAuctions)
//path := fmt.Sprintf("custom/%s/%s", auctiontypes.QuerierRoute, auctiontypes.QueryGetAuctions)
path := ""
// https://rpc.app.infra.kava.io/custom/hard/params?height=11624954

page := 1
var auctions []auctiontypes.Auction

for {
params := auctiontypes.NewQueryAllAuctionParams(page, c.PageLimit, "", "", "", sdk.AccAddress{})
//params := auctiontypes.NewQueryAllAuctionParams(page, c.PageLimit, "", "", "", sdk.AccAddress{})
params := ""
bz, err := c.cdc.MarshalJSON(&params)

if err != nil {
Expand Down
5 changes: 3 additions & 2 deletions alerts/auctions/data.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"fmt"
"math/big"

sdkmath "cosmossdk.io/math"
sdk "github.com/cosmos/cosmos-sdk/types"
auctiontypes "github.com/kava-labs/kava/x/auction/types"
cdptypes "github.com/kava-labs/kava/x/cdp/types"
Expand All @@ -13,7 +14,7 @@ import (
// AssetInfo defines the price and conversion factor of a specific asset
type AssetInfo struct {
Price sdk.Dec
ConversionFactor sdk.Int
ConversionFactor sdkmath.Int
}

// AuctionData defines a map of AssetInfo and array of current auctions
Expand Down Expand Up @@ -110,5 +111,5 @@ func deduplicateMarkets(cdpMarkets cdptypes.CollateralParams, hardMarkets hardty
type auctionMarket struct {
Denom string
SpotMarketID string
ConversionFactor sdk.Int
ConversionFactor sdkmath.Int
}
138 changes: 138 additions & 0 deletions alerts/auctions/grpc_client.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
package auctions

import (
"context"
"fmt"
"github.com/cosmos/cosmos-sdk/client/grpc/tmservice"
"github.com/cosmos/cosmos-sdk/codec"
query "github.com/cosmos/cosmos-sdk/types/query"
kavagrpc "github.com/kava-labs/kava/client/grpc"
kavagrpcutil "github.com/kava-labs/kava/client/grpc/util"
auctiontypes "github.com/kava-labs/kava/x/auction/types"
cdptypes "github.com/kava-labs/kava/x/cdp/types"
hardtypes "github.com/kava-labs/kava/x/hard/types"
pricefeedtypes "github.com/kava-labs/kava/x/pricefeed/types"
"google.golang.org/grpc"
)

// AuctionClient defines the expected client interface for interacting with auctions
type AuctionClient interface {
GetInfo() (*InfoResponse, error)
GetPrices(height int64) (pricefeedtypes.CurrentPriceResponses, error)
GetAuctions(height int64) ([]auctiontypes.Auction, error)
GetMarkets(height int64) (cdptypes.CollateralParams, error)
GetMoneyMarkets(height int64) (hardtypes.MoneyMarkets, error)
}

// GrpcAuctionClient defines a client for interacting with auctions via rpc
type GrpcAuctionClient struct {
conn *grpc.ClientConn
grpcClient *kavagrpc.KavaGrpcClient
util *kavagrpcutil.Util
cdc codec.Codec
PageLimit uint64
}

var _ AuctionClient = (*GrpcAuctionClient)(nil)

// NewGrpcAuctionClient NewRpcAuctionClient returns a new RpcAuctionClient
func NewGrpcAuctionClient(
grpcClient *kavagrpc.KavaGrpcClient,
cdc codec.Codec,
) *GrpcAuctionClient {
return &GrpcAuctionClient{
grpcClient: grpcClient,
cdc: cdc,
util: kavagrpcutil.NewUtil(nil), // we need util to create context for particular height
PageLimit: DefaultPageLimit,
}
}

// GetInfo returns the current chain info
func (c *GrpcAuctionClient) GetInfo() (*InfoResponse, error) {
resultLatestBlock, err := c.grpcClient.Query.Tm.GetLatestBlock(context.Background(), &tmservice.GetLatestBlockRequest{})
if err != nil {
return nil, err
}

resultNodeInfo, err := c.grpcClient.Query.Tm.GetNodeInfo(context.Background(), &tmservice.GetNodeInfoRequest{})
if err != nil {
return nil, err
}

return &InfoResponse{
ChainId: resultNodeInfo.GetDefaultNodeInfo().Network,
LatestHeight: resultLatestBlock.GetBlock().Header.Height,
}, nil
}

// GetPrices gets the current prices for markets
func (c *GrpcAuctionClient) GetPrices(height int64) (pricefeedtypes.CurrentPriceResponses, error) {
heightCtx := c.util.CtxAtHeight(height)
prices, err := c.grpcClient.Query.Pricefeed.Prices(
heightCtx,
&pricefeedtypes.QueryPricesRequest{},
)
if err != nil {
return nil, err
}

return prices.Prices, nil
}

// GetMarkets gets an array of collateral params for each collateral type
func (c *GrpcAuctionClient) GetMarkets(height int64) (cdptypes.CollateralParams, error) {
heightCtx := c.util.CtxAtHeight(height)
params, err := c.grpcClient.Query.Cdp.Params(heightCtx, &cdptypes.QueryParamsRequest{})
if err != nil {
return nil, err
}

return params.Params.CollateralParams, nil
}

// GetMoneyMarkets gets an array of money markets for each asset
func (c *GrpcAuctionClient) GetMoneyMarkets(height int64) (hardtypes.MoneyMarkets, error) {
heightCtx := c.util.CtxAtHeight(height)
params, err := c.grpcClient.Query.Hard.Params(heightCtx, &hardtypes.QueryParamsRequest{})
if err != nil {
return nil, err
}

return params.Params.MoneyMarkets, nil
}

// GetAuctions gets all the currently running auctions
func (c *GrpcAuctionClient) GetAuctions(height int64) ([]auctiontypes.Auction, error) {
var (
auctions []auctiontypes.Auction
key []byte
)

for {
auctionsResponse, err := c.grpcClient.Query.Auction.Auctions(context.Background(), &auctiontypes.QueryAuctionsRequest{
Pagination: &query.PageRequest{
Key: key,
Limit: c.PageLimit,
},
})
if err != nil {
return nil, err
}

for _, anyAuction := range auctionsResponse.GetAuctions() {
var auction auctiontypes.Auction
if err = c.cdc.UnpackAny(anyAuction, &auction); err != nil {
return nil, fmt.Errorf("failed to unpack auction: %w", err)
}

auctions = append(auctions, auction)
}

if auctionsResponse.Pagination == nil || auctionsResponse.Pagination.NextKey == nil {
break
}
}

return auctions, nil
}
109 changes: 109 additions & 0 deletions alerts/auctions/grpc_client_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
package auctions

import (
"encoding/json"
"fmt"
"log"
"os"
"testing"

"github.com/kava-labs/kava/app"
kava "github.com/kava-labs/kava/app"
kavagrpc "github.com/kava-labs/kava/client/grpc"

"github.com/stretchr/testify/require"
)

// pruning node stores only latest data and doesn't store historical data.
// It is much more performant and can be used for transaction search, as on archive node it is very slow.
var pruningQueryClient AuctionClient

// we should use dataQueryClient only for historical data, as pruning node doesn't contain historical data
var dataQueryClient AuctionClient

func TestMain(m *testing.M) {
app.SetSDKConfig()

// Create codec for messages
encodingConfig := kava.MakeEncodingConfig()

pruningGRPCClient, err := kavagrpc.NewClient("https://grpc.kava.io:443")
if err != nil {
log.Fatalf("grpc client failed to connect %s", err)
}

dataGRPCClient, err := kavagrpc.NewClient("https://grpc.data.infra.kava.io:443")
if err != nil {
log.Fatalf("grpc client failed to connect %s", err)
}

pruningQueryClient = NewGrpcAuctionClient(pruningGRPCClient, encodingConfig.Marshaler)
dataQueryClient = NewGrpcAuctionClient(dataGRPCClient, encodingConfig.Marshaler)

os.Exit(m.Run())
}

func TestGrpcGetInfo(t *testing.T) {
if testing.Short() {
t.Skip("skipping test in short mode")
}

info, err := pruningQueryClient.GetInfo()
require.NoError(t, err)
require.Greater(t, info.LatestHeight, int64(11000000))
require.Equal(t, "kava_2222-10", info.ChainId)
}

func TestGrpcGetPrices(t *testing.T) {
if testing.Short() {
t.Skip("skipping test in short mode")
}

prices, err := dataQueryClient.GetPrices(11000000)
require.NoError(t, err)
require.Len(t, prices, 29)
for _, price := range prices {
require.NotEmpty(t, price.MarketID)
require.NotEmpty(t, price.Price)
}
}

func TestGrpcGetAuctions(t *testing.T) {
if testing.Short() {
t.Skip("skipping test in short mode")
}

auctions, err := pruningQueryClient.GetAuctions(11000000)
require.NoError(t, err)
require.Len(t, auctions, 10)
for _, auction := range auctions {
require.NotEmpty(t, auction.GetID())
require.NotEmpty(t, auction.GetInitiator())
require.NotEmpty(t, auction.GetLot())
require.NotEmpty(t, auction.GetBid())
require.NotEmpty(t, auction.GetEndTime())
}
}

func TestGrpcGetMarkets(t *testing.T) {
if testing.Short() {
t.Skip("skipping test in short mode")
}

markets, err := dataQueryClient.GetMarkets(11000000)
require.NoError(t, err)
jsonMarkets, err := json.Marshal(markets)
fmt.Println(len(markets))
fmt.Println(string(jsonMarkets))
require.Len(t, markets, 10)
}

func TestGrpcGetMoneyMarkets(t *testing.T) {
if testing.Short() {
t.Skip("skipping test in short mode")
}

moneyMarkets, err := dataQueryClient.GetMoneyMarkets(11000000)
require.NoError(t, err)
require.Len(t, moneyMarkets, 29)
}
6 changes: 3 additions & 3 deletions alerts/auctions/rpc.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ import (
"context"
"errors"

"github.com/tendermint/tendermint/libs/bytes"
rpcclient "github.com/tendermint/tendermint/rpc/client"
ctypes "github.com/tendermint/tendermint/rpc/core/types"
"github.com/cometbft/cometbft/libs/bytes"
rpcclient "github.com/cometbft/cometbft/rpc/client"
ctypes "github.com/cometbft/cometbft/rpc/core/types"
)

type RpcClient interface {
Expand Down
Loading

0 comments on commit daae21b

Please sign in to comment.