AI-generated analysisPublished automatically and not human-verified. Validated context appears in community notes below.
← Watch feed
Informational 19 Bitcoin

wallet: cache paid-invoice keys to avoid prevout rescan

Public commit record

What the developer wrote

Authored by Sasha Zykov

85/100 · Strong
wallet: cache paid-invoice keys to avoid prevout rescan

On wallets with many outgoing invoices that share output scriptpubkeys,
broadcasting a new transaction froze the GUI for several seconds — up
to a minute on bigger wallets. The hot loops in set_broadcasting() and
_update_onchain_invoice_paid_detection() iterate every invoice touched
by the new tx's outputs, which is large when scriptpubkeys are shared
via _invoices_from_scriptpubkey_map. For each touched invoice they call
_is_onchain_invoice_paid(), which scans all of the invoice's output
scripthashes against _prevouts_by_scripthash and does a get_tx_height
per prevout. Both inner dimensions blow up together when invoices share
inputs/outputs across many past payments.

Add _paid_invoice_keys: Set[str], an in-memory cache of outgoing
invoice ids known to be PR_PAID, maintained incrementally:

- populated at wallet load by _prepare_onchain_invoice_paid_detection
- updated in _update_onchain_invoice_paid_detection (discard then
recompute, so reorgs still demote PAID->UNPAID)
- updated in save_invoice, delete_invoice, clear_invoices
- new on_event_invoice_status listener keeps it in sync with
LN-driven transitions from LNWallet.set_invoice_status

get_invoice_status() short-circuits to PR_PAID on cache hit, skipping
the prevout scan. set_broadcasting() skips already-paid invoices
entirely — broadcasting_status has no effect on a paid invoice and the
callback churn is what made the GUI freeze.
✓ Specific, descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context✓ Explains rationale or failure mode
The short version

What changed, and why it matters

This commit is a performance optimization, not a security fix. It adds an in-memory cache of which outgoing invoices are already paid, so Electrum can skip expensive re-scanning of previous transaction outputs when many invoices share the same Bitcoin address. The goal is to stop the user interface from freezing for seconds or minutes when broadcasting a transaction. There is no indication this change fixes a vulnerability or changes security-critical behavior beyond making status lookups faster.

Recommended action

No security action required. Treat as a normal performance improvement. Reviewers may want to confirm that all cache-invalidation paths (reorg, history clear, LN status transitions, invoice deletion) are covered, which the included tests appear to do.

Security signals we found

01

No security-relevant signal: the change is a performance optimization with explicit cache-invalidation paths for reorgs and history clears.

02

Cache consistency is maintained across save_invoice, delete_invoice, clear_invoices, clear_history, and LN-driven invoice_status events.

03

Tests verify that reorgs and clear_history correctly demote cached PR_PAID status, reducing risk of stale-state bugs.

Risk score

Why this scored 19/100

Our methodology →
Potential impact 0/30
Exploitability 0/25
Stealth signal 0/15
Affected reach 5/15
Confidence 9/10
Evidence quality 5/5
Human-validated context

Community notes

Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.

No validated notes yet.

The AI analysis stands alone for now. Submit a note if you can add evidence or important context.