Skip to content

GetInfo blocks on synchronous LSPS2 fee params request; failed fetches are retried on every call #2545

Description

@rolznz

Problem

/api/info can take many seconds when the LSPS2 liquidity source (e.g. Megalith) is unreachable or rejects the request (LSPSResponseError). Observed in dev mode, where every info call blocks for seconds; the auto-unlock toggle appeared slow only because the settings screen awaits an info refetch after saving.

Cause

For the LDK backend, GetInfo (api/api.go) calls GetLiquiditySourceLsps2MinPaymentSizeMsat() / GetLiquiditySourceLsps2MaxPaymentSizeMsat(), which call fetchLsps2OpeningFeeParams (lnclient/ldk/ldk.go). That performs a synchronous RequestOpeningFeeParams() network round-trip to the LSP when the cache is stale, with several aggravating details:

  1. Failures are never cached — on error the function returns without setting lsps2InfoFetchedAt, so the 60-minute cache never becomes valid and every subsequent info call re-attempts the network request and blocks until it fails. useInfo(poll) polls /api/info every 3s on some screens, so a failing LSP is also hammered with doomed requests.
  2. The mutex is held across the network call — lsps2InfoMu is locked for the duration of RequestOpeningFeeParams(), so concurrent info calls serialize behind each other. The JIT invoice path (getLsps2MaxTotalOpeningFeeMsat) shares the same mutex, so invoice creation can queue behind a stuck info poll.
  3. The fetch happens even when JIT channels is disabled — the LSPS2 calls in GetInfo are gated only on the backend being LDK, not on the JitChannelsEnabled setting (which is only consulted at invoice creation). With JIT channels turned off, /api/info still triggers wasteful LSP network requests.

No issues reported from production so far (this only bites while the LSP is failing/unreachable), so this is not urgent — but during an LSP outage the whole UI would feel sluggish, since nearly every screen touches /api/info.

Possible fixes

  • Reconsider whether the LSPS2 min/max payment size data belongs in the info endpoint at all — /api/info is called constantly and should stay cheap; a dedicated endpoint (or the existing channel/liquidity endpoints) may be a better home.
  • Skip the LSPS2 fetch when JIT channels is disabled.
  • If it stays: record the attempt time on failure and apply a short retry backoff (e.g. 1 minute) so a failing LSP costs one slow request per backoff window instead of one per call.
  • Perform the network fetch outside the mutex (fetch first, then lock to store) so concurrent callers don't serialize.

🤖 Generated with Claude Code

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions