From 9798b33ca9618cd8c96e2861464837ab9ced74a9 Mon Sep 17 00:00:00 2001 From: Cong Zhao Date: Sun, 4 Aug 2019 14:04:26 +0800 Subject: [PATCH] add levels parameter to depth ABCI query --- CHANGELOG_PENDING.md | 3 ++- plugins/dex/abci.go | 25 ++++++++++++++++++---- plugins/dex/client/cli/commands.go | 1 + plugins/dex/client/cli/tx.go | 8 ++++++- plugins/dex/client/rest/getdepth.go | 33 +++++++++++++---------------- plugins/dex/store/codec.go | 8 +++---- 6 files changed, 50 insertions(+), 28 deletions(-) diff --git a/CHANGELOG_PENDING.md b/CHANGELOG_PENDING.md index 4ab1781b3..7d54ebb3e 100644 --- a/CHANGELOG_PENDING.md +++ b/CHANGELOG_PENDING.md @@ -5,4 +5,5 @@ BUG FIXES * [\#641](https://github.com/binance-chain/node/pull/641) [Dex] Add max lock time in time lock plugin IMPROVEMENTS -* [\#638](https://github.com/binance-chain/node/pull/638) [Pub] BEP39 - add memo to transfer kafka message \ No newline at end of file +* [\#638](https://github.com/binance-chain/node/pull/638) [Pub] BEP39 - add memo to transfer kafka message +* [\#639](https://github.com/binance-chain/node/pull/639) [ABCI] add levels parameter to depth ABCI query \ No newline at end of file diff --git a/plugins/dex/abci.go b/plugins/dex/abci.go index 8cc5723e5..00616c057 100644 --- a/plugins/dex/abci.go +++ b/plugins/dex/abci.go @@ -15,7 +15,8 @@ import ( ) // TODO: improve, should be configurable -const MaxDepthLevels = 100 // matches UI requirement +const MaxDepthLevels = 1000 // matches UI requirement +const DefaultDepthLevels = 100 // matches UI requirement func createAbciQueryHandler(keeper *DexKeeper) app.AbciQueryHandler { return func(app app.ChainApp, req abci.RequestQuery, path []string) (res *abci.ResponseQuery) { @@ -80,16 +81,32 @@ func createAbciQueryHandler(keeper *DexKeeper) app.AbciQueryHandler { Value: bz, } case "orderbook": // args: ["dex", "orderbook"] - //TODO: sync lock, validate pair, level number + //TODO: sync lock, validate pair if len(path) < 3 { return &abci.ResponseQuery{ Code: uint32(sdk.CodeUnknownRequest), - Log: "OrderBook query requires the pair symbol", + Log: "OrderBook query requires the pair symbol and levels", } } pair := path[2] height := app.GetContextForCheckState().BlockHeight() - levels := keeper.GetOrderBookLevels(pair, MaxDepthLevels) + levelLimit := DefaultDepthLevels + if len(path) == 4 { + if l, err := strconv.Atoi(path[3]); err != nil { + return &abci.ResponseQuery{ + Code: uint32(sdk.CodeUnknownRequest), + Log: fmt.Sprintf("OrderBook query requires valid int levels parameter: %v", err), + } + } else if l <= 0 || l > MaxDepthLevels { + return &abci.ResponseQuery{ + Code: uint32(sdk.CodeUnknownRequest), + Log: "OrderBook query requires valid levels (>0 && <1000)", + } + } else { + levelLimit = l + } + } + levels := keeper.GetOrderBookLevels(pair, levelLimit) book := store.OrderBook{ Height: height, Levels: levels, diff --git a/plugins/dex/client/cli/commands.go b/plugins/dex/client/cli/commands.go index 31716ac55..30c3b1f3c 100644 --- a/plugins/dex/client/cli/commands.go +++ b/plugins/dex/client/cli/commands.go @@ -9,6 +9,7 @@ import ( const ( flagSymbol = "symbol" + flagLevels = "levels" ) func AddCommands(cmd *cobra.Command, cdc *wire.Codec) { diff --git a/plugins/dex/client/cli/tx.go b/plugins/dex/client/cli/tx.go index eb335a8ce..e0b7a7d1e 100644 --- a/plugins/dex/client/cli/tx.go +++ b/plugins/dex/client/cli/tx.go @@ -16,6 +16,7 @@ import ( "github.com/binance-chain/node/common/client" "github.com/binance-chain/node/common/types" "github.com/binance-chain/node/common/utils" + "github.com/binance-chain/node/plugins/dex" "github.com/binance-chain/node/plugins/dex/order" "github.com/binance-chain/node/plugins/dex/store" "github.com/binance-chain/node/wire" @@ -95,6 +96,7 @@ func newOrderCmd(cdc *wire.Codec) *cobra.Command { }, } cmd.Flags().StringP(flagSymbol, "l", "", "the listed trading pair, such as ADA_BNB") + cmd.Flags().IntP(flagLevels, "L", 100, "maximum level (1,5,10,20,50,100,500,1000) to return") cmd.Flags().StringP(flagSide, "s", "", "side (buy as 1 or sell as 2) of the order") cmd.Flags().StringP(flagPrice, "p", "", "price for the order") cmd.Flags().StringP(flagQty, "q", "", "quantity for the order") @@ -114,8 +116,12 @@ func showOrderBookCmd(cdc *wire.Codec) *cobra.Command { if err != nil { return err } + levelsLimit := viper.GetInt(flagLevels) + if levelsLimit <= 0 || levelsLimit > dex.MaxDepthLevels { + return fmt.Errorf("%s should be greater than 0 and not exceed %d", flagLevels, dex.MaxDepthLevels) + } - ob, err := store.GetOrderBook(cdc, ctx, symbol) + ob, err := store.GetOrderBook(cdc, ctx, symbol, levelsLimit) if err != nil { return err } diff --git a/plugins/dex/client/rest/getdepth.go b/plugins/dex/client/rest/getdepth.go index 36a03216c..3d5b04c59 100644 --- a/plugins/dex/client/rest/getdepth.go +++ b/plugins/dex/client/rest/getdepth.go @@ -4,7 +4,6 @@ import ( "errors" "net/http" "strconv" - "strings" "github.com/cosmos/cosmos-sdk/client/context" @@ -13,12 +12,10 @@ import ( "github.com/binance-chain/node/wire" ) -const allowedLimits = "5,10,20,50,100" -const defaultLimit = "100" +var allowedLimits = [7]int{5, 10, 20, 50, 100, 500, 1000} // DepthReqHandler creates an http request handler to show market depth data func DepthReqHandler(cdc *wire.Codec, ctx context.CLIContext) http.HandlerFunc { - allowedLimitsA := strings.Split(allowedLimits, ",") type params struct { symbol string @@ -36,24 +33,24 @@ func DepthReqHandler(cdc *wire.Codec, ctx context.CLIContext) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { limitStr := r.FormValue("limit") + limit, err := strconv.Atoi(limitStr) + if err != nil { + throw(w, http.StatusExpectationFailed, errors.New("invalid limit, supported limits: [5,10,20,50,100,500,1000]")) + return + } // validate limit param - limitStrOk := defaultLimit - for _, lmt := range allowedLimitsA { - if lmt == limitStr { - limitStrOk = limitStr + limitOk := -1 + for _, lmt := range allowedLimits { + if lmt == limit { + limitOk = lmt break } } - limit, _ := strconv.Atoi(defaultLimit) - if len(limitStrOk) > 0 { - var err error - limit, err = strconv.Atoi(limitStrOk) - if err != nil { - throw(w, http.StatusExpectationFailed, errors.New("invalid limit")) - return - } + if limitOk == -1 { + throw(w, http.StatusExpectationFailed, errors.New("invalid limit, supported limits: [5,10,20,50,100,500,1000]")) + return } // collect params @@ -63,14 +60,14 @@ func DepthReqHandler(cdc *wire.Codec, ctx context.CLIContext) http.HandlerFunc { } // validate pair - err := store.ValidatePairSymbol(params.symbol) + err = store.ValidatePairSymbol(params.symbol) if err != nil { throw(w, http.StatusNotFound, err) return } // query order book (includes block height) - ob, err := store.GetOrderBook(cdc, ctx, params.symbol) + ob, err := store.GetOrderBook(cdc, ctx, params.symbol, params.limit) if err != nil { throw(w, http.StatusInternalServerError, err) return diff --git a/plugins/dex/store/codec.go b/plugins/dex/store/codec.go index 6cfd9a3a3..301cf7aca 100644 --- a/plugins/dex/store/codec.go +++ b/plugins/dex/store/codec.go @@ -9,8 +9,8 @@ import ( ) // queryOrderBook queries the store for the serialized order book for a given pair. -func queryOrderBook(cdc *wire.Codec, ctx context.CLIContext, pair string) (*[]byte, error) { - bz, err := ctx.Query(fmt.Sprintf("dex/orderbook/%s", pair), nil) +func queryOrderBook(cdc *wire.Codec, ctx context.CLIContext, pair string, levels int) (*[]byte, error) { + bz, err := ctx.Query(fmt.Sprintf("dex/orderbook/%s/%d", pair, levels), nil) if err != nil { return nil, err } @@ -28,8 +28,8 @@ func decodeOrderBook(cdc *wire.Codec, bz *[]byte) (*OrderBook, error) { } // GetOrderBook decodes the order book from the serialized store -func GetOrderBook(cdc *wire.Codec, ctx context.CLIContext, pair string) (*OrderBook, error) { - bz, err := queryOrderBook(cdc, ctx, pair) +func GetOrderBook(cdc *wire.Codec, ctx context.CLIContext, pair string, levels int) (*OrderBook, error) { + bz, err := queryOrderBook(cdc, ctx, pair, levels) if err != nil { return nil, err }