Skip to content

Add paginated payment listing API#959

Open
benthecarman wants to merge 1 commit into
lightningdevkit:mainfrom
benthecarman:paginated-payments
Open

Add paginated payment listing API#959
benthecarman wants to merge 1 commit into
lightningdevkit:mainfrom
benthecarman:paginated-payments

Conversation

@benthecarman

Copy link
Copy Markdown
Contributor

Add DataStore::list_page, returning one page of stored objects in reverse creation order together with a token to fetch the next page. Reads within a page are spawned concurrently, and keys removed between listing and reading are skipped rather than failing the page.

Expose this via a new Node::list_payments_paginated method along with bindings support for PageToken and PaymentDetailsPage, allowing users to retrieve payments page-by-page instead of copying the entire payment history across the FFI boundary at once.

@benthecarman benthecarman requested a review from tnull July 2, 2026 04:18
@ldk-reviews-bot

ldk-reviews-bot commented Jul 2, 2026

Copy link
Copy Markdown

👋 Thanks for assigning @tnull as a reviewer!
I'll wait for their review and will help manage the review process.
Once they submit their review, I'll check if a second reviewer would be helpful.

@tnull tnull left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Few questions on the general approach / general direction going forward.

Comment thread src/ffi/types.rs Outdated
Comment thread src/lib.rs Outdated
/// Pass `None` to start listing from the most recently created payment. If the returned
/// [`PaymentDetailsPage::next_page_token`] is `Some`, pass it to a subsequent call to
/// retrieve the next page.
pub fn list_payments_paginated(

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, do we really want an additional method? At some point (hopefully for v0.9) we'll stop keeping all entries in memory and at that point at the latest the current shape of list_payments isn't feasible anymore. So should this just replace list_payments? Or not yet?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah didn't originally because of the second point but changed here to now replace the normal list_payments

Comment thread src/data_store.rs
pub(crate) async fn list_page(
&self, page_token: Option<PageToken>,
) -> Result<(Vec<SO>, Option<PageToken>), Error> {
let response = PaginatedKVStore::list_paginated(

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently, we're still leaning on all DataStore entries being kept in memory everywhere else (which we should change soon as mentioned above). So right now it's a bit odd to have the paginated version being the only one calling through to KVStore, and not even using any cache (so it's likely pretty slow).

So, should this just use the in-memory entries? If not, we could consider already making the jump to not keep all entries in memory, but then we'd need some (presumably LRU?) caching logic for DataStore first, before we add pagination support/switch it to use pagination?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed to just use in memory entries. Changing to not keep everything in memory would be a separate PR and maybe should wait for 0.9 as we have a lot of in flight storage changes right now.

Comment thread src/data_store.rs Outdated
let mut spawn_iter = response.keys.iter();
let mut read_handles = VecDeque::with_capacity(DATA_STORE_READ_CONCURRENCY_LIMIT);
for key in spawn_iter.by_ref().take(DATA_STORE_READ_CONCURRENCY_LIMIT) {
read_handles.push_back(tokio::spawn(KVStore::read(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Drive-by question: are there plans for something like list_paginated_values, so SQL backends can fetch a page of serialized values in a single query instead of doing list_paginated plus one read per key?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like a follow-up optimization that could eventually make sense (though, maybe even worth benchmarking if necessary for the concrete use cases). Mind opening an issue for it so we don't forget to revisit?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Replace the full payment listing API with paginated listing so callers
can migrate away from fetching every payment at once. Deprecate the
filtering helper because it still implies scanning the full in-memory
store.
@benthecarman

Copy link
Copy Markdown
Contributor Author

Changed to continue using the in memory entires in the DataStore. One note on this, codex suggested to make list_payments_with_filter deprecated because now this doesn't really work with pagination. To really support this in the future we'd need to keep everything in memory or make our KV Store api more SQL based.

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

Labels

None yet

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

4 participants