diff --git a/lbrynet/core/LBRYMetadata.py b/lbrynet/core/LBRYMetadata.py index b3d80cb91..beed9bf12 100644 --- a/lbrynet/core/LBRYMetadata.py +++ b/lbrynet/core/LBRYMetadata.py @@ -26,35 +26,50 @@ FEE_REVISIONS = {'0.0.1': {'required': ['amount', 'address'], 'optional': []}} CURRENT_FEE_REVISION = '0.0.1' -class LBRYFeeFormat(dict): +class LBRYFeeValidator(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()) + self.fee_version = None - self.amount = self[self.currency_symbol]['amount'] if isinstance(self[self.currency_symbol]['amount'], float) else float(self[self.currency_symbol]['amount']) + fee_to_load = deepcopy(fee_dict) + + for currency in fee_dict: + self._verify_fee(currency, fee_to_load) + + self.amount = self._get_amount() self.address = self[self.currency_symbol]['address'] + def _get_amount(self): + if isinstance(self[self.currency_symbol]['amount'], float): + return self[self.currency_symbol]['amount'] + else: + return float(self[self.currency_symbol]['amount']) -class LBRYFee(LBRYFeeFormat): + def _verify_fee(self, currency, f): + # str in case someone made a claim with a wierd fee + assert currency in CURRENCIES, "Unsupported currency: %s" % str(currency) + self.currency_symbol = currency + self.update({currency: {}}) + for version in FEE_REVISIONS: + self._load_revision(version, f) + if not f: + self.fee_version = version + break + assert f[self.currency_symbol] == {}, "Unknown fee keys: %s" % json.dumps(f.keys()) + + def _load_revision(self, version, f): + for k in FEE_REVISIONS[version]['required']: + assert k in f[self.currency_symbol], "Missing required fee field: %s" % k + self[self.currency_symbol].update({k: f[self.currency_symbol].pop(k)}) + for k in FEE_REVISIONS[version]['optional']: + if k in f[self.currency_symbol]: + self[self.currency_symbol].update({k: f[self.currency_symbol].pop(k)}) + + +class LBRYFee(LBRYFeeValidator): def __init__(self, fee_dict, rate_dict, bittrex_fee=None): - LBRYFeeFormat.__init__(self, fee_dict) + LBRYFeeValidator.__init__(self, fee_dict) self.bittrex_fee = BITTREX_FEE if bittrex_fee is None else bittrex_fee rates = deepcopy(rate_dict) @@ -102,25 +117,35 @@ class LBRYFee(LBRYFeeFormat): class Metadata(dict): def __init__(self, metadata): dict.__init__(self) - self.metaversion = None - m = deepcopy(metadata) + self.meta_version = None + metadata_to_load = deepcopy(metadata) + self._verify_sources(metadata_to_load) + self._verify_metadata(metadata_to_load) + + def _load_revision(self, version, metadata): + for k in METADATA_REVISIONS[version]['required']: + assert k in metadata, "Missing required metadata field: %s" % k + self.update({k: metadata.pop(k)}) + for k in METADATA_REVISIONS[version]['optional']: + if k == 'fee': + self['fee'] = LBRYFeeValidator(metadata.pop('fee')) + elif k in metadata: + self.update({k: metadata.pop(k)}) + + def _load_fee(self, metadata): + if 'fee' in metadata: + self['fee'] = LBRYFeeValidator(metadata.pop('fee')) + + def _verify_sources(self, metadata): assert "sources" in metadata, "No sources given" for source in metadata['sources']: assert source in SOURCE_TYPES, "Unknown source type" + def _verify_metadata(self, metadata): for version in METADATA_REVISIONS: - for k in METADATA_REVISIONS[version]['required']: - assert k in metadata, "Missing required metadata field: %s" % k - self.update({k: m.pop(k)}) - for k in METADATA_REVISIONS[version]['optional']: - if k == 'fee': - pass - elif k in metadata: - self.update({k: m.pop(k)}) - if not len(m) or m.keys() == ['fee']: - self.metaversion = version + self._load_revision(version, metadata) + if not metadata: + self.meta_version = version break - if 'fee' in m: - self['fee'] = LBRYFeeFormat(m.pop('fee')) - assert m == {}, "Unknown metadata keys: %s" % json.dumps(m.keys()) + assert metadata == {}, "Unknown metadata keys: %s" % json.dumps(metadata.keys()) diff --git a/lbrynet/core/LBRYWallet.py b/lbrynet/core/LBRYWallet.py index 3e7573a6e..1e567169d 100644 --- a/lbrynet/core/LBRYWallet.py +++ b/lbrynet/core/LBRYWallet.py @@ -379,7 +379,7 @@ class LBRYWallet(object): m = Metadata(value_dict) if 'txid' in result: d = self._save_name_metadata(name, str(result['txid']), m['sources']['lbry_sd_hash']) - d.addCallback(lambda _: log.info("lbry://%s complies with %s" % (name, m.metaversion))) + d.addCallback(lambda _: log.info("lbry://%s complies with %s" % (name, m.meta_version))) d.addCallback(lambda _: m) return d elif 'error' in result: diff --git a/lbrynet/lbrynet_daemon/LBRYDownloader.py b/lbrynet/lbrynet_daemon/LBRYDownloader.py index 0056101c5..8106b1fd4 100644 --- a/lbrynet/lbrynet_daemon/LBRYDownloader.py +++ b/lbrynet/lbrynet_daemon/LBRYDownloader.py @@ -84,26 +84,14 @@ class GetStream(object): self.code = STREAM_STAGES[4] self.finished.callback(False) + def _convert_max_fee(self): + if isinstance(self.max_key_fee, dict): + max_fee = deepcopy(self.max_key_fee) + return LBRYFee(max_fee, {'USDBTC': self.wallet._USDBTC, 'BTCLBC': self.wallet._BTCLBC}).to_lbc() + elif isinstance(self.max_key_fee, float): + return float(self.max_key_fee) + def start(self, stream_info, name): - self.resolved_name = name - 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.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(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(err): log.error(err) log.debug('Forcing a timeout') @@ -128,6 +116,23 @@ class GetStream(object): download_directory=self.download_directory, file_name=self.file_name) + self.resolved_name = name + 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.stream_info: + self.fee = LBRYFee(self.stream_info['fee'], {'USDBTC': self.wallet._USDBTC, 'BTCLBC': self.wallet._BTCLBC}) + max_key_fee = self._convert_max_fee() + if self.fee.to_lbc() > 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(), + max_key_fee, + self.resolved_name)) + self.checker.start(1) self.d.addCallback(lambda _: _set_status(None, DOWNLOAD_METADATA_CODE)) diff --git a/tests/lbrynet/core/test_LBRYMetadata.py b/tests/lbrynet/core/test_LBRYMetadata.py index ac88ffa77..643fc5d31 100644 --- a/tests/lbrynet/core/test_LBRYMetadata.py +++ b/tests/lbrynet/core/test_LBRYMetadata.py @@ -12,7 +12,7 @@ class LBRYFeeFormatTest(unittest.TestCase): 'address': None } } - fee = LBRYMetadata.LBRYFeeFormat(fee_dict) + fee = LBRYMetadata.LBRYFeeValidator(fee_dict) self.assertEqual(10, fee['USD']['amount']) @@ -68,7 +68,7 @@ class MetadataTest(unittest.TestCase): 'content-type': None, } m = LBRYMetadata.Metadata(metadata) - self.assertEquals('0.0.1', m.metaversion) + self.assertEquals('0.0.1', m.meta_version) def test_assertion_if_there_is_an_extra_field(self): metadata = { @@ -97,6 +97,6 @@ class MetadataTest(unittest.TestCase): 'ver': None } m = LBRYMetadata.Metadata(metadata) - self.assertEquals('0.0.2', m.metaversion) + self.assertEquals('0.0.2', m.meta_version)