Skip to content

Make the API async where needed, avoid block_on - #926

Draft
tnull wants to merge 5 commits into
lightningdevkit:mainfrom
tnull:2026-06-async-kvstore-persistence-async-api
Draft

Make the API async where needed, avoid block_on#926
tnull wants to merge 5 commits into
lightningdevkit:mainfrom
tnull:2026-06-async-kvstore-persistence-async-api

Conversation

@tnull

@tnulltnull commented Jun 8, 2026

Copy link
Copy Markdown
Collaborator

Based on #919.

WIP

@ldk-reviews-bot

ldk-reviews-bot commented Jun 8, 2026

Copy link
Copy Markdown

👋 Hi! This PR is now in draft status.
I'll wait to assign reviewers until you mark it as ready for review.
Just convert it out of draft status when you're ready for review!

@tnull
tnull marked this pull request as draft June 8, 2026 16:45
Comment threadbenches/payments.rs
node_b.node_id(),
preimage,
None,
);

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.

await should be here

Comment threadsrc/payment/bolt11.rs

let liquidity_source = Arc::clone(&liquidity_source);
let invoice = self.runtime.block_on(async move {
let invoice = async move {

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.

do we still need this async move?

Comment threadsrc/wallet/mod.rs Outdated
}
};

if let Err(e) = self.runtime.block_on(self.update_payment_store(events)) {

@benthecarmanbenthecarmanJun 8, 2026

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.

do we need an async version of these traits in LDK?

Comment threadsrc/wallet/mod.rs
let wallet = self.clone();
let runtime = Arc::clone(&self.runtime);
let logger = Arc::clone(&self.logger);
runtime.spawn_background_task(async move {

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.

this seems dangerous to not return an error if persists fails. Idk if we can really get around it though

Comment threadsrc/lib.rs
let logger = Arc::clone(&listening_logger);
let listening_addrs = listening_addresses.clone();
let listeners = self.runtime.block_on(async move {
let listeners = async move {

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.

dont really need this async move

Comment threadsrc/lib.rs
return Err(Error::NotRunning);
pub async fn stop(&self) -> Result<(), Error> {
{
let mut is_running_lock = self.is_running.write().expect("lock");

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.

should we still be using a sync lock for is_running?

@joostjagerjoostjager left a comment

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.

This looks great. But please don't finalize this as a single big PR, but do it incrementally instead.

Comment threadsrc/wallet/mod.rs
Ok(tx)
fn get_new_address_sync(&self) -> bitcoin::Address {
let address = self.get_new_address_inner();
self.spawn_persist_wallet();

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.

Is it safe, return before persist?

Comment threadsrc/runtime.rs
handle.spawn_blocking(func)
}

pub fn block_on<F: Future>(&self, future: F) -> F::Output {

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.

Yes!

@tnulltnull added this to the 0.9 milestone Jun 9, 2026
@tnulltnull mentioned this pull request Jun 9, 2026
9 tasks
tnull added 5 commits June 9, 2026 14:29
Avoid nested runtime waits when peer, payment, and node metrics operations persist through async storage. This lets callers already in async contexts await those operations directly while keeping existing sync boundaries explicit.
Co-Authored-By: HAL 9000
Resolve VSS schema setup through async initialization on the caller runtime so VSS stores no longer create or retain a Tokio runtime.
Co-Authored-By: HAL 9000
Construct PostgreSQL storage on the caller runtime now that store-backed APIs are async, removing the store-owned runtime and shutdown path.
Co-Authored-By: HAL 9000
Expose startup, shutdown, builder, wallet, liquidity, and bindings entrypoints as async so store-backed persistence no longer needs local synchronous future driving. Update tests and benches to await the async surface and keep store persistence helpers on the async storage path.
Co-Authored-By: HAL 9000
Describe the Tokio runtime expectations for LDK Node callers so async API users know when runtime handles are reused and why runtime worker threads must remain available for node progress.
Co-Authored-By: HAL 9000
@tnull
tnullforce-pushed the 2026-06-async-kvstore-persistence-async-api branch from 6a3db1c to f58384dCompareJune 9, 2026 12:31
@tnull

tnull commented Jun 9, 2026

Copy link
Copy Markdown
CollaboratorAuthor

Rebased after #919 landed, though we'll probably wait with moving this forward until after we branched-off for v0.8.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@tnull@ldk-reviews-bot@joostjager@benthecarman