Skip to content
This repository has been archived by the owner on Nov 16, 2022. It is now read-only.

chain: Add price_symbols endpoint #2829

Merged
merged 8 commits into from
Nov 5, 2020
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG_UNRELEASED.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

### Chain (Non-consensus)

- (feat) [\#2829](https://github.com/bandprotocol/bandchain/pull/2829) Added `price_symbols` endpoint
- (bugs) [\#2828](https://github.com/bandprotocol/bandchain/pull/2828) Add missing height on `multi_request_search` and `request_prices` endpoints
- (impv) [\#2746](https://github.com/bandprotocol/bandchain/pull/2746) Implemented emitter, price, and latest request hooks
- (impv) [\#2789](https://github.com/bandprotocol/bandchain/pull/2789) Added `bandchain/chain_id` endpoint
Expand Down
28 changes: 26 additions & 2 deletions chain/hooks/price/price.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/syndtr/goleveldb/leveldb"
"github.com/syndtr/goleveldb/leveldb/util"
abci "github.com/tendermint/tendermint/abci/types"

"github.com/bandprotocol/bandchain/chain/hooks/common"
Expand Down Expand Up @@ -74,7 +75,8 @@ func (h *Hook) AfterEndBlock(ctx sdk.Context, req abci.RequestEndBlock, res abci
obi.MustDecode(result.ResponsePacketData.Result, &output)
for idx, symbol := range input.Symbols {
price := NewPrice(symbol, input.Multiplier, output.Pxs[idx], result.ResponsePacketData.RequestID, result.ResponsePacketData.ResolveTime)
err := h.db.Put([]byte(fmt.Sprintf("%s,%d,%d", symbol, result.RequestPacketData.AskCount, result.RequestPacketData.MinCount)), h.cdc.MustMarshalBinaryBare(price), nil)
err := h.db.Put([]byte(fmt.Sprintf("%d,%d,%s", result.RequestPacketData.AskCount, result.RequestPacketData.MinCount, symbol)),
h.cdc.MustMarshalBinaryBare(price), nil)
if err != nil {
panic(err)
}
Expand All @@ -99,14 +101,36 @@ func (h *Hook) ApplyQuery(req abci.RequestQuery) (res abci.ResponseQuery, stop b
symbol := paths[2]
askCount := common.Atoui(paths[3])
minCount := common.Atoui(paths[4])
bz, err := h.db.Get([]byte(fmt.Sprintf("%s,%d,%d", symbol, askCount, minCount)), nil)
bz, err := h.db.Get([]byte(fmt.Sprintf("%d,%d,%s", askCount, minCount, symbol)), nil)
if err != nil {
return common.QueryResultError(fmt.Errorf(
"Cannot get price of %s with %d/%d counts with error: %s",
symbol, minCount, askCount, err.Error(),
)), true
}
return common.QueryResultSuccess(bz, req.Height), true
case "price_symbols":
if len(paths) < 4 {
return common.QueryResultError(errors.New("no route for symbol prices query specified")), true
}
askCount := common.Atoui(paths[2])
minCount := common.Atoui(paths[3])

prefix := []byte(fmt.Sprintf("%d,%d,", askCount, minCount))
it := h.db.NewIterator(util.BytesPrefix(prefix), nil)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good :D


symbols := []string{}
for it.Next() {
symbols = append(symbols, string(it.Key()[len(prefix):]))
}

it.Release()
if err := it.Error(); err != nil {
return common.QueryResultError(fmt.Errorf("Error while iterate over prices list: %s", err.Error())), true
}

bz := h.cdc.MustMarshalBinaryBare(symbols)
return common.QueryResultSuccess(bz, req.Height), true
default:
return abci.ResponseQuery{}, false
}
Expand Down
25 changes: 25 additions & 0 deletions chain/x/oracle/client/rest/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,31 @@ func getRequestsPricesHandler(cliCtx context.CLIContext, route string) http.Hand
}
}

func getRequestsPriceSymbolsHandler(cliCtx context.CLIContext, route string) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
cliCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r)
if !ok {
return
}

bz, height, err := cliCtx.Query(fmt.Sprintf("band/price_symbols/%s/%s", r.FormValue("ask_count"), r.FormValue("min_count")))

symbols := []string{}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using var symbols []string (Reduce unnecessarily allocate)

if err := cliCtx.Codec.UnmarshalBinaryBare(bz, &symbols); err != nil {
rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
return
}

bz, err = types.QueryOK(symbols)
if err != nil {
rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
return
}

clientcmn.PostProcessQueryResponse(w, cliCtx.WithHeight(height), bz)
}
}

func getMultiRequestSearchHandler(cliCtx context.CLIContext, route string) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
cliCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r)
Expand Down
1 change: 1 addition & 0 deletions chain/x/oracle/client/rest/rest.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ func RegisterRoutes(cliCtx context.CLIContext, r *mux.Router, storeName string)
r.HandleFunc(fmt.Sprintf("/%s/requests/{%s}", storeName, idTag), getRequestByIDHandler(cliCtx, storeName)).Methods("GET")
r.HandleFunc(fmt.Sprintf("/%s/request_search", storeName), getRequestSearchHandler(cliCtx, storeName)).Methods("GET")
r.HandleFunc(fmt.Sprintf("/%s/request_prices", storeName), getRequestsPricesHandler(cliCtx, storeName)).Methods("POST")
r.HandleFunc(fmt.Sprintf("/%s/price_symbols", storeName), getRequestsPriceSymbolsHandler(cliCtx, storeName)).Methods("GET")
r.HandleFunc(fmt.Sprintf("/%s/multi_request_search", storeName), getMultiRequestSearchHandler(cliCtx, storeName)).Methods("GET")
r.HandleFunc(fmt.Sprintf("/%s/validators/{%s}", storeName, validatorAddressTag), getValidatorStatusHandler(cliCtx, storeName)).Methods("GET")
r.HandleFunc(fmt.Sprintf("/%s/reporters/{%s}", storeName, validatorAddressTag), getReportersHandler(cliCtx, storeName)).Methods("GET")
Expand Down