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, ¶ms) 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, ¶ms) 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 }