fix max_key_fee

This commit is contained in:
Jack Robison 2019-02-08 21:08:41 -05:00
parent f65e70df2f
commit c9d54bb049
No known key found for this signature in database
GPG key ID: DF25C68FE0239BB2
4 changed files with 52 additions and 10 deletions

View file

@ -498,7 +498,7 @@ class Config(CLIConfig):
) )
max_key_fee = MaxKeyFee( max_key_fee = MaxKeyFee(
"Don't download streams with fees exceeding this amount", {'currency': 'USD', 'amount': 50.0} "Don't download streams with fees exceeding this amount", {'currency': 'USD', 'amount': 50.0}
) # TODO: use this )
# reflector settings # reflector settings
reflect_streams = Toggle( reflect_streams = Toggle(

View file

@ -4,7 +4,7 @@ import typing
import binascii import binascii
import logging import logging
import random import random
from lbrynet.error import ResolveError, InvalidStreamDescriptorError from lbrynet.error import ResolveError, InvalidStreamDescriptorError, KeyFeeAboveMaxAllowed, InsufficientFundsError
from lbrynet.stream.downloader import StreamDownloader from lbrynet.stream.downloader import StreamDownloader
from lbrynet.stream.managed_stream import ManagedStream from lbrynet.stream.managed_stream import ManagedStream
from lbrynet.schema.claim import ClaimDict from lbrynet.schema.claim import ClaimDict
@ -287,9 +287,6 @@ class StreamManager:
already_started = tuple(filter(lambda s: s.descriptor.sd_hash == sd_hash, self.streams)) already_started = tuple(filter(lambda s: s.descriptor.sd_hash == sd_hash, self.streams))
if already_started: if already_started:
return already_started[0] return already_started[0]
if should_pay and fee_address and fee_amount and fee_amount > await self.wallet.default_account.get_balance():
raise Exception("not enough funds")
self.starting_streams[sd_hash] = asyncio.Future(loop=self.loop) self.starting_streams[sd_hash] = asyncio.Future(loop=self.loop)
stream_task = self.loop.create_task( stream_task = self.loop.create_task(
self._download_stream_from_claim(node, self.config.download_dir, claim_info, file_name) self._download_stream_from_claim(node, self.config.download_dir, claim_info, file_name)
@ -354,7 +351,7 @@ class StreamManager:
timeout = timeout or self.config.download_timeout timeout = timeout or self.config.download_timeout
parsed_uri = parse_lbry_uri(uri) parsed_uri = parse_lbry_uri(uri)
if parsed_uri.is_channel: if parsed_uri.is_channel:
raise Exception("cannot download a channel claim, specify a /path") raise ResolveError("cannot download a channel claim, specify a /path")
resolved = (await self.wallet.resolve(uri)).get(uri, {}) resolved = (await self.wallet.resolve(uri)).get(uri, {})
resolved = resolved if 'value' in resolved else resolved.get('claim') resolved = resolved if 'value' in resolved else resolved.get('claim')
@ -372,6 +369,19 @@ class StreamManager:
fee_amount = round(exchange_rate_manager.convert_currency( fee_amount = round(exchange_rate_manager.convert_currency(
claim.source_fee.currency, "LBC", claim.source_fee.amount claim.source_fee.currency, "LBC", claim.source_fee.amount
), 5) ), 5)
max_fee_amount = round(exchange_rate_manager.convert_currency(
self.config.max_key_fee['currency'], "LBC", self.config.max_key_fee['amount']
), 5)
if fee_amount > max_fee_amount:
msg = f"fee of {fee_amount} exceeds max configured to allow of {max_fee_amount}"
log.warning(msg)
raise KeyFeeAboveMaxAllowed(msg)
else:
balance = await self.wallet.default_account.get_balance()
if fee_amount > balance:
msg = f"fee of {fee_amount} exceeds max available balance"
log.warning(msg)
raise InsufficientFundsError(msg)
fee_address = claim.source_fee.address.decode() fee_address = claim.source_fee.address.decode()
outpoint = f"{resolved['txid']}:{resolved['nout']}" outpoint = f"{resolved['txid']}:{resolved['nout']}"
existing = self.get_filtered_streams(outpoint=outpoint) existing = self.get_filtered_streams(outpoint=outpoint)

View file

@ -40,7 +40,7 @@ def get_dummy_exchange_rate_manager(time):
'BTCLBC': {'spot': 3.0, 'ts': time.time() + 1}, 'BTCLBC': {'spot': 3.0, 'ts': time.time() + 1},
'USDBTC': {'spot': 2.0, 'ts': time.time() + 2} 'USDBTC': {'spot': 2.0, 'ts': time.time() + 2}
} }
return DummyExchangeRateManager([BTCLBCFeed()], rates) return DummyExchangeRateManager([BTCLBCFeed(), USDBTCFeed()], rates)
class FeeFormatTest(unittest.TestCase): class FeeFormatTest(unittest.TestCase):

View file

@ -5,7 +5,7 @@ import asyncio
import time import time
from tests.unit.blob_exchange.test_transfer_blob import BlobExchangeTestBase from tests.unit.blob_exchange.test_transfer_blob import BlobExchangeTestBase
from tests.unit.lbrynet_daemon.test_ExchangeRateManager import get_dummy_exchange_rate_manager from tests.unit.lbrynet_daemon.test_ExchangeRateManager import get_dummy_exchange_rate_manager
from lbrynet.error import InsufficientFundsError, KeyFeeAboveMaxAllowed
from lbrynet.extras.wallet.manager import LbryWalletManager from lbrynet.extras.wallet.manager import LbryWalletManager
from lbrynet.stream.stream_manager import StreamManager from lbrynet.stream.stream_manager import StreamManager
from lbrynet.stream.descriptor import StreamDescriptor from lbrynet.stream.descriptor import StreamDescriptor
@ -26,7 +26,7 @@ def get_mock_node(peer):
return mock_node return mock_node
def get_mock_wallet(sd_hash, storage): def get_mock_wallet(sd_hash, storage, balance=10.0, fee=None):
claim = { claim = {
"address": "bYFeMtSL7ARuG1iMpjFyrnTe4oJHSAVNXF", "address": "bYFeMtSL7ARuG1iMpjFyrnTe4oJHSAVNXF",
"amount": "0.1", "amount": "0.1",
@ -69,6 +69,8 @@ def get_mock_wallet(sd_hash, storage):
"version": "_0_0_1" "version": "_0_0_1"
} }
} }
if fee:
claim['value']['stream']['metadata']['fee'] = fee
claim_dict = ClaimDict.load_dict(claim['value']) claim_dict = ClaimDict.load_dict(claim['value'])
claim['hex'] = binascii.hexlify(claim_dict.serialized).decode() claim['hex'] = binascii.hexlify(claim_dict.serialized).decode()
@ -80,6 +82,11 @@ def get_mock_wallet(sd_hash, storage):
mock_wallet = mock.Mock(spec=LbryWalletManager) mock_wallet = mock.Mock(spec=LbryWalletManager)
mock_wallet.resolve = mock_resolve mock_wallet.resolve = mock_resolve
async def get_balance(*_):
return balance
mock_wallet.default_account.get_balance = get_balance
return mock_wallet, claim['permanent_url'] return mock_wallet, claim['permanent_url']
@ -91,12 +98,15 @@ class TestStreamManager(BlobExchangeTestBase):
f.write(os.urandom(20000000)) f.write(os.urandom(20000000))
descriptor = await StreamDescriptor.create_stream(self.loop, self.server_blob_manager.blob_dir, file_path) descriptor = await StreamDescriptor.create_stream(self.loop, self.server_blob_manager.blob_dir, file_path)
self.sd_hash = descriptor.calculate_sd_hash() self.sd_hash = descriptor.calculate_sd_hash()
self.mock_wallet, self.uri = get_mock_wallet(self.sd_hash, self.client_storage)
async def setup_stream_manager(self, balance=10.0, fee=None):
self.mock_wallet, self.uri = get_mock_wallet(self.sd_hash, self.client_storage, balance, fee)
self.stream_manager = StreamManager(self.loop, self.client_config, self.client_blob_manager, self.mock_wallet, self.stream_manager = StreamManager(self.loop, self.client_config, self.client_blob_manager, self.mock_wallet,
self.client_storage, get_mock_node(self.server_from_client)) self.client_storage, get_mock_node(self.server_from_client))
self.exchange_rate_manager = get_dummy_exchange_rate_manager(time) self.exchange_rate_manager = get_dummy_exchange_rate_manager(time)
async def test_download_stop_resume_delete(self): async def test_download_stop_resume_delete(self):
await self.setup_stream_manager()
self.assertSetEqual(self.stream_manager.streams, set()) self.assertSetEqual(self.stream_manager.streams, set())
stream = await self.stream_manager.download_stream_from_uri(self.uri, self.exchange_rate_manager) stream = await self.stream_manager.download_stream_from_uri(self.uri, self.exchange_rate_manager)
stream_hash = stream.stream_hash stream_hash = stream.stream_hash
@ -137,3 +147,25 @@ class TestStreamManager(BlobExchangeTestBase):
"select status from file where stream_hash=?", stream_hash "select status from file where stream_hash=?", stream_hash
) )
self.assertEqual(stored_status, None) self.assertEqual(stored_status, None)
async def test_insufficient_funds(self):
fee = {
'currency': 'LBC',
'amount': 11.0,
'address': 'bYFeMtSL7ARuG1iMpjFyrnTe4oJHSAVNXF',
'version': '_0_0_1'
}
await self.setup_stream_manager(10.0, fee)
with self.assertRaises(InsufficientFundsError):
await self.stream_manager.download_stream_from_uri(self.uri, self.exchange_rate_manager)
async def test_fee_above_max_allowed(self):
fee = {
'currency': 'USD',
'amount': 51.0,
'address': 'bYFeMtSL7ARuG1iMpjFyrnTe4oJHSAVNXF',
'version': '_0_0_1'
}
await self.setup_stream_manager(1000000.0, fee)
with self.assertRaises(KeyFeeAboveMaxAllowed):
await self.stream_manager.download_stream_from_uri(self.uri, self.exchange_rate_manager)