lnworker: fix can_pay_invoice for trampoline MPP
Call it from the GUI
This commit is contained in:
@@ -111,7 +111,7 @@ class InvoiceDialog(Factory.Popup):
|
|||||||
self.status_color = pr_color[self.status]
|
self.status_color = pr_color[self.status]
|
||||||
self.can_pay = self.status in [PR_UNPAID, PR_FAILED]
|
self.can_pay = self.status in [PR_UNPAID, PR_FAILED]
|
||||||
if self.can_pay and self.is_lightning and self.app.wallet.lnworker:
|
if self.can_pay and self.is_lightning and self.app.wallet.lnworker:
|
||||||
if self.amount_sat and self.amount_sat > self.app.wallet.lnworker.num_sats_can_send():
|
if self.amount_sat and not self.app.wallet.lnworker.can_pay_invoice(invoice):
|
||||||
self.warning = _('Warning') + ': ' + _('This amount exceeds the maximum you can currently send with your channels')
|
self.warning = _('Warning') + ': ' + _('This amount exceeds the maximum you can currently send with your channels')
|
||||||
|
|
||||||
def on_dismiss(self):
|
def on_dismiss(self):
|
||||||
|
|||||||
@@ -1671,8 +1671,8 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, Logger):
|
|||||||
key = self.wallet.get_key_for_outgoing_invoice(invoice)
|
key = self.wallet.get_key_for_outgoing_invoice(invoice)
|
||||||
if amount_sat is None:
|
if amount_sat is None:
|
||||||
raise Exception("missing amount for LN invoice")
|
raise Exception("missing amount for LN invoice")
|
||||||
num_sats_can_send = int(self.wallet.lnworker.num_sats_can_send())
|
if not self.wallet.lnworker.can_pay_invoice(invoice):
|
||||||
if amount_sat > num_sats_can_send:
|
num_sats_can_send = int(self.wallet.lnworker.num_sats_can_send())
|
||||||
lightning_needed = amount_sat - num_sats_can_send
|
lightning_needed = amount_sat - num_sats_can_send
|
||||||
lightning_needed += (lightning_needed // 20) # operational safety margin
|
lightning_needed += (lightning_needed // 20) # operational safety margin
|
||||||
coins = self.get_coins(nonlocal_only=True)
|
coins = self.get_coins(nonlocal_only=True)
|
||||||
|
|||||||
@@ -1090,6 +1090,40 @@ class LNWallet(LNWorker):
|
|||||||
if invoice.is_lightning() and self.can_pay_invoice(invoice):
|
if invoice.is_lightning() and self.can_pay_invoice(invoice):
|
||||||
await self.pay_invoice(invoice.lightning_invoice, attempts=10)
|
await self.pay_invoice(invoice.lightning_invoice, attempts=10)
|
||||||
|
|
||||||
|
def can_pay_invoice(self, invoice: Invoice) -> bool:
|
||||||
|
assert invoice.is_lightning()
|
||||||
|
if invoice.get_amount_sat() > self.num_sats_can_send():
|
||||||
|
return False
|
||||||
|
# if we dont find a path because of unsynchronized DB, this method should not return False
|
||||||
|
if self.channel_db:
|
||||||
|
return True
|
||||||
|
# trampoline nodes currently cannot do legacy payments over multiple nodes
|
||||||
|
# we call create_routes_for_payment in order to find out
|
||||||
|
lnaddr = self._check_invoice(invoice.lightning_invoice, amount_msat=invoice.get_amount_msat())
|
||||||
|
min_cltv_expiry = lnaddr.get_min_final_cltv_expiry()
|
||||||
|
invoice_pubkey = lnaddr.pubkey.serialize()
|
||||||
|
invoice_features = lnaddr.get_features()
|
||||||
|
r_tags = lnaddr.get_routing_info('r')
|
||||||
|
amount_to_pay = lnaddr.get_amount_msat()
|
||||||
|
try:
|
||||||
|
routes = self.create_routes_for_payment(
|
||||||
|
amount_msat=amount_to_pay,
|
||||||
|
final_total_msat=amount_to_pay,
|
||||||
|
invoice_pubkey=invoice_pubkey,
|
||||||
|
min_cltv_expiry=min_cltv_expiry,
|
||||||
|
r_tags=r_tags,
|
||||||
|
invoice_features=invoice_features,
|
||||||
|
full_path=None,
|
||||||
|
payment_hash=bytes(32),
|
||||||
|
payment_secret=bytes(32),
|
||||||
|
trampoline_fee_level=self.INITIAL_TRAMPOLINE_FEE_LEVEL,
|
||||||
|
use_two_trampolines=False,
|
||||||
|
fwd_trampoline_onion=None
|
||||||
|
)
|
||||||
|
return True
|
||||||
|
except NoPathFound:
|
||||||
|
return False
|
||||||
|
|
||||||
@log_exceptions
|
@log_exceptions
|
||||||
async def pay_invoice(
|
async def pay_invoice(
|
||||||
self, invoice: str, *,
|
self, invoice: str, *,
|
||||||
@@ -2085,10 +2119,6 @@ class LNWallet(LNWorker):
|
|||||||
can_receive = max([c.available_to_spend(REMOTE) for c in channels]) if channels else 0
|
can_receive = max([c.available_to_spend(REMOTE) for c in channels]) if channels else 0
|
||||||
return Decimal(can_receive) / 1000
|
return Decimal(can_receive) / 1000
|
||||||
|
|
||||||
def can_pay_invoice(self, invoice: Invoice) -> bool:
|
|
||||||
assert invoice.is_lightning()
|
|
||||||
return invoice.get_amount_sat() <= self.num_sats_can_send()
|
|
||||||
|
|
||||||
def can_receive_invoice(self, invoice: Invoice) -> bool:
|
def can_receive_invoice(self, invoice: Invoice) -> bool:
|
||||||
assert invoice.is_lightning()
|
assert invoice.is_lightning()
|
||||||
return invoice.get_amount_sat() <= self.num_sats_can_receive()
|
return invoice.get_amount_sat() <= self.num_sats_can_receive()
|
||||||
|
|||||||
Reference in New Issue
Block a user