forked from LBRYCommunity/lbry-sdk
fix key payment problems
This commit is contained in:
parent
491d431ea5
commit
0811ebb52d
3 changed files with 67 additions and 58 deletions
|
@ -2,11 +2,13 @@ import requests
|
|||
import json
|
||||
import time
|
||||
|
||||
from copy import deepcopy
|
||||
from googlefinance import getQuotes
|
||||
from lbrynet.conf import CURRENCIES
|
||||
import logging
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
log.setLevel(logging.INFO)
|
||||
|
||||
BITTREX_FEE = 0.0025
|
||||
|
||||
|
@ -26,23 +28,42 @@ FEE_REVISIONS = {'0.0.1': {'required': ['amount', 'address'], 'optional': []}}
|
|||
CURRENT_FEE_REVISION = '0.0.1'
|
||||
|
||||
|
||||
class LBRYFee(object):
|
||||
def __init__(self, fee_dict, rate_dict):
|
||||
fee = LBRYFeeFormat(fee_dict)
|
||||
|
||||
for currency in fee:
|
||||
self.address = fee[currency]['address']
|
||||
if not isinstance(fee[currency]['amount'], float):
|
||||
self.amount = float(fee[currency]['amount'])
|
||||
else:
|
||||
self.amount = fee[currency]['amount']
|
||||
class LBRYFeeFormat(dict):
|
||||
def __init__(self, fee_dict):
|
||||
dict.__init__(self)
|
||||
self.fee_version = None
|
||||
f = deepcopy(fee_dict)
|
||||
assert len(fee_dict) == 1
|
||||
for currency in fee_dict:
|
||||
assert currency in CURRENCIES, "Unsupported currency: %s" % str(currency)
|
||||
self.currency_symbol = currency
|
||||
self.update({currency: {}})
|
||||
for version in FEE_REVISIONS:
|
||||
for k in FEE_REVISIONS[version]['required']:
|
||||
assert k in fee_dict[currency], "Missing required fee field: %s" % k
|
||||
self[currency].update({k: f[currency].pop(k)})
|
||||
for k in FEE_REVISIONS[version]['optional']:
|
||||
if k in fee_dict[currency]:
|
||||
self[currency].update({k: f[currency].pop(k)})
|
||||
if not len(f):
|
||||
self.fee_version = version
|
||||
break
|
||||
assert f[currency] == {}, "Unknown fee keys: %s" % json.dumps(f.keys())
|
||||
|
||||
assert 'BTCLBC' in rate_dict and 'USDBTC' in rate_dict
|
||||
self.amount = self[self.currency_symbol]['amount'] if isinstance(self[self.currency_symbol]['amount'], float) else float(self[self.currency_symbol]['amount'])
|
||||
self.address = self[self.currency_symbol]['address']
|
||||
|
||||
|
||||
class LBRYFee(LBRYFeeFormat):
|
||||
def __init__(self, fee_dict, rate_dict):
|
||||
LBRYFeeFormat.__init__(self, fee_dict)
|
||||
rates = deepcopy(rate_dict)
|
||||
|
||||
assert 'BTCLBC' in rates and 'USDBTC' in rates
|
||||
for fx in rate_dict:
|
||||
assert int(time.time()) - int(rate_dict[fx]['ts']) < 3600, "%s quote is out of date" % fx
|
||||
self._USDBTC = {'spot': rate_dict['USDBTC']['spot'], 'ts': rate_dict['USDBTC']['ts']}
|
||||
self._BTCLBC = {'spot': rate_dict['BTCLBC']['spot'], 'ts': rate_dict['BTCLBC']['ts']}
|
||||
assert int(time.time()) - int(rates[fx]['ts']) < 3600, "%s quote is out of date" % fx
|
||||
self._USDBTC = {'spot': rates['USDBTC']['spot'], 'ts': rates['USDBTC']['ts']}
|
||||
self._BTCLBC = {'spot': rates['BTCLBC']['spot'], 'ts': rates['BTCLBC']['ts']}
|
||||
|
||||
def to_lbc(self):
|
||||
r = None
|
||||
|
@ -67,45 +88,31 @@ class LBRYFee(object):
|
|||
return r
|
||||
|
||||
def _usd_to_btc(self, usd):
|
||||
# log.error("usd to btc: " + str(usd))
|
||||
# log.error("%f * %f = %f" % (self._USDBTC['spot'], float(usd), self._USDBTC['spot'] * float(usd)))
|
||||
return self._USDBTC['spot'] * float(usd)
|
||||
|
||||
def _btc_to_usd(self, btc):
|
||||
# log.error("btc to usd: " + str(btc))
|
||||
# log.error("%f / %f = %f" % (float(btc), self._USDBTC['spot'], float(btc) / self._USDBTC['spot']))
|
||||
return float(btc) / self._USDBTC['spot']
|
||||
|
||||
def _btc_to_lbc(self, btc):
|
||||
# log.error("btc to lbc: " + str(btc))
|
||||
# log.error("%f * %f = %f" % (float(btc), self._BTCLBC['spot'], float(btc) * self._BTCLBC['spot'] / (1.0 - BITTREX_FEE)))
|
||||
return float(btc) * self._BTCLBC['spot'] / (1.0 - BITTREX_FEE)
|
||||
|
||||
def _lbc_to_btc(self, lbc):
|
||||
# log.error("lbc to btc: " + str(lbc))
|
||||
# log.error("%f / %f = %f" % (self._BTCLBC['spot'], float(lbc), self._BTCLBC['spot'] / float(lbc)))
|
||||
return self._BTCLBC['spot'] / float(lbc)
|
||||
|
||||
|
||||
class LBRYFeeFormat(dict):
|
||||
def __init__(self, fee_dict):
|
||||
dict.__init__(self)
|
||||
self.fee_version = None
|
||||
f = fee_dict.copy()
|
||||
assert len(fee_dict) == 1
|
||||
for currency in fee_dict:
|
||||
assert currency in CURRENCIES, "Unsupported currency: %s" % str(currency)
|
||||
self.update({currency: {}})
|
||||
for version in FEE_REVISIONS:
|
||||
for k in FEE_REVISIONS[version]['required']:
|
||||
assert k in fee_dict[currency], "Missing required fee field: %s" % k
|
||||
self[currency].update({k: f[currency].pop(k)})
|
||||
for k in FEE_REVISIONS[version]['optional']:
|
||||
if k in fee_dict[currency]:
|
||||
self[currency].update({k: f[currency].pop(k)})
|
||||
if not len(f):
|
||||
self.fee_version = version
|
||||
break
|
||||
assert f[currency] == {}, "Unknown fee keys: %s" % json.dumps(f.keys())
|
||||
|
||||
|
||||
class Metadata(dict):
|
||||
def __init__(self, metadata):
|
||||
dict.__init__(self)
|
||||
self.metaversion = None
|
||||
m = metadata.copy()
|
||||
m = deepcopy(metadata)
|
||||
|
||||
assert "sources" in metadata, "No sources given"
|
||||
for source in metadata['sources']:
|
||||
|
|
|
@ -1899,20 +1899,19 @@ class LBRYDaemon(jsonrpc.JSONRPC):
|
|||
file_path = p['file_path']
|
||||
metadata = p['metadata']
|
||||
|
||||
def _set_address(address):
|
||||
metadata['fee']['address'] = address
|
||||
d = defer.succeed(None)
|
||||
|
||||
def _set_address(address, currency):
|
||||
metadata['fee'][currency]['address'] = address
|
||||
return defer.succeed(None)
|
||||
|
||||
if 'fee' in p:
|
||||
metadata['fee'] = p['fee']
|
||||
if 'address' not in metadata['fee']:
|
||||
assert len(metadata['fee']) == 1, "Too many fees"
|
||||
for c in metadata['fee']:
|
||||
if 'address' not in metadata['fee'][c]:
|
||||
d = self.session.wallet.get_new_address()
|
||||
d.addCallback(_set_address)
|
||||
else:
|
||||
d = defer.succeed(None)
|
||||
else:
|
||||
d = defer.succeed(None)
|
||||
|
||||
d.addCallback(lambda addr: _set_address(addr, c))
|
||||
|
||||
pub = Publisher(self.session, self.lbry_file_manager, self.session.wallet)
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ import logging
|
|||
import os
|
||||
import sys
|
||||
|
||||
from copy import deepcopy
|
||||
from appdirs import user_data_dir
|
||||
from datetime import datetime
|
||||
from twisted.internet import defer
|
||||
|
@ -58,7 +59,7 @@ class GetStream(object):
|
|||
self.sd_identifier = sd_identifier
|
||||
self.stream_hash = None
|
||||
self.max_key_fee = max_key_fee
|
||||
self.metadata = None
|
||||
self.stream_info = None
|
||||
self.stream_info_manager = None
|
||||
self.d = defer.Deferred(None)
|
||||
self.timeout = timeout
|
||||
|
@ -86,20 +87,23 @@ class GetStream(object):
|
|||
|
||||
def start(self, stream_info, name):
|
||||
self.resolved_name = name
|
||||
self.metadata = stream_info
|
||||
self.stream_hash = self.metadata['sources']['lbry_sd_hash']
|
||||
self.stream_info = deepcopy(stream_info)
|
||||
self.description = self.stream_info['description']
|
||||
self.stream_hash = self.stream_info['sources']['lbry_sd_hash']
|
||||
|
||||
if 'fee' in self.metadata:
|
||||
self.fee = LBRYFee(self.metadata['fee'], {'USDBTC': self.wallet._USDBTC, 'BTCLBC': self.wallet._BTCLBC})
|
||||
if 'fee' in self.stream_info:
|
||||
self.fee = LBRYFee(self.stream_info['fee'], {'USDBTC': self.wallet._USDBTC, 'BTCLBC': self.wallet._BTCLBC})
|
||||
if isinstance(self.max_key_fee, float):
|
||||
if self.fee.to_lbc() > self.max_key_fee:
|
||||
log.info("Key fee %f above limit of %f didn't download lbry://%s" % (self.fee.to_lbc(), self.max_key_fee, self.resolved_name))
|
||||
return defer.fail(KeyFeeAboveMaxAllowed())
|
||||
log.info("Key fee %f below limit of %f, downloading lbry://%s" % (self.fee.to_lbc(), self.max_key_fee, self.resolved_name))
|
||||
elif isinstance(self.max_key_fee, dict):
|
||||
max_key = LBRYFee(self.max_key_fee, {'USDBTC': self.wallet._USDBTC, 'BTCLBC': self.wallet._BTCLBC})
|
||||
max_key = LBRYFee(deepcopy(self.max_key_fee), {'USDBTC': self.wallet._USDBTC, 'BTCLBC': self.wallet._BTCLBC})
|
||||
if self.fee.to_lbc() > max_key.to_lbc():
|
||||
log.info("Key fee %f above limit of %f didn't download lbry://%s" % (self.fee.to_lbc(), max_key.to_lbc(), self.resolved_name))
|
||||
return defer.fail(KeyFeeAboveMaxAllowed())
|
||||
log.info("Key fee %f below limit of %f, downloading lbry://%s" % (self.fee.to_lbc(), max_key.to_lbc(), self.resolved_name))
|
||||
|
||||
def _cause_timeout():
|
||||
self.timeout_counter = self.timeout * 2
|
||||
|
@ -130,20 +134,19 @@ class GetStream(object):
|
|||
def _start_download(self, downloader):
|
||||
def _pay_key_fee():
|
||||
if self.fee is not None:
|
||||
fee_lbc = self.fee.to_lbc()
|
||||
fee_lbc = float(self.fee.to_lbc())
|
||||
reserved_points = self.wallet.reserve_points(self.fee.address, fee_lbc)
|
||||
if reserved_points is None:
|
||||
return defer.fail(InsufficientFundsError())
|
||||
log.info("Key fee: %f --> %s" % (fee_lbc, self.fee.address))
|
||||
d = self.wallet.send_points_to_address(reserved_points, self.fee.address)
|
||||
return d
|
||||
return self.wallet.send_points_to_address(reserved_points, fee_lbc)
|
||||
|
||||
return defer.succeed(None)
|
||||
|
||||
d = _pay_key_fee()
|
||||
|
||||
self.downloader = downloader
|
||||
self.download_path = os.path.join(downloader.download_directory, downloader.file_name)
|
||||
|
||||
d = _pay_key_fee()
|
||||
d.addCallback(lambda _: log.info("Downloading %s --> %s", self.stream_hash, self.downloader.file_name))
|
||||
d.addCallback(lambda _: self.downloader.start())
|
||||
|
||||
|
|
Loading…
Reference in a new issue