Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

multi: add Coindesk backends for fiat prices #116

Merged
merged 3 commits into from
May 19, 2021

Conversation

ellemouton
Copy link
Member

This PR addresses #37 by adding CoinDesk as a possible backend to use for price information. Users can use the fiat_backend flag in the audit and fiat RPCs to chose a backend. The default is still CoinCap.

For example:

$ frcli fiat --amt_msat=100000000000 --fiat_backend=coindesk

100000000000 msat = 55668.2283 USD, priced at 2021-04-19 02:00:00 +0200 SAST

(This PR kinda clashes with #115 but CoinDesk also has an endpoint for different currency rates so I can update this PR to include that if #115 ends up being accepted 👍 )

@ellemouton ellemouton force-pushed the coindeskBackends branch 3 times, most recently from 560959b to ec0338b Compare April 22, 2021 06:52
@carlaKC carlaKC self-requested a review April 23, 2021 07:17
Copy link
Contributor

@carlaKC carlaKC left a comment

Choose a reason for hiding this comment

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

Awesome job expanding a pretty convoluted part of the codebase! Just a few comments from me re how we abstract our fiat backend implementation.

Comment on lines 60 to 61
// nolint: prealloc
var usdRecords []*USDPrice
Copy link
Contributor

Choose a reason for hiding this comment

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

Why no prealloc?

fiat/prices.go Outdated
GetPrices(ctx context.Context, startTime, endTime time.Time) ([]*USDPrice, error)
}

type PriceBackend string
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: godocs for this enum and the coincap/coindesk values below.

I also have a slight preference for uint8 for categories like this, I think it's a bit more standard, but that's a loose opinion loosely held. If you just do ints, you can add a String method which returns the names as you have them here.


// GetPrices retrieves price information from coindesks's api for the given
// time range.
func (c *coinDeskAPI) GetPrices(ctx context.Context, start,
Copy link
Contributor

Choose a reason for hiding this comment

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

Time range validation and sort by timestamp is going to be common to all fiat backends, so could we cut the duplication out?

Thinking something like this:

type FiatSource struct{
    impl fiatBackend
}

func (f *FiatSource) GetPrices(){
   utils.ValidateTimeRange
   
   records, err := f.impl.rawPriceData()
    
   sort(records)
}

Where fiatBackend would be coincap/coindesk implementation that just fetches data. You'd need to rename the coincap GetPrices and move validation out, but then we can just return a FiatSource and we don't even need to export the interface.

frdrpc/exchange_rate.go Show resolved Hide resolved
frdrpc/faraday.proto Show resolved Hide resolved
cmd/frcli/utils.go Show resolved Hide resolved
fiat/prices.go Outdated
@@ -31,7 +31,7 @@ type PriceAPIBackend interface {
type PriceBackend string

const (
UnknownPriceBackend PriceBackend = ""
UnknownPriceBackend PriceBackend = ""
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: format in previous commit?

@ellemouton
Copy link
Member Author

Updated 👍

fiat/prices.go Outdated
Comment on lines 84 to 98
var priceBackendNames = map[PriceBackend]string{
UnknownPriceBackend: "",
CoinCapPriceBackend: "coincap",
CoinDeskPriceBackend: "coindesk",
}

func (p PriceBackend) ToString() string {
return priceBackendNames[p]
}

Copy link
Member Author

Choose a reason for hiding this comment

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

hmm so #117 adds another one of these maps. Could get messy if more things are added. How about something like this rather:

type backendsConfig struct {
	name string
	proxySupport bool
}

var priceBackendsConfig = map[PriceBackend]backendsConfig {
	UnknownPriceBackend: {},
	CoinCapPriceBackend: {
		name: "coincap",
		proxySupport: false,
	},
	CoinDeskPriceBackend: {
		name: "coindesk",
		proxySupport: true,
	},
}

Copy link
Contributor

@carlaKC carlaKC left a comment

Choose a reason for hiding this comment

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

Great commit structure! Makes such a difference in reveiw :)

This is shaping up really well, just some nits, and the imports GH action is failing (experimenting with a check to group imports nicely, there may be some bugs in it so lmk if it seems unreasonable).

fiat/prices.go Show resolved Hide resolved
fiat/prices.go Outdated
)

var priceBackendNames = map[PriceBackend]string{
UnknownPriceBackend: "",
Copy link
Contributor

Choose a reason for hiding this comment

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

Probably better to make this "Unknown", otherwise once day we'll forget that it's empty and know why we're logging some random empty string.

fiat/prices.go Outdated
CoinCapPriceBackend: "coincap",
}

func (p PriceBackend) ToString() string {
Copy link
Contributor

Choose a reason for hiding this comment

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

String so that it satisfies Stringer interface?

fiat/coindesk_api.go Show resolved Hide resolved
frdrpc/faraday.proto Show resolved Hide resolved
if err != nil {
return nil, err
}

prices, err := fiat.GetPrices(ctx, timestamps, *granularity)
prices, err := fiat.GetPrices(ctx, timestamps, fiatBackend, *granularity)
Copy link
Contributor

Choose a reason for hiding this comment

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

These look a bit long, are they wrapped at 80?

@ellemouton ellemouton force-pushed the coindeskBackends branch 3 times, most recently from 6d2d620 to 18a4d01 Compare May 6, 2021 07:42
@ellemouton
Copy link
Member Author

Thanks for the review @carlaKC 😊 updated 👍

@ellemouton ellemouton requested a review from carlaKC May 6, 2021 08:00
Copy link
Contributor

@carlaKC carlaKC left a comment

Choose a reason for hiding this comment

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

Great set of well structured change!

Just going to do some testing on my end and then will hit the green button.

fiat/prices.go Outdated Show resolved Hide resolved
fiat/prices.go Show resolved Hide resolved
)

var priceBackendNames = map[PriceBackend]string{
Copy link
Contributor

Choose a reason for hiding this comment

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

ok nice, following the logic for a map here given the context of the follow up PR 👌

This commit adds a fiatBackend interface that added fiat backend needs
to implement.
This commit adds a coindesk implementation of the fiatBackend interface.
This commit adds a fiat_backends option to the RPC relevant RPC
endpoints. Namely, the NodeAudit and ExchangeRate endpoint.
Copy link
Contributor

@carlaKC carlaKC left a comment

Choose a reason for hiding this comment

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

goods as advertised! fiat & audit endpoints flawless with both APIs, and coincap default is backwards compatible 💰

great improvement to code structure, really good work on this one!

@carlaKC carlaKC merged commit 7646023 into lightninglabs:master May 19, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants