github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/x/order/keeper/querier.go (about)

     1  package keeper
     2  
     3  import (
     4  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/codec"
     5  	sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types"
     6  	abci "github.com/fibonacci-chain/fbc/libs/tendermint/abci/types"
     7  
     8  	"github.com/fibonacci-chain/fbc/x/common"
     9  	"github.com/fibonacci-chain/fbc/x/order/types"
    10  )
    11  
    12  // nolint
    13  const (
    14  	DefaultBookSize = 200
    15  )
    16  
    17  // NewQuerier is the module level router for state queries
    18  func NewQuerier(keeper Keeper) sdk.Querier {
    19  	return func(ctx sdk.Context, path []string, req abci.RequestQuery) (res []byte, err sdk.Error) {
    20  		switch path[0] {
    21  		case types.QueryOrderDetail:
    22  			return queryOrder(ctx, path[1:], req, keeper)
    23  		case types.QueryDepthBook:
    24  			return queryDepthBook(ctx, path[1:], req, keeper)
    25  		case types.QueryStore:
    26  			return queryStore(ctx, path[1:], req, keeper)
    27  		case types.QueryParameters:
    28  			return queryParameters(ctx, keeper)
    29  
    30  		case types.QueryDepthBookV2:
    31  			return queryDepthBookV2(ctx, path[1:], req, keeper)
    32  		default:
    33  			return nil, types.ErrUnknownOrderQueryType()
    34  		}
    35  	}
    36  }
    37  
    38  // nolint: unparam
    39  func queryOrder(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Keeper) (res []byte,
    40  	err sdk.Error) {
    41  	order := keeper.GetOrder(ctx, path[0])
    42  	if order == nil {
    43  		return nil, types.ErrOrderIsNotExist(path[0])
    44  	}
    45  	bz := keeper.cdc.MustMarshalJSON(order)
    46  	return bz, nil
    47  }
    48  
    49  // QueryDepthBookParams as input parameters when querying the depthBook
    50  type QueryDepthBookParams struct {
    51  	Product string
    52  	Size    uint
    53  }
    54  
    55  // NewQueryDepthBookParams creates a new instance of QueryProposalParams
    56  func NewQueryDepthBookParams(product string, size uint) QueryDepthBookParams {
    57  	if size == 0 {
    58  		size = DefaultBookSize
    59  	}
    60  	return QueryDepthBookParams{
    61  		Product: product,
    62  		Size:    size,
    63  	}
    64  }
    65  
    66  // nolint
    67  type BookResItem struct {
    68  	Price    string `json:"price"`
    69  	Quantity string `json:"quantity"`
    70  }
    71  
    72  // BookRes is used to return the result of queryDepthBook
    73  type BookRes struct {
    74  	Asks []BookResItem `json:"asks"`
    75  	Bids []BookResItem `json:"bids"`
    76  }
    77  
    78  // nolint: unparam
    79  func queryDepthBook(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Keeper) ([]byte,
    80  	sdk.Error) {
    81  	var params QueryDepthBookParams
    82  	err := keeper.cdc.UnmarshalJSON(req.Data, &params)
    83  	if err != nil {
    84  		return nil, common.ErrUnMarshalJSONFailed("incorrectly formatted request Data")
    85  	}
    86  	if params.Size == 0 {
    87  		return nil, types.ErrInvalidSizeParam(params.Size)
    88  	}
    89  	tokenPair := keeper.GetDexKeeper().GetTokenPair(ctx, params.Product)
    90  	if tokenPair == nil {
    91  		return nil, types.ErrOrderIsNotExist(params.Product)
    92  	}
    93  	depthBook := keeper.GetDepthBookFromDB(ctx, params.Product)
    94  
    95  	var asks []BookResItem
    96  	var bids []BookResItem
    97  	for _, item := range depthBook.Items {
    98  		if item.SellQuantity.IsPositive() {
    99  			asks = append([]BookResItem{{item.Price.String(), item.SellQuantity.String()}}, asks...)
   100  		}
   101  		if item.BuyQuantity.IsPositive() {
   102  			bids = append(bids, BookResItem{item.Price.String(), item.BuyQuantity.String()})
   103  		}
   104  	}
   105  	if uint(len(asks)) > params.Size {
   106  		asks = asks[:params.Size]
   107  	}
   108  	if uint(len(bids)) > params.Size {
   109  		bids = bids[:params.Size]
   110  	}
   111  
   112  	bookRes := BookRes{
   113  		Asks: asks,
   114  		Bids: bids,
   115  	}
   116  	bz := keeper.cdc.MustMarshalJSON(bookRes)
   117  	return bz, nil
   118  }
   119  
   120  // StoreStatistic is used to store the state of depthBook
   121  type StoreStatistic struct {
   122  	StoreOrderNum   int64
   123  	DepthBookNum    map[string]int64
   124  	BookOrderIDsNum map[string]int64
   125  }
   126  
   127  func getStoreStatistic(ctx sdk.Context, keeper Keeper) *StoreStatistic {
   128  	storeOrderNum := keeper.GetStoreOrderNum(ctx)
   129  	ss := &StoreStatistic{
   130  		StoreOrderNum: storeOrderNum,
   131  	}
   132  
   133  	depthBookMap := make(map[string]types.DepthBook)
   134  
   135  	depthStore := ctx.KVStore(keeper.orderStoreKey)
   136  	iter := sdk.KVStorePrefixIterator(depthStore, types.DepthBookKey)
   137  
   138  	defer iter.Close()
   139  
   140  	for ; iter.Valid(); iter.Next() {
   141  		var depthBook types.DepthBook
   142  		bz := iter.Value()
   143  		keeper.cdc.MustUnmarshalBinaryBare(bz, &depthBook)
   144  		depthBookMap[types.GetKey(iter)] = depthBook
   145  	}
   146  	ss.DepthBookNum = make(map[string]int64, len(depthBookMap))
   147  	ss.BookOrderIDsNum = make(map[string]int64, len(depthBookMap)*500)
   148  	for product, depthBook := range depthBookMap {
   149  		ss.DepthBookNum[product] = int64(len(depthBook.Items))
   150  		for _, item := range depthBook.Items {
   151  			if item.BuyQuantity.IsPositive() {
   152  				key := types.FormatOrderIDsKey(product, item.Price, types.BuyOrder)
   153  				orderIDs := keeper.GetProductPriceOrderIDs(key)
   154  				ss.BookOrderIDsNum[key] = int64(len(orderIDs))
   155  			}
   156  			if item.SellQuantity.IsPositive() {
   157  				key := types.FormatOrderIDsKey(product, item.Price, types.SellOrder)
   158  				orderIDs := keeper.GetProductPriceOrderIDs(key)
   159  				ss.BookOrderIDsNum[key] = int64(len(orderIDs))
   160  			}
   161  		}
   162  	}
   163  	return ss
   164  }
   165  
   166  func queryStore(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Keeper) ([]byte,
   167  	sdk.Error) {
   168  	ss := getStoreStatistic(ctx, keeper)
   169  	bz := keeper.cdc.MustMarshalJSON(ss)
   170  	return bz, nil
   171  }
   172  
   173  func queryParameters(ctx sdk.Context, keeper Keeper) (res []byte, err sdk.Error) {
   174  	params := keeper.GetParams(ctx)
   175  	res, errRes := codec.MarshalJSONIndent(keeper.cdc, params)
   176  	if errRes != nil {
   177  		return nil, common.ErrMarshalJSONFailed(errRes.Error())
   178  	}
   179  	return res, nil
   180  }
   181  
   182  func queryDepthBookV2(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Keeper) ([]byte, sdk.Error) {
   183  	var params QueryDepthBookParams
   184  	err := keeper.cdc.UnmarshalJSON(req.Data, &params)
   185  	if err != nil {
   186  		return nil, common.ErrUnMarshalJSONFailed(err.Error())
   187  	}
   188  	if params.Size == 0 {
   189  		return nil, types.ErrInvalidSizeParam(params.Size)
   190  	}
   191  	depthBook := keeper.GetDepthBookFromDB(ctx, params.Product)
   192  
   193  	var asks []BookResItem
   194  	var bids []BookResItem
   195  	for _, item := range depthBook.Items {
   196  		if item.SellQuantity.IsPositive() {
   197  			asks = append([]BookResItem{{item.Price.String(), item.SellQuantity.String()}}, asks...)
   198  		}
   199  		if item.BuyQuantity.IsPositive() {
   200  			bids = append(bids, BookResItem{item.Price.String(), item.BuyQuantity.String()})
   201  		}
   202  	}
   203  	if uint(len(asks)) > params.Size {
   204  		asks = asks[:params.Size]
   205  	}
   206  	if uint(len(bids)) > params.Size {
   207  		bids = bids[:params.Size]
   208  	}
   209  
   210  	bookRes := BookRes{
   211  		Asks: asks,
   212  		Bids: bids,
   213  	}
   214  
   215  	res, err := common.JSONMarshalV2(bookRes)
   216  	if err != nil {
   217  		return nil, common.ErrMarshalJSONFailed(err.Error())
   218  	}
   219  	return res, nil
   220  }