You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Turns out this it the only async -> sync -> (blocked) async inversion we have in ldk-sample, so making the traits async-optional (via some proc-macro?) would be really nice.
Turns out this it the only async -> sync -> (blocked) async inversion we have in ldk-sample,
I'm not quite sure this is true, due to ChangeDestinationSource being used in OutputSweeper's spending method which in turn is triggered by Confirm/Listen (and similar would hold for WalletSource, as the anchor spends are triggered by new best blocks?). So if we make the traits async-optional, we'd also need to propagate it up the chain syncing logic, including all the traits and connected methods, no?
I mean I'm all for more async-optional traits, but I'm not sure how we'd actually use async variants of ChangeDestinationSource/WalletSource in our code without introducing async contagion currently?
Grr, right. I suppose we could fix that with OutputSweeper having a fixed payout address (or a list) that is pre-configured if users want to avoid that inversion. Still seems worth doing?
Grr, right. I suppose we could fix that with OutputSweeper having a fixed payout address (or a list) that is pre-configured if users want to avoid that inversion. Still seems worth doing?
That sound pretty bad privacy-wise? There would really be no use doing #1139 and/or going out of our way to do something similar while making payment key recoverable, to then just sweep everything to the same address in the end?
Another approach to solve this for the OutputSweeper would be to trigger spending/rebroadcasting via the (already optionally-async) background processor rather than have it triggered by Filter/Confirm (which might be a good idea anyways, as more and more stuff piles onto block connection, and resulting deadlocks and/or performance spikes might get harder and harder to debug).
And I guess we for the other concerns we could make the BumpTransactionEventHandler and related traits async-optional as well (the latter via proc-macros via async_trait I guess, until our MSRV hits 1.75? Essentially simply re-doing and applying what we dropped during #3330?)?
Just discussed offline that we try to prioritize this for 0.2, i.e., making ChangeDestinationSource/WalletSource async-optional and have the sweeper and BumpTransactionEventHandler driven by the BackgroundProcessor.
After exploring optional asyncification and also (just for me) rust async in general, it seems that trying to do it all using macros isn't very pleasant.
There's the macro that duplicates and asyncifies all the 'async-contaminated' functions, similar to maybe_async. But also for example for the OutputSweeper itself that is dependent on ChangeDestinationSource, a macro would need to duplicate the whole struct with a different (async) parameter for the trait.
And then OutputSweeper is still relatively on the side. For other interfaces, the macros may end up duplicating large portions of LDK? ChannelManager has its own homebrewn callback mechanism, so that large part could probably avoid async duplication.
Also driving sweeping from the background processor just to be able to use it asynchronously seems like a workaround too, which may not be ideal either.
An alternative is to continue with the homebrewn callbacks for the wallet operations that this issue aims to make non-blocking. Need to see whether that introduces circular dependencies.
(mostly take aways from offline discussion with @TheBlueMatt)
Activity
tnull commentedon Jan 17, 2025
I'm not quite sure this is true, due to
ChangeDestinationSource
being used inOutputSweeper
's spending method which in turn is triggered byConfirm
/Listen
(and similar would hold forWalletSource
, as the anchor spends are triggered by new best blocks?). So if we make the traits async-optional, we'd also need to propagate it up the chain syncing logic, including all the traits and connected methods, no?I mean I'm all for more async-optional traits, but I'm not sure how we'd actually use async variants of
ChangeDestinationSource
/WalletSource
in our code without introducingasync
contagion currently?TheBlueMatt commentedon Jan 18, 2025
Grr, right. I suppose we could fix that with
OutputSweeper
having a fixed payout address (or a list) that is pre-configured if users want to avoid that inversion. Still seems worth doing?tnull commentedon Jan 20, 2025
That sound pretty bad privacy-wise? There would really be no use doing #1139 and/or going out of our way to do something similar while making payment key recoverable, to then just sweep everything to the same address in the end?
Another approach to solve this for the
OutputSweeper
would be to trigger spending/rebroadcasting via the (already optionally-async) background processor rather than have it triggered byFilter
/Confirm
(which might be a good idea anyways, as more and more stuff piles onto block connection, and resulting deadlocks and/or performance spikes might get harder and harder to debug).And I guess we for the other concerns we could make the
BumpTransactionEventHandler
and related traits async-optional as well (the latter via proc-macros viaasync_trait
I guess, until our MSRV hits 1.75? Essentially simply re-doing and applying what we dropped during #3330?)?tnull commentedon Feb 25, 2025
Just discussed offline that we try to prioritize this for 0.2, i.e., making
ChangeDestinationSource
/WalletSource
async-optional and have the sweeper andBumpTransactionEventHandler
driven by theBackgroundProcessor
.joostjager commentedon Apr 3, 2025
After exploring optional asyncification and also (just for me) rust async in general, it seems that trying to do it all using macros isn't very pleasant.
There's the macro that duplicates and asyncifies all the 'async-contaminated' functions, similar to
maybe_async
. But also for example for the OutputSweeper itself that is dependent onChangeDestinationSource
, a macro would need to duplicate the whole struct with a different (async) parameter for the trait.And then
OutputSweeper
is still relatively on the side. For other interfaces, the macros may end up duplicating large portions of LDK? ChannelManager has its own homebrewn callback mechanism, so that large part could probably avoid async duplication.Also driving sweeping from the background processor just to be able to use it asynchronously seems like a workaround too, which may not be ideal either.
An alternative is to continue with the homebrewn callbacks for the wallet operations that this issue aims to make non-blocking. Need to see whether that introduces circular dependencies.
(mostly take aways from offline discussion with @TheBlueMatt)
joostjager commentedon Apr 24, 2025
Update: went with the third option of providing sync-wrappers in #3734.