fix key payment problems

This commit is contained in:
Jack 2016-07-26 17:20:51 -04:00
parent 491d431ea5
commit 0811ebb52d
3 changed files with 67 additions and 58 deletions

View file

@ -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']:

View file

@ -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)

View file

@ -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())