Skip to content

LSP panics on restart due to stale LSPS2 payment queue entries (duplicate intercept_id assertion) #4637

Description

@f3r10

Description:

Summary

After a clean restart of an ldk-node LSPS2 service node, the node panics when the next inbound HTLC arrives for a JIT channel. The panic is caused by a stale payment queue entry from the previous session whose intercept SCID is still being used by the client node.

Panic

thread 'tokio-rt-worker' panicked at
lightning-liquidity/src/lsps2/payment_queue.rs:36:13:
assertion failed: entry.htlcs.iter().all(|htlc| htlc.intercept_id != new_htlc.intercept_id)

This poisons the internal mutex, cascading into:

thread 'tokio-rt-worker' panicked at lightning-liquidity/src/lsps2/service.rs:1510:53:
called Result::unwrap() on an Err value: PoisonError { .. }

thread 'tokio-rt-worker' panicked at lightning-net-tokio/src/lib.rs:359:5:
assertion failed: e.is_cancelled()

After this the LSP is completely non-functional until restarted again (and the cycle repeats).

Root Cause

Two problems combine to produce this:

  1. The LSPS2 client (node-service) persists and reuses the intercept SCID after restart. receive_via_jit_channel stores its LSPS2 client state (including the assigned intercept SCID) in lightning_liquidity_state in SQLite. On restart, when a new invoice is requested, the client presents the same intercept SCID again via a new LSPS2 buy request.

  2. The LSPS2 service (lsp-service) persists its payment queue but never cleans up settled entries. The lightning_liquidity_state|lsps2_service|<peer_id> row survives restart with the old queue entry for the completed payment still present. When the same intercept SCID arrives again, payment_queue.rs:36 asserts uniqueness and panics.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions