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

invoices+sqldb/sqlc: replace offset-based pagination with cursor-based

Public commit record

What the developer wrote

Authored by ziggie

85/100 · Strong
invoices+sqldb/sqlc: replace offset-based pagination with cursor-based

The invoice filter queries (FetchPendingInvoices,
FilterInvoicesBySettleIndex, FilterInvoicesByAddIndex,
FilterInvoicesForward, FilterInvoicesReverse) all used LIMIT+OFFSET for
internal pagination. This causes SQLite to build an ephemeral temp
B-tree for every page to implement the OFFSET skip, making each
successive page O(offset+limit). On nodes with large invoice histories
this compounds into a significant CPU cost — profiling showed
FilterInvoicesReverse consuming 53% of total CPU, with _sqlite3BtreeInsert
and _balance_nonroot (2.4s combined) appearing inside the SELECT due to
the temp B-tree being built and rebalanced to skip rows.

Replace the OFFSET loop (queryWithLimit) with cursor-based pagination
across all four callers in sql_store.go:

- FetchPendingInvoices: add id_cursor param, advance cursor to
last_id + 1 each page.
- InvoicesSettledSince: add id_cursor param alongside the existing
settle_index lower bound, advance cursor to last_id + 1 each page.
- InvoicesAddedSince: cursor starts at idx+1, advances to last_id+1.
- QueryInvoices: forward cursor starts at IndexOffset+1 and advances
by +1; reverse cursor starts at IndexOffset-1 (or MaxInt64) and
advances by -1. Inclusive SQL bounds (>= / <=) are preserved so
query semantics and all existing callers are unchanged.

The queryWithLimit helper is removed as it has no remaining callers.

Each page now performs a single PK seek + forward scan of exactly
page_size rows with no temp sort structure, matching the cursor-based
pattern already used by the payments filter queries.
✓ 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 replaces slow database pagination that skipped rows using OFFSET with faster cursor-based pagination using primary-key ranges. On nodes with very large invoice histories this can dramatically reduce CPU usage and query time, but it does not close any vulnerability that an attacker could exploit.

Recommended action

Treat as a routine performance improvement. No security response is required, but operators with large invoice databases should benefit from lower CPU usage after upgrading.

Security signals we found

No strong security signals were identified.

Risk score

Why this scored 27/100

Our methodology →
Potential impact 5/30
Exploitability 0/25
Stealth signal 0/15
Affected reach 10/15
Confidence 8/10
Evidence quality 4/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.