Skip to content

Commit

Permalink
Merge branch 'master' into fix_account_tx
Browse files Browse the repository at this point in the history
  • Loading branch information
JustinBeBoy committed Jul 15, 2024
2 parents 1ddb02d + 2d6e3a9 commit ee5a994
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 56 deletions.
3 changes: 3 additions & 0 deletions libwallet/assets_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,9 @@ func (mgr *AssetsManager) SetDarkMode(data bool) {

// GetCurrencyConversionExchange returns the currency conversion exchange.
func (mgr *AssetsManager) GetCurrencyConversionExchange() string {
if mgr.RateSource != nil {
return mgr.RateSource.Name()
}
var key string
mgr.ReadAppConfigValue(sharedW.CurrencyConversionConfigKey, &key)
if key == "" {
Expand Down
91 changes: 37 additions & 54 deletions libwallet/ext/rate_source.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import (

const (
// These are constants used to represent various rate sources supported.
bittrex = values.BittrexExchange
binance = values.BinanceExchange
binanceUS = values.BinanceUSExchange
coinpaprika = values.Coinpaprika
Expand All @@ -31,12 +30,6 @@ const (
)

var (
// These are urls to fetch rate information from the Bittrex exchange.
bittrexURLs = sourceURLs{
price: "https://api.bittrex.com/v3/markets/%s/ticker",
stats: "https://api.bittrex.com/v3/markets/%s/summary",
}

// According to the docs (See:
// https://www.binance.com/en/support/faq/frequently-asked-questions-on-api-360004492232),
// there's a 6,000 request weight per minute (keep in mind that this is not
Expand Down Expand Up @@ -129,6 +122,8 @@ type RateListener struct {
OnRateUpdated func()
}

type tickerFunc func(market values.Market) (*Ticker, error)

// CommonRateSource is an external rate source for fiat and crypto-currency
// rates. These rates are estimates and maybe be affected by server latency and
// should not be used for actual buy or sell orders except to display reasonable
Expand All @@ -141,7 +136,7 @@ type CommonRateSource struct {
tickers map[values.Market]*Ticker
refreshing bool
cond *sync.Cond
getTicker func(market values.Market) (*Ticker, error)
getTicker tickerFunc
sourceChanged chan *struct{}
lastUpdate time.Time

Expand Down Expand Up @@ -169,8 +164,7 @@ func NewCommonRateSource(ctx context.Context, source string, disableConversionEx

// Name is the string associated with the rate source for display.
func (cs *CommonRateSource) Name() string {
src := cs.source
return strings.ToUpper(src[:1]) + src[1:]
return cs.source
}

func (cs *CommonRateSource) Ready() bool {
Expand Down Expand Up @@ -358,21 +352,36 @@ func (cs *CommonRateSource) fetchRate(market values.Market) *Ticker {
func (cs *CommonRateSource) retryGetTicker(market values.Market) (*Ticker, error) {
var newTicker *Ticker
var err error
backoff := 1 * time.Second
for i := 0; i < 3; i++ {
select {
case <-cs.ctx.Done():
log.Errorf("fetching ticker canceled: %v", cs.ctx.Err())
return nil, cs.ctx.Err()
default:
log.Infof("fetching %s rate from %v", market, cs.source)
newTicker, err = cs.getTicker(market)
if err == nil {
return newTicker, nil
}
}
// fetch ticker from available exchanges
log.Infof("fetching from other exchanges")
for _, source := range sources {
if source == cs.source {
continue
}
getTickerFn := cs.sourceGetTickerFunc(source)
select {
case <-cs.ctx.Done():
log.Errorf("fetching ticker canceled: %v", cs.ctx.Err())
return nil, cs.ctx.Err()
default:
newTicker, err = cs.getTicker(market)
log.Infof("fetching %s rate from %v", market, source)
newTicker, err = getTickerFn(market)
if err == nil {
log.Infof("%s is chosen", source)
cs.source = source
return newTicker, nil
}

log.Errorf("fetching ticker %d failed: %v. Retrying in %v\n", i+1, err, backoff)
time.Sleep(backoff)
backoff *= 2 // Exponential backoff
}
}
if cs.disableConversionExchange != nil {
Expand All @@ -386,15 +395,14 @@ func (cs *CommonRateSource) binanceGetTicker(market values.Market) (*Ticker, err
HTTPURL: fmt.Sprintf(binanceURLs.price, market.MarketWithoutSep()),
Method: "GET",
}

if cs.source == binanceUS {
reqCfg.HTTPURL = fmt.Sprintf(binanceUSURLs.price, market.MarketWithoutSep())
}

resp := new(BinanceTickerResponse)
_, err := utils.HTTPRequest(reqCfg, &resp)
if err != nil {
return nil, fmt.Errorf("%s failed to fetch ticker for %s: %w", binance, market, err)
return nil, fmt.Errorf("%s failed to fetch ticker for %s: %w", cs.source, market, err)
}

percentChange := resp.PriceChangePercent
Expand All @@ -408,38 +416,6 @@ func (cs *CommonRateSource) binanceGetTicker(market values.Market) (*Ticker, err
return ticker, nil
}

func bittrexGetTicker(market values.Market) (*Ticker, error) {
reqCfg := &utils.ReqConfig{
HTTPURL: fmt.Sprintf(bittrexURLs.price, market.String()),
Method: "GET",
}

// Fetch current rate.
resp := new(BittrexTickerResponse)
_, err := utils.HTTPRequest(reqCfg, &resp)
if err != nil {
return nil, fmt.Errorf("%s failed to fetch ticker for %s: %w", bittrex, market, err)
}

ticker := &Ticker{
Market: resp.Symbol, // Ok: e.g BTC-USDT
LastTradePrice: resp.LastTradeRate,
}

// Fetch percentage change.
reqCfg.HTTPURL = fmt.Sprintf(bittrexURLs.stats, market)
res := new(BittrexMarketSummaryResponse)
_, err = utils.HTTPRequest(reqCfg, &res)
if err != nil {
return nil, fmt.Errorf("%s failed to fetch ticker for %s: %w", bittrex, market, err)
}

percentChange := res.PercentChange
ticker.PriceChangePercent = &percentChange
ticker.lastUpdate = time.Now()
return ticker, nil
}

// coinpaprikaGetTicker don't need market param, but need it to satisfy the format of the getrate function
func (cs *CommonRateSource) coinpaprikaGetTicker(market values.Market) (*Ticker, error) {
reqCfg := &utils.ReqConfig{
Expand Down Expand Up @@ -596,7 +572,7 @@ func isSupportedMarket(market values.Market, rateSource string) (values.Market,

func isValidSource(source string) bool {
switch source {
case bittrex, binance, binanceUS, coinpaprika, messari, kucoinExchange, none:
case binance, binanceUS, coinpaprika, messari, kucoinExchange, none:
return true
default:
return false
Expand All @@ -607,8 +583,6 @@ func (cs *CommonRateSource) sourceGetTickerFunc(source string) func(values.Marke
switch source {
case binance, binanceUS:
return cs.binanceGetTicker
case bittrex:
return bittrexGetTicker
case messari:
return messariGetTicker
case kucoinExchange:
Expand All @@ -622,6 +596,15 @@ func (cs *CommonRateSource) sourceGetTickerFunc(source string) func(values.Marke
}
}

var sources = []string{
binance,
binanceUS,
messari,
kucoinExchange,
coinpaprika,
none,
}

func dummyGetTickerFunc(values.Market) (*Ticker, error) {
return &Ticker{}, nil
}
1 change: 0 additions & 1 deletion ui/preference/list_preference.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ var (
ExchOptions = []ItemPreference{
{Key: values.BinanceExchange, Value: values.StrUsdBinance, Warning: values.String(values.StrRateBinanceWarning), WarningLink: binanceProhibitedCountries},
{Key: values.BinanceUSExchange, Value: values.StrUsdBinanceUS},
{Key: values.BittrexExchange, Value: values.StrUsdBittrex, Warning: values.String(values.StrRateBittrexWarning), WarningLink: bittrexProhibitedCountries},
{Key: values.Coinpaprika, Value: values.StrUsdCoinpaprika},
{Key: values.Messari, Value: values.StrUsdMessari},
{Key: values.KucoinExchange, Value: values.StrUsdKucoin, Warning: values.String(values.StrRateKucoinWarning), WarningLink: kucoinProhibitedCountries},
Expand Down
1 change: 0 additions & 1 deletion ui/values/arrays.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import "github.com/crypto-power/cryptopower/libwallet/utils"
// These are a list of supported rate sources.
const (
DefaultExchangeValue = "none"
BittrexExchange = "bittrex"
BinanceExchange = "binance"
BinanceUSExchange = "binanceus"
Coinpaprika = "coinpaprika"
Expand Down

0 comments on commit ee5a994

Please sign in to comment.