From 171b7f9b9de10eec89c211ae3f833cfa41736f81 Mon Sep 17 00:00:00 2001 From: Vladyslav Burzakovskyy Date: Tue, 21 Jan 2020 18:57:55 +0100 Subject: [PATCH] balanceHistory: accept a list of currencies, update tests --- api/types.go | 12 ++++++------ api/worker.go | 41 ++++++++++++++++------------------------- api/xpub.go | 6 +++--- server/public.go | 8 ++++++-- server/public_test.go | 36 +++++++++++++++++++++++++++++++----- server/websocket.go | 16 ++++++++-------- 6 files changed, 70 insertions(+), 49 deletions(-) diff --git a/api/types.go b/api/types.go index 518a62c9..0b97ae49 100644 --- a/api/types.go +++ b/api/types.go @@ -299,12 +299,12 @@ func (a Utxos) Less(i, j int) bool { // BalanceHistory contains info about one point in time of balance history type BalanceHistory struct { - Time uint32 `json:"time"` - Txs uint32 `json:"txs"` - ReceivedSat *Amount `json:"received"` - SentSat *Amount `json:"sent"` - FiatRate float64 `json:"fiatRate,omitempty"` - Txid string `json:"txid,omitempty"` + Time uint32 `json:"time"` + Txs uint32 `json:"txs"` + ReceivedSat *Amount `json:"received"` + SentSat *Amount `json:"sent"` + FiatRates map[string]float64 `json:"rates,omitempty"` + Txid string `json:"txid,omitempty"` } // BalanceHistories is array of BalanceHistory diff --git a/api/worker.go b/api/worker.go index 30e4e385..6477a5ed 100644 --- a/api/worker.go +++ b/api/worker.go @@ -13,6 +13,7 @@ import ( "os" "sort" "strconv" + "strings" "time" "github.com/golang/glog" @@ -913,7 +914,7 @@ func (w *Worker) balanceHistoryForTxid(addrDesc bchain.AddressDescriptor, txid s return &bh, nil } -func (w *Worker) setFiatRateToBalanceHistories(histories BalanceHistories, fiat string) error { +func (w *Worker) setFiatRateToBalanceHistories(histories BalanceHistories, currencies []string) error { for i := range histories { bh := &histories[i] t := time.Unix(int64(bh.Time), 0) @@ -924,15 +925,24 @@ func (w *Worker) setFiatRateToBalanceHistories(histories BalanceHistories, fiat } else if ticker == nil { continue } - if rate, found := ticker.Rates[fiat]; found { - bh.FiatRate = rate + if len(currencies) > 0 { + rates := make(map[string]float64) + for _, currency := range currencies { + currency = strings.ToLower(currency) + if rate, found := ticker.Rates[currency]; found { + rates[currency] = rate + } else { + rates[currency] = -1 + } + } + bh.FiatRates = rates } } return nil } // GetBalanceHistory returns history of balance for given address -func (w *Worker) GetBalanceHistory(address string, fromTimestamp, toTimestamp int64, fiat string, groupBy uint32) (BalanceHistories, error) { +func (w *Worker) GetBalanceHistory(address string, fromTimestamp, toTimestamp int64, currencies []string, groupBy uint32) (BalanceHistories, error) { bhs := make(BalanceHistories, 0) start := time.Now() addrDesc, _, err := w.getAddrDescAndNormalizeAddress(address) @@ -957,8 +967,8 @@ func (w *Worker) GetBalanceHistory(address string, fromTimestamp, toTimestamp in } } bha := bhs.SortAndAggregate(groupBy) - if fiat != "" { - err = w.setFiatRateToBalanceHistories(bha, fiat) + if len(currencies) > 0 { + err = w.setFiatRateToBalanceHistories(bha, currencies) if err != nil { return nil, err } @@ -1145,25 +1155,6 @@ func (w *Worker) GetBlocks(page int, blocksOnPage int) (*Blocks, error) { return r, nil } -// getFiatRatesResults checks if CurrencyRatesTicker contains all necessary data and returns formatted result -func (w *Worker) getFiatRatesResults(currency string, ticker *db.CurrencyRatesTicker) (*db.ResultTickerAsString, error) { - if currency == "" { - return &db.ResultTickerAsString{ - Timestamp: ticker.Timestamp.UTC().Unix(), - Rates: ticker.Rates, - }, nil - } - timestamp := ticker.Timestamp.UTC().Unix() - if rate, found := ticker.Rates[currency]; !found { - return nil, NewAPIError(fmt.Sprintf("Currency %q is not available for timestamp %d.", currency, timestamp), true) - } else { - return &db.ResultTickerAsString{ - Timestamp: timestamp, - Rates: map[string]float64{currency: rate}, - }, nil - } -} - // getFiatRatesResult checks if CurrencyRatesTicker contains all necessary data and returns formatted result func (w *Worker) getFiatRatesResult(currency string, ticker *db.CurrencyRatesTicker) (*db.ResultTickerAsString, error) { if currency == "" { diff --git a/api/xpub.go b/api/xpub.go index 49945ad2..7f9e8440 100644 --- a/api/xpub.go +++ b/api/xpub.go @@ -591,7 +591,7 @@ func (w *Worker) GetXpubUtxo(xpub string, onlyConfirmed bool, gap int) (Utxos, e } // GetXpubBalanceHistory returns history of balance for given xpub -func (w *Worker) GetXpubBalanceHistory(xpub string, fromTimestamp, toTimestamp int64, fiat string, gap int, groupBy uint32) (BalanceHistories, error) { +func (w *Worker) GetXpubBalanceHistory(xpub string, fromTimestamp, toTimestamp int64, currencies []string, gap int, groupBy uint32) (BalanceHistories, error) { bhs := make(BalanceHistories, 0) start := time.Now() fromUnix, fromHeight, toUnix, toHeight := w.balanceHistoryHeightsFromTo(fromTimestamp, toTimestamp) @@ -623,8 +623,8 @@ func (w *Worker) GetXpubBalanceHistory(xpub string, fromTimestamp, toTimestamp i } } bha := bhs.SortAndAggregate(groupBy) - if fiat != "" { - err = w.setFiatRateToBalanceHistories(bha, fiat) + if len(currencies) > 0 { + err = w.setFiatRateToBalanceHistories(bha, currencies) if err != nil { return nil, err } diff --git a/server/public.go b/server/public.go index a9188bcd..d0cea301 100644 --- a/server/public.go +++ b/server/public.go @@ -1069,11 +1069,15 @@ func (s *PublicServer) apiBalanceHistory(r *http.Request, apiVersion int) (inter groupBy = 3600 } fiat := r.URL.Query().Get("fiatcurrency") - history, err = s.api.GetXpubBalanceHistory(r.URL.Path[i+1:], fromTimestamp, toTimestamp, fiat, gap, uint32(groupBy)) + var fiatArray []string + if fiat != "" { + fiatArray = []string{fiat} + } + history, err = s.api.GetXpubBalanceHistory(r.URL.Path[i+1:], fromTimestamp, toTimestamp, fiatArray, gap, uint32(groupBy)) if err == nil { s.metrics.ExplorerViews.With(common.Labels{"action": "api-xpub-balancehistory"}).Inc() } else { - history, err = s.api.GetBalanceHistory(r.URL.Path[i+1:], fromTimestamp, toTimestamp, fiat, uint32(groupBy)) + history, err = s.api.GetBalanceHistory(r.URL.Path[i+1:], fromTimestamp, toTimestamp, fiatArray, uint32(groupBy)) s.metrics.ExplorerViews.With(common.Labels{"action": "api-address-balancehistory"}).Inc() } } diff --git a/server/public_test.go b/server/public_test.go index 621ff9c3..2c91271b 100644 --- a/server/public_test.go +++ b/server/public_test.go @@ -785,7 +785,7 @@ func httpTestsBitcoinType(t *testing.T, ts *httptest.Server) { status: http.StatusOK, contentType: "application/json; charset=utf-8", body: []string{ - `[{"time":1521514800,"txs":1,"received":"9876","sent":"0","fiatRate":1301},{"time":1521594000,"txs":1,"received":"9000","sent":"9876","fiatRate":1303}]`, + `[{"time":1521514800,"txs":1,"received":"9876","sent":"0","rates":{"eur":1301}},{"time":1521594000,"txs":1,"received":"9000","sent":"9876","rates":{"eur":1303}}]`, }, }, { @@ -821,7 +821,7 @@ func httpTestsBitcoinType(t *testing.T, ts *httptest.Server) { status: http.StatusOK, contentType: "application/json; charset=utf-8", body: []string{ - `[{"time":1521514800,"txs":1,"received":"1","sent":"0","fiatRate":2001}]`, + `[{"time":1521514800,"txs":1,"received":"1","sent":"0","rates":{"usd":2001}}]`, }, }, { @@ -1363,17 +1363,43 @@ func websocketTestsBitcoinType(t *testing.T, ts *httptest.Server) { want: `{"id":"32","data":[{"time":1521514800,"txs":1,"received":"1","sent":"0"},{"time":1521594000,"txs":1,"received":"118641975500","sent":"1"}]}`, }, { - name: "websocket getBalanceHistory xpub from=1521504000&to=1521590400&fiat=usd", + name: "websocket getBalanceHistory xpub from=1521504000&to=1521590400 currencies=[usd]", req: websocketReq{ Method: "getBalanceHistory", Params: map[string]interface{}{ "descriptor": dbtestdata.Xpub, "from": 1521504000, "to": 1521590400, - "fiat": "usd", + "currencies": []string{"usd"}, }, }, - want: `{"id":"33","data":[{"time":1521514800,"txs":1,"received":"1","sent":"0","fiatRate":2001}]}`, + want: `{"id":"33","data":[{"time":1521514800,"txs":1,"received":"1","sent":"0","rates":{"usd":2001}}]}`, + }, + { + name: "websocket getBalanceHistory xpub from=1521504000&to=1521590400 currencies=[usd, eur, incorrect]", + req: websocketReq{ + Method: "getBalanceHistory", + Params: map[string]interface{}{ + "descriptor": dbtestdata.Xpub, + "from": 1521504000, + "to": 1521590400, + "currencies": []string{"usd", "eur", "incorrect"}, + }, + }, + want: `{"id":"34","data":[{"time":1521514800,"txs":1,"received":"1","sent":"0","rates":{"eur":1301,"incorrect":-1,"usd":2001}}]}`, + }, + { + name: "websocket getBalanceHistory xpub from=1521504000&to=1521590400 currencies=[]", + req: websocketReq{ + Method: "getBalanceHistory", + Params: map[string]interface{}{ + "descriptor": dbtestdata.Xpub, + "from": 1521504000, + "to": 1521590400, + "currencies": []string{}, + }, + }, + want: `{"id":"35","data":[{"time":1521514800,"txs":1,"received":"1","sent":"0"}]}`, }, } diff --git a/server/websocket.go b/server/websocket.go index 980bf490..e051b9eb 100644 --- a/server/websocket.go +++ b/server/websocket.go @@ -259,12 +259,12 @@ var requestHandlers = map[string]func(*WebsocketServer, *websocketChannel, *webs }, "getBalanceHistory": func(s *WebsocketServer, c *websocketChannel, req *websocketReq) (rv interface{}, err error) { r := struct { - Descriptor string `json:"descriptor"` - From int64 `json:"from"` - To int64 `json:"to"` - Fiat string `json:"fiat"` - Gap int `json:"gap"` - GroupBy uint32 `json:"groupBy"` + Descriptor string `json:"descriptor"` + From int64 `json:"from"` + To int64 `json:"to"` + Currencies []string `json:"currencies"` + Gap int `json:"gap"` + GroupBy uint32 `json:"groupBy"` }{} err = json.Unmarshal(req.Params, &r) if err == nil { @@ -277,9 +277,9 @@ var requestHandlers = map[string]func(*WebsocketServer, *websocketChannel, *webs if r.GroupBy <= 0 { r.GroupBy = 3600 } - rv, err = s.api.GetXpubBalanceHistory(r.Descriptor, r.From, r.To, strings.ToLower(r.Fiat), r.Gap, r.GroupBy) + rv, err = s.api.GetXpubBalanceHistory(r.Descriptor, r.From, r.To, r.Currencies, r.Gap, r.GroupBy) if err != nil { - rv, err = s.api.GetBalanceHistory(r.Descriptor, r.From, r.To, strings.ToLower(r.Fiat), r.GroupBy) + rv, err = s.api.GetBalanceHistory(r.Descriptor, r.From, r.To, r.Currencies, r.GroupBy) } } return