Merge pull request #1996 from jerryfletcher21/cln-invoice-dropped-fix

cln fix invoice dropped that caused order stuck
This commit is contained in:
KoalaSat
2025-06-16 09:47:29 +00:00
committed by GitHub
3 changed files with 39 additions and 18 deletions

View File

@ -307,7 +307,7 @@ class CLNNode:
holdstub = hold_pb2_grpc.HoldStub(cls.hold_channel)
response = holdstub.HoldInvoiceLookup(request)
# Will fail if 'unable to locate invoice'. Happens if invoice expiry
# Will fail if 'empty result for listdatastore_state' or 'Invoice dropped from internal state unexpectedly'. Happens if invoice expiry
# time has passed (but these are 15% padded at the moment). Should catch it
# and report back that the invoice has expired (better robustness)
if response.state == hold_pb2.Holdstate.OPEN:
@ -361,7 +361,10 @@ class CLNNode:
# If it fails at finding the invoice: it has been expired for more than an hour (and could be paid or just expired).
# In RoboSats DB we make a distinction between cancelled and returned
# (holdinvoice plugin has separate state for hodl-invoices, which it forgets after an invoice expired more than an hour ago)
if "empty result for listdatastore_state" in str(e):
if (
"empty result for listdatastore_state" in str(e) or
"Invoice dropped from internal state unexpectedly" in str(e)
):
print(str(e))
request2 = node_pb2.ListinvoicesRequest(
payment_hash=bytes.fromhex(lnpayment.payment_hash)
@ -369,20 +372,20 @@ class CLNNode:
try:
nodestub = node_pb2_grpc.NodeStub(cls.node_channel)
response2 = nodestub.ListInvoices(request2).invoices
except Exception as e:
print(str(e))
if (
response2[0].status
== node_pb2.ListinvoicesInvoices.ListinvoicesInvoicesStatus.PAID
):
status = LNPayment.Status.SETLED
elif (
response2[0].status
== node_pb2.ListinvoicesInvoices.ListinvoicesInvoicesStatus.EXPIRED
):
status = LNPayment.Status.CANCEL
else:
if (
response2[0].status
== node_pb2.ListinvoicesInvoices.ListinvoicesInvoicesStatus.PAID
):
status = LNPayment.Status.SETLED
elif (
response2[0].status
== node_pb2.ListinvoicesInvoices.ListinvoicesInvoicesStatus.EXPIRED
):
status = LNPayment.Status.CANCEL
else:
print(str(e))
except Exception as e:
print(str(e))
# Other write to logs

View File

@ -353,7 +353,7 @@ class LNDNode:
status = LNPayment.Status.CANCEL
# LND restarted.
if "wallet locked, unlock it" in str(e):
elif "wallet locked, unlock it" in str(e):
print(str(timezone.now()) + " :: Wallet Locked")
# Other write to logs

View File

@ -2,11 +2,29 @@ import time
from django.core.management.base import BaseCommand
from django.utils import timezone
from decouple import config
from api.logics import Logics
from api.models import Order, TakeOrder
LNVENDOR = config("LNVENDOR", cast=str, default="LND")
def invoice_lookup_error(exc_string: str) -> bool:
if LNVENDOR == "LND":
if "unable to locate invoice" in exc_string:
return True
elif LNVENDOR == "CLN":
if (
"empty result for listdatastore_state" in exc_string or
"Invoice dropped from internal state unexpectedly" in exc_string
):
return True
return False
class Command(BaseCommand):
help = "Follows all active orders and make them expire if needed."
@ -57,7 +75,7 @@ class Command(BaseCommand):
debug["failed_order_expiry"].append({idx: context})
debug["reason_failure"].append({idx: str(e)})
if "unable to locate invoice" in str(e):
if invoice_lookup_error(str(e)):
self.stdout.write(str(e))
order.update_status(Order.Status.EXP)
debug["expired_orders"].append({idx: context})
@ -85,7 +103,7 @@ class Command(BaseCommand):
debug["failed_take_order_expiry"].append({idx: context})
debug["reason_take_failure"].append({idx: str(e)})
if "unable to locate invoice" in str(e):
if invoice_lookup_error(str(e)):
self.stdout.write(str(e))
debug["expired_take_orders"].append({idx: context})