Skip to content

bug: restored wallet pays a spark-paid invoice again over channels #1855

Closed

Description

@ovitrif

Behaviour

After a wallet restore, an unexpired invoice that Spark already paid can be paid again over the channels before Spark's first successful sync.

  • The check that refuses a channel payment Spark already made (SparkRepo.kt:906) falls back to the locally saved Spark send hashes while Spark's history is unavailable.
  • A restore brings back metadata from the backup, which can lack sends made after that backup was taken.
  • So for such an invoice the check finds no earlier send, and LightningRepo.payInvoiceWithLdk dispatches it again over usable channels. The payee, or any hop, already knows the preimage.

The node side has the same gap in reverse: a restore copies ldkSendHashesSeeded = true with the old device's hash set (BackupRepo.kt:1203-1204), so while the node isn't running earlierNodeSend (LightningRepo.kt:1585-1596) trusts a stale list and Spark could pay what the node already paid.

Found by

@pwltr in a post-merge review of #1697: #1697 (review)

Duplicate dispatch follows from the code; a duplicate settlement has not been reproduced.

Scope

  • Installs that never restored are not affected: every Spark Lightning send saves its hash before dispatch (SparkRepo.kt:311), and no released build sent over Spark.
  • Fix: while history is unseeded after a restore, refuse only invoices dated before the restore, on both sides, until Spark or the node lists its sends.

Activity

  1. added this to the 3.2.0 milestone on Nov 11, 2026
  2. self-assigned this
    on Nov 11, 2026
  3. changed the title [-]fix: restored wallet can pay a spark-paid invoice again over channels[/-] [+]bug: restored wallet pays a spark-paid invoice again over channels[/+] on Nov 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions