Don't use retriable_call(). Add handling for InsufficientFundsError.

This commit is contained in:
Jonathan Moody 2022-09-16 11:01:13 -05:00 committed by Lex Berezhny
parent 231b982422
commit 20b1865879

View file

@ -1,9 +1,8 @@
import asyncio import asyncio
import logging import logging
import sys
import traceback
from lbry.error import ( from lbry.error import (
InsufficientFundsError,
ServerPaymentFeeAboveMaxAllowedError, ServerPaymentFeeAboveMaxAllowedError,
ServerPaymentInvalidAddressError, ServerPaymentInvalidAddressError,
ServerPaymentWalletLockedError ServerPaymentWalletLockedError
@ -26,67 +25,66 @@ class WalletServerPayer:
self.max_fee = max_fee self.max_fee = max_fee
self._on_payment_controller = StreamController() self._on_payment_controller = StreamController()
self.on_payment = self._on_payment_controller.stream self.on_payment = self._on_payment_controller.stream
self.on_payment.listen(None, on_error=lambda e: logging.warning(e.args[0])) self.on_payment.listen(None, on_error=lambda e: log.warning(e.args[0]))
async def pay(self): async def pay(self):
while self.running: while self.running:
try: try:
await self._pay() await self._pay()
except BaseException: except (asyncio.TimeoutError, ConnectionError):
if self.running: if not self.running:
traceback.print_exception(*sys.exc_info()) break
log.warning("Caught exception: %s", sys.exc_info()[0].__name__) delay = max(self.payment_period / 24, 10)
else: log.warning("Payement failed. Will retry after %g seconds.", delay)
log.warning("Caught exception: %s", sys.exc_info()[0].__name__) asyncio.sleep(delay)
except Exception:
log.exception("Unexpected exception. Payment task exiting early.")
raise raise
#if not self.running:
# raise
async def _pay(self): async def _pay(self):
while self.running: while self.running:
log.info("pay loop: before sleep")
await asyncio.sleep(self.payment_period) await asyncio.sleep(self.payment_period)
log.info("pay loop: before get_server_features") features = await self.ledger.network.get_server_features()
features = await self.ledger.network.retriable_call(self.ledger.network.get_server_features) log.debug("pay loop: received server features: %s", str(features))
log.info("pay loop: received features: %s", str(features))
address = features['payment_address'] address = features['payment_address']
amount = str(features['daily_fee']) amount = str(features['daily_fee'])
if not address or not amount: if not address or not amount:
log.warning("pay loop: no address or no amount") log.debug("pay loop: no address or no amount")
continue continue
if not self.ledger.is_pubkey_address(address): if not self.ledger.is_pubkey_address(address):
log.warning("pay loop: address not pubkey") log.info("pay loop: address not pubkey")
self._on_payment_controller.add_error(ServerPaymentInvalidAddressError(address)) self._on_payment_controller.add_error(ServerPaymentInvalidAddressError(address))
continue continue
if self.wallet.is_locked: if self.wallet.is_locked:
log.warning("pay loop: wallet is locked") log.info("pay loop: wallet is locked")
self._on_payment_controller.add_error(ServerPaymentWalletLockedError()) self._on_payment_controller.add_error(ServerPaymentWalletLockedError())
continue continue
amount = lbc_to_dewies(features['daily_fee']) # check that this is in lbc and not dewies amount = lbc_to_dewies(features['daily_fee']) # check that this is in lbc and not dewies
limit = lbc_to_dewies(self.max_fee) limit = lbc_to_dewies(self.max_fee)
if amount > limit: if amount > limit:
log.warning("pay loop: amount (%d) > limit (%d)", amount, limit) log.info("pay loop: amount (%d) > limit (%d)", amount, limit)
self._on_payment_controller.add_error( self._on_payment_controller.add_error(
ServerPaymentFeeAboveMaxAllowedError(features['daily_fee'], self.max_fee) ServerPaymentFeeAboveMaxAllowedError(features['daily_fee'], self.max_fee)
) )
continue continue
log.info("pay loop: before transaction create") try:
tx = await Transaction.create( tx = await Transaction.create(
[], [],
[Output.pay_pubkey_hash(amount, self.ledger.address_to_hash160(address))], [Output.pay_pubkey_hash(amount, self.ledger.address_to_hash160(address))],
self.wallet.get_accounts_or_all(None), self.wallet.get_accounts_or_all(None),
self.wallet.get_account_or_default(None) self.wallet.get_account_or_default(None)
) )
except InsufficientFundsError as e:
self._on_payment_controller.add_error(e)
continue
log.info("pay loop: before transaction broadcast")
await self.ledger.broadcast_or_release(tx, blocking=True) await self.ledger.broadcast_or_release(tx, blocking=True)
if self.analytics_manager: if self.analytics_manager:
await self.analytics_manager.send_credits_sent() await self.analytics_manager.send_credits_sent()
log.info("pay loop: after transaction broadcast")
self._on_payment_controller.add(tx) self._on_payment_controller.add(tx)
async def start(self, ledger=None, wallet=None): async def start(self, ledger=None, wallet=None):