Skip to content

Conversation

@ellemouton
Copy link
Member

@ellemouton ellemouton commented May 21, 2021

This PR allows a user to specify their own fiat price points in a CSV file in the following format:

Unix Timestamp [seconds] Price of 1 BTC in chosen currency
1621246440 10.1
1621249080 123.45
... ...

Then you can do the following:

$ frcli audit --enable_fiat --fiat_backend=custom --prices_csv_path=/path/to/pricedata.csv --custom_price_currency=ZAR --start_time=1621246480 --end_time=1621249110

and

$ frcli fiat --amt_msat=100000000000  --fiat_backend=custom --prices_csv_path=/path/to/pricedata.csv --custom_price_currency=ZAR

Fixes #113

@carlaKC carlaKC self-requested a review May 25, 2021 08:12
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.

Looking great!

Mostly comments re how we validate this new input, could use slightly stricter checks so it's very clear what we're requiring.
Sorry it took me so long! Also could move some of the renames into their own commits, but that is a hassle so non-blocking.

@ellemouton
Copy link
Member Author

Updated and split out some commits. I still gotta add the price point time stamp filtering on the frcli side. Will do that soon 👍

@ellemouton
Copy link
Member Author

cool, the last commit does the timestamp filtering in frcli

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.

A few last nits from me, looking spectacular.

I like having the frcli side filtering, saves us from shuffling a ton of unnecessary data back and forth.

The last thing that I think we need is to add some rpcserver side validation of the custom price data. The way that our price logic works is that we always need a timestamp that is before our start date to be able to get prices. This should live in the server, so that cli and rpc clients are validated. Since prices can be provided at varying granularity (eg, yearly, monthly, daily), it's difficult to know what other checks we should enforce on that data, but at least <= start date should be required.

// coinCapHistoryAPI is the endpoint we hit for historical price data.
coinCapHistoryAPI = "https://api.coincap.io/v2/assets/bitcoin/history"

// coinCapDefaultCurrency is the currency that the price data returned by the
Copy link
Contributor

Choose a reason for hiding this comment

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

is this wrapped at 80? Looks a leetle off to me.

}()

if len(report.Reports) > 0 {
CSVHeaders = strings.Replace(
Copy link
Contributor

Choose a reason for hiding this comment

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

Instead of strings.Replace we could have:

var CSVHeaders = "Timestamp,OnChain,Type,Category,Amount(Msat),Amount(%v),TxID,Reference,BTCPrice,BTCTimestamp,Note"

headers = fmt.Sprintf(CSVHeaders, report.Reports[0].BtcPrice.Currency)

Just a little shorter, and gives us options to add more variable fields going forward.

fiat/prices.go Outdated

// validatePriceSourceConfig checks that the PriceSourceConfig fields are valid
// given the chosen price backend.
func validatePriceSourceConfig(cfg *PriceSourceConfig) error {
Copy link
Contributor

Choose a reason for hiding this comment

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

could also be func (p *PriceSourceConfig) validate()error and then we only validate if non-nil.

@carlaKC
Copy link
Contributor

carlaKC commented Aug 27, 2021

Would be great if we can pick this up again!

Rename the USDPrice struct to Price so that it can be used to represent
more than 1 currency.
Rename usdPrice func type to fiatPrice so that the name is appropriate
for multiple fiat currencies.
Rename the MsatToUSD functino to MsatToFiat so that the name is
appropriate for multiple currencies.
Add Currency field to the price struct so that Price can be used to
represent any currency.
Update the RPC methods (exchange rate and node report) so that they show
the fiat currency that the bitcoin price is quoted in.
This commit adds a new implementation of the fiatBackend interface which
uses user provided prices data.
Add a PriceSourceConfig struct to consolidate the options required for
initialising a new PriceSource.
Add new CustomPriceBackend option to NewPriceSource function that
initialises the customPrices implementation of the fiatBackend
interface.
Rename the csv function to writeToCSV so that the csv package can be
imported in a future commit without needing to rename the import.
This commit adds the options required for the custom fiat price data to
the RPC methods. These methods include the NodeAudit and ExchangeRate
methods.
This commit filters the custom price points provided using the given
start and end timestamps. This is done so that only the necessary time
stamps are sent to the server.
This commit adds a server side check that ensures that at least one
price point is provided that has a timestamp preceding the start time.
@ellemouton
Copy link
Member Author

Updated @carlaKC :)

The last thing that I think we need is to add some rpcserver side validation of the custom price data.

Added this in the last commit

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 to wrap this up!

Just one Q left, probably because I've forgotten context here :')

// given the chosen price backend.
func (cfg *PriceSourceConfig) validatePriceSourceConfig() error {
switch cfg.Backend {
case UnknownPriceBackend, CoinCapPriceBackend:
Copy link
Contributor

Choose a reason for hiding this comment

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

Why do we require granularity set for UnknownPriceBackend? Wouldn't we only expect it for coincap?

@carlaKC carlaKC merged commit f953eea into lightninglabs:master Aug 30, 2021
@ellemouton ellemouton deleted the customPrices branch August 30, 2021 07:53
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.

Allow for custom price API

2 participants