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 json
|
||||||
import time
|
import time
|
||||||
|
|
||||||
|
from copy import deepcopy
|
||||||
from googlefinance import getQuotes
|
from googlefinance import getQuotes
|
||||||
from lbrynet.conf import CURRENCIES
|
from lbrynet.conf import CURRENCIES
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
log.setLevel(logging.INFO)
|
||||||
|
|
||||||
BITTREX_FEE = 0.0025
|
BITTREX_FEE = 0.0025
|
||||||
|
|
||||||
|
@ -26,23 +28,42 @@ FEE_REVISIONS = {'0.0.1': {'required': ['amount', 'address'], 'optional': []}}
|
||||||
CURRENT_FEE_REVISION = '0.0.1'
|
CURRENT_FEE_REVISION = '0.0.1'
|
||||||
|
|
||||||
|
|
||||||
class LBRYFee(object):
|
class LBRYFeeFormat(dict):
|
||||||
def __init__(self, fee_dict, rate_dict):
|
def __init__(self, fee_dict):
|
||||||
fee = LBRYFeeFormat(fee_dict)
|
dict.__init__(self)
|
||||||
|
self.fee_version = None
|
||||||
for currency in fee:
|
f = deepcopy(fee_dict)
|
||||||
self.address = fee[currency]['address']
|
assert len(fee_dict) == 1
|
||||||
if not isinstance(fee[currency]['amount'], float):
|
for currency in fee_dict:
|
||||||
self.amount = float(fee[currency]['amount'])
|
assert currency in CURRENCIES, "Unsupported currency: %s" % str(currency)
|
||||||
else:
|
|
||||||
self.amount = fee[currency]['amount']
|
|
||||||
self.currency_symbol = 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:
|
for fx in rate_dict:
|
||||||
assert int(time.time()) - int(rate_dict[fx]['ts']) < 3600, "%s quote is out of date" % fx
|
assert int(time.time()) - int(rates[fx]['ts']) < 3600, "%s quote is out of date" % fx
|
||||||
self._USDBTC = {'spot': rate_dict['USDBTC']['spot'], 'ts': rate_dict['USDBTC']['ts']}
|
self._USDBTC = {'spot': rates['USDBTC']['spot'], 'ts': rates['USDBTC']['ts']}
|
||||||
self._BTCLBC = {'spot': rate_dict['BTCLBC']['spot'], 'ts': rate_dict['BTCLBC']['ts']}
|
self._BTCLBC = {'spot': rates['BTCLBC']['spot'], 'ts': rates['BTCLBC']['ts']}
|
||||||
|
|
||||||
def to_lbc(self):
|
def to_lbc(self):
|
||||||
r = None
|
r = None
|
||||||
|
@ -67,45 +88,31 @@ class LBRYFee(object):
|
||||||
return r
|
return r
|
||||||
|
|
||||||
def _usd_to_btc(self, usd):
|
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)
|
return self._USDBTC['spot'] * float(usd)
|
||||||
|
|
||||||
def _btc_to_usd(self, btc):
|
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']
|
return float(btc) / self._USDBTC['spot']
|
||||||
|
|
||||||
def _btc_to_lbc(self, btc):
|
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)
|
return float(btc) * self._BTCLBC['spot'] / (1.0 - BITTREX_FEE)
|
||||||
|
|
||||||
def _lbc_to_btc(self, lbc):
|
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)
|
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):
|
class Metadata(dict):
|
||||||
def __init__(self, metadata):
|
def __init__(self, metadata):
|
||||||
dict.__init__(self)
|
dict.__init__(self)
|
||||||
self.metaversion = None
|
self.metaversion = None
|
||||||
m = metadata.copy()
|
m = deepcopy(metadata)
|
||||||
|
|
||||||
assert "sources" in metadata, "No sources given"
|
assert "sources" in metadata, "No sources given"
|
||||||
for source in metadata['sources']:
|
for source in metadata['sources']:
|
||||||
|
|
|
@ -1899,20 +1899,19 @@ class LBRYDaemon(jsonrpc.JSONRPC):
|
||||||
file_path = p['file_path']
|
file_path = p['file_path']
|
||||||
metadata = p['metadata']
|
metadata = p['metadata']
|
||||||
|
|
||||||
def _set_address(address):
|
d = defer.succeed(None)
|
||||||
metadata['fee']['address'] = address
|
|
||||||
|
def _set_address(address, currency):
|
||||||
|
metadata['fee'][currency]['address'] = address
|
||||||
return defer.succeed(None)
|
return defer.succeed(None)
|
||||||
|
|
||||||
if 'fee' in p:
|
if 'fee' in p:
|
||||||
metadata['fee'] = p['fee']
|
metadata['fee'] = p['fee']
|
||||||
if 'address' not in metadata['fee']:
|
assert len(metadata['fee']) == 1, "Too many fees"
|
||||||
d = self.session.wallet.get_new_address()
|
for c in metadata['fee']:
|
||||||
d.addCallback(_set_address)
|
if 'address' not in metadata['fee'][c]:
|
||||||
else:
|
d = self.session.wallet.get_new_address()
|
||||||
d = defer.succeed(None)
|
d.addCallback(lambda addr: _set_address(addr, c))
|
||||||
else:
|
|
||||||
d = defer.succeed(None)
|
|
||||||
|
|
||||||
|
|
||||||
pub = Publisher(self.session, self.lbry_file_manager, self.session.wallet)
|
pub = Publisher(self.session, self.lbry_file_manager, self.session.wallet)
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@ import logging
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
from copy import deepcopy
|
||||||
from appdirs import user_data_dir
|
from appdirs import user_data_dir
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from twisted.internet import defer
|
from twisted.internet import defer
|
||||||
|
@ -58,7 +59,7 @@ class GetStream(object):
|
||||||
self.sd_identifier = sd_identifier
|
self.sd_identifier = sd_identifier
|
||||||
self.stream_hash = None
|
self.stream_hash = None
|
||||||
self.max_key_fee = max_key_fee
|
self.max_key_fee = max_key_fee
|
||||||
self.metadata = None
|
self.stream_info = None
|
||||||
self.stream_info_manager = None
|
self.stream_info_manager = None
|
||||||
self.d = defer.Deferred(None)
|
self.d = defer.Deferred(None)
|
||||||
self.timeout = timeout
|
self.timeout = timeout
|
||||||
|
@ -86,20 +87,23 @@ class GetStream(object):
|
||||||
|
|
||||||
def start(self, stream_info, name):
|
def start(self, stream_info, name):
|
||||||
self.resolved_name = name
|
self.resolved_name = name
|
||||||
self.metadata = stream_info
|
self.stream_info = deepcopy(stream_info)
|
||||||
self.stream_hash = self.metadata['sources']['lbry_sd_hash']
|
self.description = self.stream_info['description']
|
||||||
|
self.stream_hash = self.stream_info['sources']['lbry_sd_hash']
|
||||||
|
|
||||||
if 'fee' in self.metadata:
|
if 'fee' in self.stream_info:
|
||||||
self.fee = LBRYFee(self.metadata['fee'], {'USDBTC': self.wallet._USDBTC, 'BTCLBC': self.wallet._BTCLBC})
|
self.fee = LBRYFee(self.stream_info['fee'], {'USDBTC': self.wallet._USDBTC, 'BTCLBC': self.wallet._BTCLBC})
|
||||||
if isinstance(self.max_key_fee, float):
|
if isinstance(self.max_key_fee, float):
|
||||||
if self.fee.to_lbc() > self.max_key_fee:
|
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))
|
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())
|
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):
|
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():
|
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))
|
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())
|
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():
|
def _cause_timeout():
|
||||||
self.timeout_counter = self.timeout * 2
|
self.timeout_counter = self.timeout * 2
|
||||||
|
@ -130,20 +134,19 @@ class GetStream(object):
|
||||||
def _start_download(self, downloader):
|
def _start_download(self, downloader):
|
||||||
def _pay_key_fee():
|
def _pay_key_fee():
|
||||||
if self.fee is not None:
|
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)
|
reserved_points = self.wallet.reserve_points(self.fee.address, fee_lbc)
|
||||||
if reserved_points is None:
|
if reserved_points is None:
|
||||||
return defer.fail(InsufficientFundsError())
|
return defer.fail(InsufficientFundsError())
|
||||||
log.info("Key fee: %f --> %s" % (fee_lbc, self.fee.address))
|
return self.wallet.send_points_to_address(reserved_points, fee_lbc)
|
||||||
d = self.wallet.send_points_to_address(reserved_points, self.fee.address)
|
|
||||||
return d
|
|
||||||
|
|
||||||
return defer.succeed(None)
|
return defer.succeed(None)
|
||||||
|
|
||||||
|
d = _pay_key_fee()
|
||||||
|
|
||||||
self.downloader = downloader
|
self.downloader = downloader
|
||||||
self.download_path = os.path.join(downloader.download_directory, downloader.file_name)
|
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 _: log.info("Downloading %s --> %s", self.stream_hash, self.downloader.file_name))
|
||||||
d.addCallback(lambda _: self.downloader.start())
|
d.addCallback(lambda _: self.downloader.start())
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue