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

@tnull tnull 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 thread benches/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 thread src/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 thread src/wallet/mod.rs Outdated
}
};

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

@benthecarman benthecarman Jun 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 thread src/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 thread src/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 thread src/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?

@joostjager joostjager 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 thread src/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 thread src/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!

@tnull tnull added this to the 0.9 milestone Jun 9, 2026
@tnull tnull 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 tnull force-pushed the 2026-06-async-kvstore-persistence-async-api branch from 6a3db1c to f58384d Compare June 9, 2026 12:31
@tnull

tnull commented Jun 9, 2026

Copy link
Copy Markdown
Collaborator Author

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

Sign up for free to 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