Browse Source

move lnpay attempts logic to lnworker.pay

dependabot/pip/contrib/deterministic-build/ecdsa-0.13.3
ThomasV 6 years ago
parent
commit
dbe8b75659
  1. 5
      electrum/commands.py
  2. 11
      electrum/gui/qt/main_window.py
  3. 11
      electrum/lnworker.py

5
electrum/commands.py

@ -780,8 +780,8 @@ class Commands:
self.lnworker.reestablish_channel() self.lnworker.reestablish_channel()
@command('wn') @command('wn')
def lnpay(self, invoice, timeout=10): def lnpay(self, invoice, attempts=1, timeout=10):
return self.lnworker.pay(invoice, timeout=timeout) return self.lnworker.pay(invoice, attempts=attempts, timeout=timeout)
@command('wn') @command('wn')
def addinvoice(self, requested_amount, message): def addinvoice(self, requested_amount, message):
@ -902,6 +902,7 @@ command_options = {
'domain': ("-D", "List of addresses"), 'domain': ("-D", "List of addresses"),
'memo': ("-m", "Description of the request"), 'memo': ("-m", "Description of the request"),
'expiration': (None, "Time in seconds"), 'expiration': (None, "Time in seconds"),
'attempts': (None, "Number of payment attempts"),
'timeout': (None, "Timeout in seconds"), 'timeout': (None, "Timeout in seconds"),
'force': (None, "Create new address beyond gap limit, if no more addresses are available."), 'force': (None, "Create new address beyond gap limit, if no more addresses are available."),
'pending': (None, "Show only pending requests."), 'pending': (None, "Show only pending requests."),

11
electrum/gui/qt/main_window.py

@ -1678,6 +1678,7 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, Logger):
LN_NUM_PAYMENT_ATTEMPTS = 3 LN_NUM_PAYMENT_ATTEMPTS = 3
def on_success(result): def on_success(result):
self.logger.info(f'ln payment success. {result}') self.logger.info(f'ln payment success. {result}')
self.show_error(_('Payment succeeded'))
self.do_clear() self.do_clear()
def on_failure(exc_info): def on_failure(exc_info):
type_, e, traceback = exc_info type_, e, traceback = exc_info
@ -1686,14 +1687,12 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, Logger):
elif isinstance(e, InvoiceError): elif isinstance(e, InvoiceError):
self.show_error(_('InvoiceError: {}').format(e)) self.show_error(_('InvoiceError: {}').format(e))
else: else:
self.show_error(_('Error: {}').format(e))
raise e raise e
def task(): def task():
for i in range(LN_NUM_PAYMENT_ATTEMPTS): success = self.wallet.lnworker.pay(invoice, attempts=LN_NUM_PAYMENT_ATTEMPTS, amount_sat=amount, timeout=30)
success = self.wallet.lnworker.pay(invoice, amount_sat=amount, timeout=30) if not success:
if success: raise PaymentFailure('Failed after {LN_NUM_PAYMENT_ATTEMPTS} attempts')
break
else:
raise PaymentFailure('Failed after {i} attempts')
msg = _('Sending lightning payment...') msg = _('Sending lightning payment...')
WaitingDialog(self, msg, task, on_success, on_failure) WaitingDialog(self, msg, task, on_success, on_failure)

11
electrum/lnworker.py

@ -652,13 +652,13 @@ class LNWallet(LNWorker):
chan = f.result(timeout) chan = f.result(timeout)
return chan.funding_outpoint.to_str() return chan.funding_outpoint.to_str()
def pay(self, invoice, amount_sat=None, timeout=10): def pay(self, invoice, attempts=1, amount_sat=None, timeout=10):
""" """
Can be called from other threads Can be called from other threads
Raises timeout exception if htlc is not fulfilled Raises timeout exception if htlc is not fulfilled
""" """
fut = asyncio.run_coroutine_threadsafe( fut = asyncio.run_coroutine_threadsafe(
self._pay(invoice, amount_sat), self._pay(invoice, attempts, amount_sat),
self.network.asyncio_loop) self.network.asyncio_loop)
return fut.result(timeout=timeout) return fut.result(timeout=timeout)
@ -668,14 +668,17 @@ class LNWallet(LNWorker):
if chan.short_channel_id == short_channel_id: if chan.short_channel_id == short_channel_id:
return chan return chan
async def _pay(self, invoice, amount_sat=None): async def _pay(self, invoice, attempts=1, amount_sat=None):
addr = self._check_invoice(invoice, amount_sat) addr = self._check_invoice(invoice, amount_sat)
self.save_invoice(addr.paymenthash, invoice, SENT, is_paid=False) self.save_invoice(addr.paymenthash, invoice, SENT, is_paid=False)
self.wallet.set_label(bh2u(addr.paymenthash), addr.get_description()) self.wallet.set_label(bh2u(addr.paymenthash), addr.get_description())
for i in range(attempts):
route = await self._create_route_from_invoice(decoded_invoice=addr) route = await self._create_route_from_invoice(decoded_invoice=addr)
if not self.get_channel_by_short_id(route[0].short_channel_id): if not self.get_channel_by_short_id(route[0].short_channel_id):
assert False, 'Found route with short channel ID we don\'t have: ' + repr(route[0].short_channel_id) assert False, 'Found route with short channel ID we don\'t have: ' + repr(route[0].short_channel_id)
return await self._pay_to_route(route, addr, invoice) if await self._pay_to_route(route, addr, invoice):
return True
return False
async def _pay_to_route(self, route, addr, pay_req): async def _pay_to_route(self, route, addr, pay_req):
short_channel_id = route[0].short_channel_id short_channel_id = route[0].short_channel_id

Loading…
Cancel
Save