balanceHistory: accept a list of currencies, update tests
This commit is contained in:
parent
6f06b549df
commit
171b7f9b9d
12
api/types.go
12
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
|
// BalanceHistory contains info about one point in time of balance history
|
||||||
type BalanceHistory struct {
|
type BalanceHistory struct {
|
||||||
Time uint32 `json:"time"`
|
Time uint32 `json:"time"`
|
||||||
Txs uint32 `json:"txs"`
|
Txs uint32 `json:"txs"`
|
||||||
ReceivedSat *Amount `json:"received"`
|
ReceivedSat *Amount `json:"received"`
|
||||||
SentSat *Amount `json:"sent"`
|
SentSat *Amount `json:"sent"`
|
||||||
FiatRate float64 `json:"fiatRate,omitempty"`
|
FiatRates map[string]float64 `json:"rates,omitempty"`
|
||||||
Txid string `json:"txid,omitempty"`
|
Txid string `json:"txid,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// BalanceHistories is array of BalanceHistory
|
// BalanceHistories is array of BalanceHistory
|
||||||
|
|||||||
@ -13,6 +13,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/golang/glog"
|
"github.com/golang/glog"
|
||||||
@ -913,7 +914,7 @@ func (w *Worker) balanceHistoryForTxid(addrDesc bchain.AddressDescriptor, txid s
|
|||||||
return &bh, nil
|
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 {
|
for i := range histories {
|
||||||
bh := &histories[i]
|
bh := &histories[i]
|
||||||
t := time.Unix(int64(bh.Time), 0)
|
t := time.Unix(int64(bh.Time), 0)
|
||||||
@ -924,15 +925,24 @@ func (w *Worker) setFiatRateToBalanceHistories(histories BalanceHistories, fiat
|
|||||||
} else if ticker == nil {
|
} else if ticker == nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if rate, found := ticker.Rates[fiat]; found {
|
if len(currencies) > 0 {
|
||||||
bh.FiatRate = rate
|
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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetBalanceHistory returns history of balance for given address
|
// 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)
|
bhs := make(BalanceHistories, 0)
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
addrDesc, _, err := w.getAddrDescAndNormalizeAddress(address)
|
addrDesc, _, err := w.getAddrDescAndNormalizeAddress(address)
|
||||||
@ -957,8 +967,8 @@ func (w *Worker) GetBalanceHistory(address string, fromTimestamp, toTimestamp in
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
bha := bhs.SortAndAggregate(groupBy)
|
bha := bhs.SortAndAggregate(groupBy)
|
||||||
if fiat != "" {
|
if len(currencies) > 0 {
|
||||||
err = w.setFiatRateToBalanceHistories(bha, fiat)
|
err = w.setFiatRateToBalanceHistories(bha, currencies)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -1145,25 +1155,6 @@ func (w *Worker) GetBlocks(page int, blocksOnPage int) (*Blocks, error) {
|
|||||||
return r, nil
|
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
|
// getFiatRatesResult checks if CurrencyRatesTicker contains all necessary data and returns formatted result
|
||||||
func (w *Worker) getFiatRatesResult(currency string, ticker *db.CurrencyRatesTicker) (*db.ResultTickerAsString, error) {
|
func (w *Worker) getFiatRatesResult(currency string, ticker *db.CurrencyRatesTicker) (*db.ResultTickerAsString, error) {
|
||||||
if currency == "" {
|
if currency == "" {
|
||||||
|
|||||||
@ -591,7 +591,7 @@ func (w *Worker) GetXpubUtxo(xpub string, onlyConfirmed bool, gap int) (Utxos, e
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetXpubBalanceHistory returns history of balance for given xpub
|
// 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)
|
bhs := make(BalanceHistories, 0)
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
fromUnix, fromHeight, toUnix, toHeight := w.balanceHistoryHeightsFromTo(fromTimestamp, toTimestamp)
|
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)
|
bha := bhs.SortAndAggregate(groupBy)
|
||||||
if fiat != "" {
|
if len(currencies) > 0 {
|
||||||
err = w.setFiatRateToBalanceHistories(bha, fiat)
|
err = w.setFiatRateToBalanceHistories(bha, currencies)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1069,11 +1069,15 @@ func (s *PublicServer) apiBalanceHistory(r *http.Request, apiVersion int) (inter
|
|||||||
groupBy = 3600
|
groupBy = 3600
|
||||||
}
|
}
|
||||||
fiat := r.URL.Query().Get("fiatcurrency")
|
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 {
|
if err == nil {
|
||||||
s.metrics.ExplorerViews.With(common.Labels{"action": "api-xpub-balancehistory"}).Inc()
|
s.metrics.ExplorerViews.With(common.Labels{"action": "api-xpub-balancehistory"}).Inc()
|
||||||
} else {
|
} 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()
|
s.metrics.ExplorerViews.With(common.Labels{"action": "api-address-balancehistory"}).Inc()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -785,7 +785,7 @@ func httpTestsBitcoinType(t *testing.T, ts *httptest.Server) {
|
|||||||
status: http.StatusOK,
|
status: http.StatusOK,
|
||||||
contentType: "application/json; charset=utf-8",
|
contentType: "application/json; charset=utf-8",
|
||||||
body: []string{
|
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,
|
status: http.StatusOK,
|
||||||
contentType: "application/json; charset=utf-8",
|
contentType: "application/json; charset=utf-8",
|
||||||
body: []string{
|
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"}]}`,
|
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{
|
req: websocketReq{
|
||||||
Method: "getBalanceHistory",
|
Method: "getBalanceHistory",
|
||||||
Params: map[string]interface{}{
|
Params: map[string]interface{}{
|
||||||
"descriptor": dbtestdata.Xpub,
|
"descriptor": dbtestdata.Xpub,
|
||||||
"from": 1521504000,
|
"from": 1521504000,
|
||||||
"to": 1521590400,
|
"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"}]}`,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -259,12 +259,12 @@ var requestHandlers = map[string]func(*WebsocketServer, *websocketChannel, *webs
|
|||||||
},
|
},
|
||||||
"getBalanceHistory": func(s *WebsocketServer, c *websocketChannel, req *websocketReq) (rv interface{}, err error) {
|
"getBalanceHistory": func(s *WebsocketServer, c *websocketChannel, req *websocketReq) (rv interface{}, err error) {
|
||||||
r := struct {
|
r := struct {
|
||||||
Descriptor string `json:"descriptor"`
|
Descriptor string `json:"descriptor"`
|
||||||
From int64 `json:"from"`
|
From int64 `json:"from"`
|
||||||
To int64 `json:"to"`
|
To int64 `json:"to"`
|
||||||
Fiat string `json:"fiat"`
|
Currencies []string `json:"currencies"`
|
||||||
Gap int `json:"gap"`
|
Gap int `json:"gap"`
|
||||||
GroupBy uint32 `json:"groupBy"`
|
GroupBy uint32 `json:"groupBy"`
|
||||||
}{}
|
}{}
|
||||||
err = json.Unmarshal(req.Params, &r)
|
err = json.Unmarshal(req.Params, &r)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
@ -277,9 +277,9 @@ var requestHandlers = map[string]func(*WebsocketServer, *websocketChannel, *webs
|
|||||||
if r.GroupBy <= 0 {
|
if r.GroupBy <= 0 {
|
||||||
r.GroupBy = 3600
|
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 {
|
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
|
return
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user