mirror of
https://github.com/lightninglabs/faraday.git
synced 2026-08-13 12:33:35 +02:00
multi: rename USDPrice struct to Price
Rename the USDPrice struct to Price so that it can be used to represent more than 1 currency.
This commit is contained in:
parent
165414a15a
commit
8b213c7640
12 changed files with 42 additions and 41 deletions
|
|
@ -11,7 +11,7 @@ import (
|
|||
)
|
||||
|
||||
// usdPrice is a function which gets the USD price of bitcoin at a given time.
|
||||
type usdPrice func(timestamp time.Time) (*fiat.USDPrice, error)
|
||||
type usdPrice func(timestamp time.Time) (*fiat.Price, error)
|
||||
|
||||
// satsToMsat converts an amount expressed in sats to msat.
|
||||
func satsToMsat(sats btcutil.Amount) int64 {
|
||||
|
|
@ -39,8 +39,8 @@ func getConversion(ctx context.Context, startTime, endTime time.Time,
|
|||
// If we don't want fiat values, just return a price which will yield
|
||||
// a zero price and timestamp.
|
||||
if disableFiat {
|
||||
return func(_ time.Time) (*fiat.USDPrice, error) {
|
||||
return &fiat.USDPrice{}, nil
|
||||
return func(_ time.Time) (*fiat.Price, error) {
|
||||
return &fiat.Price{}, nil
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
|
@ -64,7 +64,7 @@ func getConversion(ctx context.Context, startTime, endTime time.Time,
|
|||
|
||||
// Create a wrapper function which can be used to get individual price
|
||||
// points from our set of price data as we create our report.
|
||||
return func(ts time.Time) (*fiat.USDPrice, error) {
|
||||
return func(ts time.Time) (*fiat.Price, error) {
|
||||
return fiat.GetPrice(prices, ts)
|
||||
}, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -163,7 +163,7 @@ var (
|
|||
|
||||
mockPriceTimestamp = time.Unix(1594306589, 0)
|
||||
|
||||
mockBTCPrice = &fiat.USDPrice{
|
||||
mockBTCPrice = &fiat.Price{
|
||||
Timestamp: mockPriceTimestamp,
|
||||
Price: decimal.NewFromInt(100000),
|
||||
}
|
||||
|
|
@ -178,7 +178,7 @@ var (
|
|||
)
|
||||
|
||||
// mockPrice is a mocked price function which returns mockPrice * amount.
|
||||
func mockPrice(_ time.Time) (*fiat.USDPrice, error) {
|
||||
func mockPrice(_ time.Time) (*fiat.Price, error) {
|
||||
return mockBTCPrice, nil
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ type HarmonyEntry struct {
|
|||
|
||||
// BTCPrice is the timestamped bitcoin price we used to get our fiat
|
||||
// value.
|
||||
BTCPrice *fiat.USDPrice
|
||||
BTCPrice *fiat.Price
|
||||
}
|
||||
|
||||
// newHarmonyEntry produces a harmony entry. If provided with a negative amount,
|
||||
|
|
|
|||
|
|
@ -127,7 +127,7 @@ type coinCapAPI struct {
|
|||
|
||||
// convert produces usd prices from the output of the query function.
|
||||
// It is set within the struct so that it can be mocked for testing.
|
||||
convert func([]byte) ([]*USDPrice, error)
|
||||
convert func([]byte) ([]*Price, error)
|
||||
}
|
||||
|
||||
// newCoinCapAPI returns a coin cap api struct which can be used to query
|
||||
|
|
@ -176,13 +176,13 @@ type coinCapDataPoint struct {
|
|||
|
||||
// parseCoinCapData parses http response data to usc price structs, using
|
||||
// intermediary structs to get around parsing.
|
||||
func parseCoinCapData(data []byte) ([]*USDPrice, error) {
|
||||
func parseCoinCapData(data []byte) ([]*Price, error) {
|
||||
var priceEntries coinCapResponse
|
||||
if err := json.Unmarshal(data, &priceEntries); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var usdRecords = make([]*USDPrice, len(priceEntries.Data))
|
||||
var usdRecords = make([]*Price, len(priceEntries.Data))
|
||||
|
||||
// Convert each entry from the api to a usable record with a converted
|
||||
// time and parsed price.
|
||||
|
|
@ -193,7 +193,7 @@ func parseCoinCapData(data []byte) ([]*USDPrice, error) {
|
|||
}
|
||||
|
||||
ns := time.Duration(entry.Timestamp) * time.Millisecond
|
||||
usdRecords[i] = &USDPrice{
|
||||
usdRecords[i] = &Price{
|
||||
Timestamp: time.Unix(0, ns.Nanoseconds()),
|
||||
Price: decPrice,
|
||||
}
|
||||
|
|
@ -206,7 +206,7 @@ func parseCoinCapData(data []byte) ([]*USDPrice, error) {
|
|||
// requested is more than coincap will serve us in a single request, we break
|
||||
// our queries up into multiple chunks.
|
||||
func (c *coinCapAPI) rawPriceData(ctx context.Context, startTime,
|
||||
endTime time.Time) ([]*USDPrice, error) {
|
||||
endTime time.Time) ([]*Price, error) {
|
||||
|
||||
// When we query prices over a range, it is likely that the first data
|
||||
// point we get is after our starting point, since we have discrete
|
||||
|
|
@ -217,7 +217,7 @@ func (c *coinCapAPI) rawPriceData(ctx context.Context, startTime,
|
|||
// so that we do not have overlapping data across queries.
|
||||
startTime = startTime.Add(c.granularity.aggregation * -1)
|
||||
|
||||
var historicalRecords []*USDPrice
|
||||
var historicalRecords []*Price
|
||||
|
||||
// Create start and end vars to query one maximum length at a time.
|
||||
maxPeriod := c.granularity.maximumQuery
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ func TestCoinCapGetPrices(t *testing.T) {
|
|||
}
|
||||
|
||||
// Create a mocked convert function.
|
||||
convert := func([]byte) ([]*USDPrice, error) {
|
||||
convert := func([]byte) ([]*Price, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
|
|
@ -189,7 +189,7 @@ func TestParseCoinCapData(t *testing.T) {
|
|||
prices, err := parseCoinCapData(bytes)
|
||||
require.NoError(t, err)
|
||||
|
||||
expectedPrices := []*USDPrice{
|
||||
expectedPrices := []*Price{
|
||||
{
|
||||
Price: price1,
|
||||
Timestamp: time1,
|
||||
|
|
|
|||
|
|
@ -46,15 +46,15 @@ func queryCoinDesk(start, end time.Time) ([]byte, error) {
|
|||
return ioutil.ReadAll(response.Body)
|
||||
}
|
||||
|
||||
// parseCoinDeskData parses http response data from coindesk into USDPrice
|
||||
// parseCoinDeskData parses http response data from coindesk into Price
|
||||
// structs.
|
||||
func parseCoinDeskData(data []byte) ([]*USDPrice, error) {
|
||||
func parseCoinDeskData(data []byte) ([]*Price, error) {
|
||||
var priceEntries coinDeskResponse
|
||||
if err := json.Unmarshal(data, &priceEntries); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var usdRecords = make([]*USDPrice, 0, len(priceEntries.Data))
|
||||
var usdRecords = make([]*Price, 0, len(priceEntries.Data))
|
||||
|
||||
for date, price := range priceEntries.Data {
|
||||
timestamp, err := time.Parse(coinDeskTimeFormat, date)
|
||||
|
|
@ -62,7 +62,7 @@ func parseCoinDeskData(data []byte) ([]*USDPrice, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
usdRecords = append(usdRecords, &USDPrice{
|
||||
usdRecords = append(usdRecords, &Price{
|
||||
Timestamp: timestamp,
|
||||
Price: decimal.NewFromFloat(price),
|
||||
})
|
||||
|
|
@ -74,7 +74,7 @@ func parseCoinDeskData(data []byte) ([]*USDPrice, error) {
|
|||
// rawPriceData retrieves price information from coindesks's api for the given
|
||||
// time range.
|
||||
func (c *coinDeskAPI) rawPriceData(ctx context.Context, start,
|
||||
end time.Time) ([]*USDPrice, error) {
|
||||
end time.Time) ([]*Price, error) {
|
||||
|
||||
query := func() ([]byte, error) {
|
||||
return queryCoinDesk(start, end)
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ func TestParseCoinDeskData(t *testing.T) {
|
|||
prices, err := parseCoinDeskData(bytes)
|
||||
require.NoError(t, err)
|
||||
|
||||
expectedPrices := []*USDPrice{
|
||||
expectedPrices := []*Price{
|
||||
{
|
||||
Price: price,
|
||||
Timestamp: timestamp,
|
||||
|
|
|
|||
|
|
@ -23,12 +23,13 @@ var (
|
|||
errRetriesFailed = errors.New("could not get data within max retries")
|
||||
)
|
||||
|
||||
// USDPrice represents the Bitcoin price in USD at a certain time.
|
||||
type USDPrice struct {
|
||||
// Price represents the Bitcoin price in USD at a certain time.
|
||||
type Price struct {
|
||||
// Timestamp is the time at which the BTC price is quoted.
|
||||
Timestamp time.Time
|
||||
|
||||
// Price is the price in USD for 1 BTC at the given timestamp.
|
||||
// Price is the fiat price for the given currency for 1 BTC at the
|
||||
// given timestamp.
|
||||
Price decimal.Decimal
|
||||
}
|
||||
|
||||
|
|
@ -37,7 +38,7 @@ type USDPrice struct {
|
|||
// context passed in. It takes query and convert functions as parameters for
|
||||
// testing purposes.
|
||||
func retryQuery(ctx context.Context, queryAPI func() ([]byte, error),
|
||||
convert func([]byte) ([]*USDPrice, error)) ([]*USDPrice, error) {
|
||||
convert func([]byte) ([]*Price, error)) ([]*Price, error) {
|
||||
|
||||
for i := 0; i < maxRetries; i++ {
|
||||
// If our request fails, log the error, sleep for the retry
|
||||
|
|
|
|||
|
|
@ -101,7 +101,7 @@ func TestRetryQuery(t *testing.T) {
|
|||
}
|
||||
|
||||
// Create a mocked parse call which acts as a nop.
|
||||
parse := func([]byte) ([]*USDPrice, error) {
|
||||
parse := func([]byte) ([]*Price, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ var (
|
|||
// is used to fetch fiat price information.
|
||||
type fiatBackend interface {
|
||||
rawPriceData(ctx context.Context, startTime,
|
||||
endTime time.Time) ([]*USDPrice, error)
|
||||
endTime time.Time) ([]*Price, error)
|
||||
}
|
||||
|
||||
// PriceSource holds a fiatBackend that can be used to fetch fiat price
|
||||
|
|
@ -41,7 +41,7 @@ type PriceSource struct {
|
|||
// fiatBackend implementation. GetPrices also validates the time parameters and
|
||||
// sorts the results.
|
||||
func (p PriceSource) GetPrices(ctx context.Context, startTime,
|
||||
endTime time.Time) ([]*USDPrice, error) {
|
||||
endTime time.Time) ([]*Price, error) {
|
||||
|
||||
// First, check that we have a valid start and end time, and that the
|
||||
// range specified is not in the future.
|
||||
|
|
@ -134,7 +134,7 @@ type PriceRequest struct {
|
|||
// GetPrices gets a set of prices for a set of timestamps.
|
||||
func GetPrices(ctx context.Context, timestamps []time.Time,
|
||||
backend PriceBackend, granularity Granularity) (
|
||||
map[time.Time]*USDPrice, error) {
|
||||
map[time.Time]*Price, error) {
|
||||
|
||||
if len(timestamps) == 0 {
|
||||
return nil, nil
|
||||
|
|
@ -163,7 +163,7 @@ func GetPrices(ctx context.Context, timestamps []time.Time,
|
|||
}
|
||||
|
||||
// Prices will map transaction timestamps to their USD prices.
|
||||
var prices = make(map[time.Time]*USDPrice, len(timestamps))
|
||||
var prices = make(map[time.Time]*Price, len(timestamps))
|
||||
|
||||
for _, ts := range timestamps {
|
||||
price, err := GetPrice(priceData, ts)
|
||||
|
|
@ -195,12 +195,12 @@ func MsatToUSD(price decimal.Decimal, amt lnwire.MilliSatoshi) decimal.Decimal {
|
|||
// querying. The last datapoint's timestamp may be before the timestamp we are
|
||||
// querying. If a request lies between two price points, we just return the
|
||||
// earlier price.
|
||||
func GetPrice(prices []*USDPrice, timestamp time.Time) (*USDPrice, error) {
|
||||
func GetPrice(prices []*Price, timestamp time.Time) (*Price, error) {
|
||||
if len(prices) == 0 {
|
||||
return nil, errNoPrices
|
||||
}
|
||||
|
||||
var lastPrice *USDPrice
|
||||
var lastPrice *Price
|
||||
|
||||
// Run through our prices until we find a timestamp that our price
|
||||
// point lies before. Since we always return the previous price, this
|
||||
|
|
|
|||
|
|
@ -18,22 +18,22 @@ func TestGetPrice(t *testing.T) {
|
|||
price10K := decimal.New(10000, 1)
|
||||
price20K := decimal.New(20000, 1)
|
||||
|
||||
now10k := &USDPrice{
|
||||
now10k := &Price{
|
||||
Timestamp: now,
|
||||
Price: price10K,
|
||||
}
|
||||
|
||||
hourAgo20K := &USDPrice{
|
||||
hourAgo20K := &Price{
|
||||
Timestamp: oneHourAgo,
|
||||
Price: price20K,
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
prices []*USDPrice
|
||||
prices []*Price
|
||||
request time.Time
|
||||
expectedErr error
|
||||
expectedPrice *USDPrice
|
||||
expectedPrice *Price
|
||||
}{
|
||||
{
|
||||
name: "no prices",
|
||||
|
|
@ -43,21 +43,21 @@ func TestGetPrice(t *testing.T) {
|
|||
},
|
||||
{
|
||||
name: "timestamp before range",
|
||||
prices: []*USDPrice{now10k},
|
||||
prices: []*Price{now10k},
|
||||
request: oneHourAgo,
|
||||
expectedErr: errPriceOutOfRange,
|
||||
expectedPrice: nil,
|
||||
},
|
||||
{
|
||||
name: "timestamp equals data point timestamp",
|
||||
prices: []*USDPrice{hourAgo20K, now10k},
|
||||
prices: []*Price{hourAgo20K, now10k},
|
||||
request: now,
|
||||
expectedErr: nil,
|
||||
expectedPrice: now10k,
|
||||
},
|
||||
{
|
||||
name: "timestamp after range",
|
||||
prices: []*USDPrice{
|
||||
prices: []*Price{
|
||||
{
|
||||
Timestamp: twoHoursAgo,
|
||||
Price: price10K,
|
||||
|
|
@ -70,7 +70,7 @@ func TestGetPrice(t *testing.T) {
|
|||
},
|
||||
{
|
||||
name: "timestamp between prices, pick earlier",
|
||||
prices: []*USDPrice{hourAgo20K, now10k},
|
||||
prices: []*Price{hourAgo20K, now10k},
|
||||
request: now.Add(time.Minute * -30),
|
||||
expectedErr: nil,
|
||||
expectedPrice: hourAgo20K,
|
||||
|
|
|
|||
|
|
@ -115,7 +115,7 @@ func parseExchangeRateRequest(req *ExchangeRateRequest) ([]time.Time,
|
|||
return timestamps, fiatBackend, granularity, nil
|
||||
}
|
||||
|
||||
func exchangeRateResponse(prices map[time.Time]*fiat.USDPrice) *ExchangeRateResponse {
|
||||
func exchangeRateResponse(prices map[time.Time]*fiat.Price) *ExchangeRateResponse {
|
||||
fiatVals := make([]*ExchangeRate, 0, len(prices))
|
||||
|
||||
for ts, price := range prices {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue