2019-12-15 07:02:18 +01:00
|
|
|
import asyncio
|
2019-03-20 06:46:23 +01:00
|
|
|
from decimal import Decimal
|
2019-12-15 07:02:18 +01:00
|
|
|
from time import time
|
2019-06-21 03:02:58 +02:00
|
|
|
from lbry.schema.claim import Claim
|
2019-12-15 07:02:18 +01:00
|
|
|
from lbry.extras.daemon.exchange_rate_manager import (
|
|
|
|
ExchangeRate, ExchangeRateManager, CurrencyConversionError,
|
|
|
|
LBRYFeed, LBRYBTCFeed,
|
|
|
|
CryptonatorFeed, CryptonatorBTCFeed,
|
|
|
|
BittrexFeed,
|
|
|
|
)
|
2019-12-31 21:30:13 +01:00
|
|
|
from lbry.testcase import AsyncioTestCase, FakeExchangeRateManager, get_fake_exchange_rate_manager
|
2019-11-20 02:34:39 +01:00
|
|
|
from lbry.error import InvalidExchangeRateResponseError
|
2019-01-22 23:54:25 +01:00
|
|
|
|
|
|
|
|
2019-12-15 07:02:18 +01:00
|
|
|
class ExchangeRateTests(AsyncioTestCase):
|
2017-05-31 20:15:15 +02:00
|
|
|
|
|
|
|
def test_invalid_rates(self):
|
2017-10-17 04:11:20 +02:00
|
|
|
with self.assertRaises(ValueError):
|
2019-12-15 07:02:18 +01:00
|
|
|
ExchangeRate('USDBTC', 0, time())
|
2017-10-17 04:11:20 +02:00
|
|
|
with self.assertRaises(ValueError):
|
2019-12-15 07:02:18 +01:00
|
|
|
ExchangeRate('USDBTC', -1, time())
|
2017-02-28 02:18:57 +01:00
|
|
|
|
|
|
|
def test_fee_converts_to_lbc(self):
|
2019-03-20 06:46:23 +01:00
|
|
|
fee = Claim().stream.fee
|
|
|
|
fee.usd = Decimal(10.0)
|
|
|
|
fee.address = "bRcHraa8bYJZL7vkh5sNmGwPDERFUjGPP9"
|
2019-12-15 07:37:55 +01:00
|
|
|
manager = get_fake_exchange_rate_manager()
|
2017-05-30 23:07:23 +02:00
|
|
|
result = manager.convert_currency(fee.currency, "LBC", fee.amount)
|
2017-02-28 02:18:57 +01:00
|
|
|
self.assertEqual(60.0, result)
|
|
|
|
|
2017-05-31 20:15:15 +02:00
|
|
|
def test_missing_feed(self):
|
2019-03-20 06:46:23 +01:00
|
|
|
fee = Claim().stream.fee
|
|
|
|
fee.usd = Decimal(1.0)
|
|
|
|
fee.address = "bRcHraa8bYJZL7vkh5sNmGwPDERFUjGPP9"
|
2019-12-15 07:37:55 +01:00
|
|
|
manager = FakeExchangeRateManager([LBRYFeed()], {'BTCLBC': 1.0})
|
2019-12-15 07:02:18 +01:00
|
|
|
with self.assertRaises(CurrencyConversionError):
|
2017-09-07 20:01:06 +02:00
|
|
|
manager.convert_currency(fee.currency, "LBC", fee.amount)
|
2017-05-31 20:15:15 +02:00
|
|
|
|
2019-12-15 07:02:18 +01:00
|
|
|
def test_lbry_feed_response(self):
|
|
|
|
feed = LBRYFeed()
|
|
|
|
out = feed.get_rate_from_response({
|
2019-10-14 11:17:18 +02:00
|
|
|
'data': {
|
2019-12-15 07:02:18 +01:00
|
|
|
'fresh': 0, 'lbc_usd': 0.05863062523378918,
|
|
|
|
'lbc_btc': 5.065289549855739e-05, 'btc_usd': 1157.498
|
2019-10-14 11:17:18 +02:00
|
|
|
},
|
|
|
|
'success': True,
|
|
|
|
'error': None
|
2019-12-15 07:02:18 +01:00
|
|
|
})
|
|
|
|
self.assertEqual(1.0 / 5.065289549855739e-05, out)
|
2019-11-20 02:34:39 +01:00
|
|
|
with self.assertRaises(InvalidExchangeRateResponseError):
|
2019-12-15 07:02:18 +01:00
|
|
|
feed.get_rate_from_response({})
|
2019-11-20 02:34:39 +01:00
|
|
|
with self.assertRaises(InvalidExchangeRateResponseError):
|
2019-12-15 07:02:18 +01:00
|
|
|
feed.get_rate_from_response({
|
|
|
|
"success": True,
|
|
|
|
"result": []
|
|
|
|
})
|
|
|
|
|
|
|
|
def test_lbry_btc_feed_response(self):
|
|
|
|
feed = LBRYBTCFeed()
|
|
|
|
out = feed.get_rate_from_response({
|
2019-10-14 11:17:18 +02:00
|
|
|
'data': {
|
2019-12-15 07:02:18 +01:00
|
|
|
'fresh': 0, 'lbc_usd': 0.05863062523378918,
|
|
|
|
'lbc_btc': 5.065289549855739e-05, 'btc_usd': 1157.498
|
2019-10-14 11:17:18 +02:00
|
|
|
},
|
|
|
|
'success': True,
|
|
|
|
'error': None
|
2019-12-15 07:02:18 +01:00
|
|
|
})
|
|
|
|
self.assertEqual(1.0 / 1157.498, out)
|
2019-11-20 02:34:39 +01:00
|
|
|
with self.assertRaises(InvalidExchangeRateResponseError):
|
2019-12-15 07:02:18 +01:00
|
|
|
feed.get_rate_from_response({})
|
2019-11-20 02:34:39 +01:00
|
|
|
with self.assertRaises(InvalidExchangeRateResponseError):
|
2019-12-15 07:02:18 +01:00
|
|
|
feed.get_rate_from_response({
|
|
|
|
"success": True,
|
|
|
|
"result": {}
|
|
|
|
})
|
|
|
|
|
|
|
|
def test_cryptonator_lbc_feed_response(self):
|
|
|
|
feed = CryptonatorFeed()
|
|
|
|
out = feed.get_rate_from_response({
|
2019-10-14 11:17:18 +02:00
|
|
|
'ticker': {
|
2019-12-15 07:02:18 +01:00
|
|
|
'base': 'BTC', 'target': 'LBC', 'price': 23657.44026496,
|
|
|
|
'volume': '', 'change': -5.59806916,
|
2019-10-14 11:17:18 +02:00
|
|
|
},
|
|
|
|
'timestamp': 1507470422,
|
|
|
|
'success': True,
|
|
|
|
'error': ""
|
2019-12-15 07:02:18 +01:00
|
|
|
})
|
|
|
|
self.assertEqual(23_657.44026496, out)
|
2019-11-20 02:34:39 +01:00
|
|
|
with self.assertRaises(InvalidExchangeRateResponseError):
|
2019-12-15 07:02:18 +01:00
|
|
|
feed.get_rate_from_response({})
|
2019-11-20 02:34:39 +01:00
|
|
|
with self.assertRaises(InvalidExchangeRateResponseError):
|
2019-12-15 07:02:18 +01:00
|
|
|
feed.get_rate_from_response({
|
|
|
|
"success": True,
|
|
|
|
"ticker": {}
|
|
|
|
})
|
|
|
|
|
|
|
|
def test_cryptonator_btc_feed_response(self):
|
|
|
|
feed = CryptonatorBTCFeed()
|
|
|
|
out = feed.get_rate_from_response({
|
2019-10-14 11:17:18 +02:00
|
|
|
'ticker': {
|
2019-12-15 07:02:18 +01:00
|
|
|
'base': 'BTC', 'target': 'LBC', 'price': 0.00022123,
|
|
|
|
'volume': '', 'change': -0.00000259,
|
2019-10-14 11:17:18 +02:00
|
|
|
},
|
|
|
|
'timestamp': 1507471141,
|
|
|
|
'success': True,
|
|
|
|
'error': ''
|
2019-12-15 07:02:18 +01:00
|
|
|
})
|
|
|
|
self.assertEqual(0.00022123, out)
|
2019-11-20 02:34:39 +01:00
|
|
|
with self.assertRaises(InvalidExchangeRateResponseError):
|
2019-12-15 07:02:18 +01:00
|
|
|
feed.get_rate_from_response({})
|
2019-11-20 02:34:39 +01:00
|
|
|
with self.assertRaises(InvalidExchangeRateResponseError):
|
2019-12-15 07:02:18 +01:00
|
|
|
feed.get_rate_from_response({
|
|
|
|
"success": True,
|
|
|
|
"ticker": {}
|
|
|
|
})
|
|
|
|
|
|
|
|
def test_bittrex_feed_response(self):
|
|
|
|
feed = BittrexFeed()
|
|
|
|
out = feed.get_rate_from_response({
|
2019-10-14 11:17:18 +02:00
|
|
|
"success": True,
|
|
|
|
"message": "",
|
|
|
|
"result": [
|
|
|
|
{
|
|
|
|
'Id': 6902471, 'TimeStamp': '2017-02-27T23:41:52.213', 'Quantity': 56.12611239,
|
|
|
|
"Price": 0.00001621, "Total": 0.00090980, "FillType": "PARTIAL_FILL", "OrderType": "SELL"
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"Id": 6902403, "TimeStamp": "2017-02-27t23:31:40.463", "Quantity": 430.99988180,
|
|
|
|
"Price": 0.00001592, "Total": 0.00686151, "FillType": "PARTIAL_FILL", "OrderType": "SELL"
|
|
|
|
}
|
|
|
|
]
|
2019-12-15 07:02:18 +01:00
|
|
|
})
|
|
|
|
self.assertEqual(1.0 / ((0.00090980+0.00686151) / (56.12611239+430.99988180)), out)
|
2019-11-20 02:34:39 +01:00
|
|
|
with self.assertRaises(InvalidExchangeRateResponseError):
|
2019-12-15 07:02:18 +01:00
|
|
|
feed.get_rate_from_response({})
|
2019-11-20 02:34:39 +01:00
|
|
|
with self.assertRaises(InvalidExchangeRateResponseError):
|
2019-12-15 07:02:18 +01:00
|
|
|
feed.get_rate_from_response({
|
|
|
|
"success": True,
|
|
|
|
"result": []
|
|
|
|
})
|
2019-10-14 11:17:18 +02:00
|
|
|
|
|
|
|
|
2019-12-15 07:02:18 +01:00
|
|
|
class BadMarketFeed(LBRYFeed):
|
2019-10-14 11:17:18 +02:00
|
|
|
|
2019-12-15 07:02:18 +01:00
|
|
|
def get_response(self):
|
|
|
|
raise InvalidExchangeRateResponseError(self.name, 'bad stuff')
|
2019-10-14 11:17:18 +02:00
|
|
|
|
|
|
|
|
2019-12-15 07:02:18 +01:00
|
|
|
class ExchangeRateManagerTests(AsyncioTestCase):
|
2019-10-14 11:17:18 +02:00
|
|
|
|
2019-12-15 07:02:18 +01:00
|
|
|
async def test_get_rate_failure_retrieved(self):
|
|
|
|
manager = ExchangeRateManager([BadMarketFeed])
|
|
|
|
manager.start()
|
|
|
|
await asyncio.sleep(1)
|
|
|
|
self.addCleanup(manager.stop)
|