-
Notifications
You must be signed in to change notification settings - Fork 412
Async BumpTransactionEventHandler #3752
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
👋 Thanks for assigning @TheBlueMatt as a reviewer! |
d9b1c75
to
873516b
Compare
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #3752 +/- ##
==========================================
+ Coverage 89.92% 90.78% +0.86%
==========================================
Files 160 161 +1
Lines 129322 137021 +7699
Branches 129322 137021 +7699
==========================================
+ Hits 116290 124393 +8103
+ Misses 10345 9956 -389
+ Partials 2687 2672 -15 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
4b4b898
to
3816c66
Compare
1a86521
to
e1509f1
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did a first / quickish pass. Generally looks good so far.
lightning/Cargo.toml
Outdated
@@ -48,12 +48,14 @@ backtrace = { version = "0.3", optional = true } | |||
|
|||
libm = { version = "0.2", default-features = false } | |||
inventory = { version = "0.3", optional = true } | |||
tokio = { version = "1.35", features = [ "macros", "rt" ], optional = true } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please set default-features = false
here and below.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added. Why is this? I looked at the tokio crate and it seems there are no default features?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's 'best practice' and will also make sure we'd not add arbitrary dependencies if tokio
decided to add default features in some release.
*commitment_tx_fee_satoshis, | ||
anchor_descriptor, | ||
) { | ||
if let Err(_) = self |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMO these would be a bit more readable if we did the the whole call including .await
on a separate line and then simply did if res.is_err() { .. }
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tried it, but I don't think it is an improvement with that temp var.
let res = self
.handle_channel_close(
*claim_id,
*package_target_feerate_sat_per_1000_weight,
commitment_tx,
*commitment_tx_fee_satoshis,
anchor_descriptor,
)
.await;
if res.is_err() {
log_error!(
self.logger,
"Failed bumping commitment transaction fee for {}",
commitment_tx.compute_txid()
);
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also tried with map_err
, but that doesn't work all that well with the parent fn without a return result.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also tried with
map_err
, but that doesn't work all that well with the parent fn without a return result.
How about:
self.handle_channel_close(
*claim_id,
*package_target_feerate_sat_per_1000_weight,
commitment_tx,
*commitment_tx_fee_satoshis,
anchor_descriptor,
)
.await
.unwrap_or_else(|_| {
log_error!(
self.logger,
"Failed bumping commitment transaction fee for {}",
commitment_tx.compute_txid()
);
});
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah this is nicer. Wasn't aware of the unwrap_or_else on result. Updated.
lightning/src/ln/functional_tests.rs
Outdated
#[allow(clippy::expect_used, clippy::diverging_sub_expression)] | ||
{ | ||
return tokio::runtime::Builder::new_current_thread() | ||
.enable_all() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FWIW, I don't think we need to enable_all
here, could just actually enable features we need. Same goes for all the tests that use [tokio::test]
, although not sure if it makes a big difference in practice.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just expanded the macro. Can make customizations, but maybe it is better to keep to the original expansion? Also if it doesn't matter in practice...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, no strong opinion. If we increase the number of tests using tokio, we might want to some benchmarks though, as the runtime of cargo test
accumulates over time, so every second we can squeeze out of it would be appreciated.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed then. If we get more of these xtests, we might need to duplicate the macro or something like that.
let configs = [(false, false), (false, true), (true, false), (true, true)]; | ||
let mut last_err = None; | ||
for (force_conflicting_utxo_spend, tolerate_high_network_feerates) in configs { | ||
log_debug!( | ||
self.logger, | ||
"Attempting coin selection targeting {} sat/kW (force_conflicting_utxo_spend = {}, tolerate_high_network_feerates = {})", | ||
target_feerate_sat_per_1000_weight, | ||
force_conflicting_utxo_spend, | ||
tolerate_high_network_feerates | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: Indent off here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see the indent off. The closing parenthesis?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually the parenthesis and all arguments of log_debug
too (they need to be indented by one tab).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see the problem anymore in the diff now, but github still shows it on the old code fragment? In my IDE it all looks good with tabs, so I think it is solved.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, happened in the next commit. Fixed now.
👋 The first review has been submitted! Do you think this PR is ready for a second reviewer? If so, click here to assign a second reviewer. |
🔔 4th Reminder Hey @TheBlueMatt! This PR has been waiting for your review. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Excuse the delay here, finally got to testing this out with LDK Node.
One request for a minor change, otherwise it seems to work as expected with minmal changes (see https://github.com/tnull/ldk-node/tree/2025-02-upgrade-to-ldk-0.2-with-async-bumper)
fn list_confirmed_utxos<'a>(&'a self) -> AsyncResult<'a, Vec<Utxo>>; | ||
/// Returns a script to use for change above dust resulting from a successful coin selection | ||
/// attempt. | ||
fn get_change_script<'a>(&self) -> AsyncResult<'a, ScriptBuf>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a particular reason why we bound &'a self
for list_confirmed_utxos
but not for get_change_script
/ sign_psbt
? I should be able to work around this, but this simple diff would make my life considerably easier:
diff --git a/lightning/src/events/bump_transaction.rs b/lightning/src/events/bump_transaction.rs
index 8a3d3cb9b..98bd3525a 100644
--- a/lightning/src/events/bump_transaction.rs
+++ b/lightning/src/events/bump_transaction.rs
@@ -366,14 +366,14 @@ pub trait WalletSource {
fn list_confirmed_utxos<'a>(&'a self) -> AsyncResult<'a, Vec<Utxo>>;
/// Returns a script to use for change above dust resulting from a successful coin selection
/// attempt.
- fn get_change_script<'a>(&self) -> AsyncResult<'a, ScriptBuf>;
+ fn get_change_script<'a>(&'a self) -> AsyncResult<'a, ScriptBuf>;
/// Signs and provides the full [`TxIn::script_sig`] and [`TxIn::witness`] for all inputs within
/// the transaction known to the wallet (i.e., any provided via
/// [`WalletSource::list_confirmed_utxos`]).
///
/// If your wallet does not support signing PSBTs you can call `psbt.extract_tx()` to get the
/// unsigned transaction and then sign it with your wallet.
- fn sign_psbt<'a>(&self, psbt: Psbt) -> AsyncResult<'a, Transaction>;
+ fn sign_psbt<'a>(&'a self, psbt: Psbt) -> AsyncResult<'a, Transaction>;
}
/// A synchronous version of the [`WalletSource`] trait. Implementations of this trait should be wrapped in
@@ -420,7 +420,7 @@ where
/// Returns a script to use for change above dust resulting from a successful coin selection attempt. Wraps
/// [`WalletSourceSync::get_change_script`].
- fn get_change_script<'a>(&self) -> AsyncResult<'a, ScriptBuf> {
+ fn get_change_script<'a>(&'a self) -> AsyncResult<'a, ScriptBuf> {
let script = self.0.get_change_script();
Box::pin(async move { script })
}
@@ -428,7 +428,7 @@ where
/// Signs and provides the full [`TxIn::script_sig`] and [`TxIn::witness`] for all inputs within the transaction
/// known to the wallet (i.e., any provided via [`WalletSource::list_confirmed_utxos`]). Wraps
/// [`WalletSourceSync::sign_psbt`].
- fn sign_psbt<'a>(&self, psbt: Psbt) -> AsyncResult<'a, Transaction> {
+ fn sign_psbt<'a>(&'a self, psbt: Psbt) -> AsyncResult<'a, Transaction> {
let signed_psbt = self.0.sign_psbt(psbt);
Box::pin(async move { signed_psbt })
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I removed them because they weren't necessary. But seems better to stick with the same pattern everywhere. If we would have used async traits, they would also always expand to the same thing, I think.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I removed them because they weren't necessary. But seems better to stick with the same pattern everywhere. If we would have used async traits, they would also always expand to the same thing, I think.
Well, and just because they are not necessary in for the TestWalletSource
, it doesn't mean they aren't needed/helpful elsewhere.
🔔 5th Reminder Hey @TheBlueMatt! This PR has been waiting for your review. |
534ee90
to
4107b83
Compare
Looks good that code. I also found myself doing the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Two doc nits and one actual comment.
d8f4c67
to
462afa0
Compare
} | ||
} | ||
|
||
impl<W: Deref + MaybeSync + MaybeSend, L: Deref + MaybeSync + MaybeSend> CoinSelectionSource |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe we should instead implement CoinSelectionSourceSync
so that we can use BumpTransactionEventHandlerSync
, no?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh man, you are totally right. Now I can revert all the asyncification of the tests 😅
I will be back
It seems that the compiler doesn't recognize the drop and complains that the mutex crosses an await (introduced in later commit), even though it doesn't.
This preparatory commit converts do_coin_selection from a closure into a standard function.
462afa0
to
c34c042
Compare
@@ -1874,36 +1873,36 @@ impl Drop for TestScorer { | |||
|
|||
pub struct TestWalletSource { | |||
secret_key: SecretKey, | |||
utxos: RefCell<Vec<Utxo>>, | |||
utxos: Mutex<Vec<Utxo>>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Still need this in the sync code it seems, unfortunately.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if this is a show stopper for the whole sync wrapping concept. I hope not.
c34c042
to
d01009c
Compare
As already mentioned in #3752 (comment), a lot of the asyncification could be reverted now that the right wrappers are available. I also isolated the wrappers in their own file. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems CI is failing now.
d01009c
to
1892700
Compare
1892700
to
e7d43db
Compare
CI passes |
Reviewers, didn't do fix up commits as the commit structure changed substantially. Thanks for your patience with this PR. Should have realized that the sync wrappers could avoid all the test changes that have now been reverted. |
Converts
BumpTransactionEventHandler
to async.Changes the
CoinSelectionSource
andWalletSource
traits to be async and providesWalletSourceSyncWrapper
as a helper for users that want to implement a sync wallet source.TestWalletSource
is kept sync, to prevent a cascade of async conversions in tests.Fixes #3540