|
|
|
|
@ -693,6 +693,7 @@ class PaySession(Logger):
|
|
|
|
|
|
|
|
|
|
self._amount_inflight = 0 # what we sent in htlcs (that receiver gets, without fees) |
|
|
|
|
self._nhtlcs_inflight = 0 |
|
|
|
|
self.is_active = True |
|
|
|
|
|
|
|
|
|
def diagnostic_name(self): |
|
|
|
|
pkey = sha256(self.payment_key) |
|
|
|
|
@ -779,6 +780,14 @@ class PaySession(Logger):
|
|
|
|
|
def get_outstanding_amount_to_send(self) -> int: |
|
|
|
|
return self.amount_to_pay - self._amount_inflight |
|
|
|
|
|
|
|
|
|
def can_be_deleted(self) -> bool: |
|
|
|
|
if self.is_active: |
|
|
|
|
return False |
|
|
|
|
# note: no one is consuming from sent_htlcs_q anymore |
|
|
|
|
nhtlcs_resolved = self.sent_htlcs_q.qsize() |
|
|
|
|
assert nhtlcs_resolved <= self._nhtlcs_inflight |
|
|
|
|
return nhtlcs_resolved == self._nhtlcs_inflight |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class LNWallet(LNWorker): |
|
|
|
|
|
|
|
|
|
@ -1412,7 +1421,7 @@ class LNWallet(LNWorker):
|
|
|
|
|
raise OnionRoutingFailure(code=OnionFailureCode.TRAMPOLINE_EXPIRY_TOO_SOON, data=b'') |
|
|
|
|
|
|
|
|
|
payment_key = payment_hash + payment_secret |
|
|
|
|
#assert payment_key not in self._paysessions # FIXME |
|
|
|
|
assert payment_key not in self._paysessions |
|
|
|
|
self._paysessions[payment_key] = paysession = PaySession( |
|
|
|
|
payment_hash=payment_hash, |
|
|
|
|
payment_secret=payment_secret, |
|
|
|
|
@ -1429,6 +1438,7 @@ class LNWallet(LNWorker):
|
|
|
|
|
# when encountering trampoline forwarding difficulties in the legacy case, we |
|
|
|
|
# sometimes need to fall back to a single trampoline forwarder, at the expense |
|
|
|
|
# of privacy |
|
|
|
|
try: |
|
|
|
|
while True: |
|
|
|
|
if (amount_to_send := paysession.get_outstanding_amount_to_send()) > 0: |
|
|
|
|
# 1. create a set of routes for remaining amount. |
|
|
|
|
@ -1488,6 +1498,10 @@ class LNWallet(LNWorker):
|
|
|
|
|
else: |
|
|
|
|
self.handle_error_code_from_failed_htlc( |
|
|
|
|
route=route, sender_idx=sender_idx, failure_msg=failure_msg, amount=htlc_log.amount_msat) |
|
|
|
|
finally: |
|
|
|
|
paysession.is_active = False |
|
|
|
|
if paysession.can_be_deleted(): |
|
|
|
|
self._paysessions.pop(payment_key) |
|
|
|
|
|
|
|
|
|
async def pay_to_route( |
|
|
|
|
self, *, |
|
|
|
|
@ -2225,6 +2239,8 @@ class LNWallet(LNWorker):
|
|
|
|
|
amount_msat=shi.amount_receiver_msat, |
|
|
|
|
trampoline_fee_level=shi.trampoline_fee_level) |
|
|
|
|
q.put_nowait(htlc_log) |
|
|
|
|
if paysession.can_be_deleted(): |
|
|
|
|
self._paysessions.pop(payment_key) |
|
|
|
|
else: |
|
|
|
|
key = payment_hash.hex() |
|
|
|
|
self.set_invoice_status(key, PR_PAID) |
|
|
|
|
@ -2278,6 +2294,8 @@ class LNWallet(LNWorker):
|
|
|
|
|
sender_idx=sender_idx, |
|
|
|
|
trampoline_fee_level=shi.trampoline_fee_level) |
|
|
|
|
q.put_nowait(htlc_log) |
|
|
|
|
if paysession.can_be_deleted(): |
|
|
|
|
self._paysessions.pop(payment_okey) |
|
|
|
|
else: |
|
|
|
|
self.logger.info(f"received unknown htlc_failed, probably from previous session") |
|
|
|
|
key = payment_hash.hex() |
|
|
|
|
|