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.

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.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@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
},
});

uniffi::custom_type!(PageToken, String, {

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.

Can we use the remote type rather than adding a custom type (as we try to get rid of the latter over time)?

Comment thread src/lib.rs
/// 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?

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?

Comment thread src/data_store.rs
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.

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