-
Notifications
You must be signed in to change notification settings - Fork 382
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
Add deadline height to UrgentOnChainSweep #3563
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -61,7 +61,9 @@ pub enum ConfirmationTarget { | |
/// Generally we have in the high tens to low hundreds of blocks to get our transaction | ||
/// on-chain (it doesn't have to happen in the next few blocks!), but we shouldn't risk too low | ||
/// a fee - this should be a relatively high priority feerate. | ||
UrgentOnChainSweep, | ||
/// | ||
/// If a target confirmation delta is known, it can be set as the parameter. | ||
UrgentOnChainSweep(Option<u32>), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't buy that we need an |
||
/// This is the lowest feerate we will allow our channel counterparty to have in an anchor | ||
/// channel in order to close the channel if a channel party goes away. | ||
/// | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm a bit concerned about performance here, as well as whether setting the CLTV expiry itself as the deadline is prudent, or if it should be offset by some constant value. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In most cases, you'll find the same HTLCs across the commitments, so we could just have a single set/vec to filter out duplicates. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We need to be careful about the deadlines. Since we often need to get 2 transactions confirmed to claim HTLCs (commitment + HTLC claim), we can't always just set the deadline to the CLTV expiry. Ideally I'd suggest something like:
This wouldn't work properly with the current logic, since Alternatively we could choose a fixed delta to subtract from CLTV expiry for the commitment deadline, but that seems less clean IMO. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wonder if the cleanest way to accomplish this is by having this method return a tuple instead of a single confirmation target enum variant, or if we should break this up into commitment and HTLC conf target methods. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe we just have two different variants - a "we need to get this confirmed by X" and a "we need to get two transactions confirmed by X" variant? Seems to communicate it all to the user and we can let them figure it out. |
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -2743,22 +2743,47 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> { | |||||||||||||||||||||
fn closure_conf_target(&self) -> ConfirmationTarget { | ||||||||||||||||||||||
// Treat the sweep as urgent as long as there is at least one HTLC which is pending on a | ||||||||||||||||||||||
// valid commitment transaction. | ||||||||||||||||||||||
let mut minimum_expiry = None; | ||||||||||||||||||||||
let update_minimum_expiry = |local_minimum: Option<u32>, global_minimum: &mut Option<u32>| { | ||||||||||||||||||||||
if let Some(expiry) = local_minimum { | ||||||||||||||||||||||
*global_minimum = Some(global_minimum.map_or(expiry, |m| cmp::min(expiry, m))); | ||||||||||||||||||||||
} | ||||||||||||||||||||||
}; | ||||||||||||||||||||||
Comment on lines
+2747
to
+2751
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit: I think the following refactor is more readable:
Suggested change
|
||||||||||||||||||||||
|
||||||||||||||||||||||
if !self.current_holder_commitment_tx.htlc_outputs.is_empty() { | ||||||||||||||||||||||
return ConfirmationTarget::UrgentOnChainSweep; | ||||||||||||||||||||||
let local_minimum_expiry = self.current_holder_commitment_tx.htlc_outputs | ||||||||||||||||||||||
.iter() | ||||||||||||||||||||||
.map(|o| o.0.cltv_expiry) | ||||||||||||||||||||||
.min(); | ||||||||||||||||||||||
update_minimum_expiry(local_minimum_expiry, &mut minimum_expiry); | ||||||||||||||||||||||
} | ||||||||||||||||||||||
if self.prev_holder_signed_commitment_tx.as_ref().map(|t| !t.htlc_outputs.is_empty()).unwrap_or(false) { | ||||||||||||||||||||||
return ConfirmationTarget::UrgentOnChainSweep; | ||||||||||||||||||||||
let local_minimum_expiry = self.prev_holder_signed_commitment_tx.as_ref().map(|t| t.htlc_outputs | ||||||||||||||||||||||
.iter() | ||||||||||||||||||||||
.map(|o| o.0.cltv_expiry) | ||||||||||||||||||||||
.min() | ||||||||||||||||||||||
).flatten(); | ||||||||||||||||||||||
update_minimum_expiry(local_minimum_expiry, &mut minimum_expiry); | ||||||||||||||||||||||
} | ||||||||||||||||||||||
if let Some(txid) = self.current_counterparty_commitment_txid { | ||||||||||||||||||||||
if !self.counterparty_claimable_outpoints.get(&txid).unwrap().is_empty() { | ||||||||||||||||||||||
return ConfirmationTarget::UrgentOnChainSweep; | ||||||||||||||||||||||
let claimable_outpoints = self.counterparty_claimable_outpoints.get(&txid).unwrap(); | ||||||||||||||||||||||
if !claimable_outpoints.is_empty() { | ||||||||||||||||||||||
let local_minimum_expiry = claimable_outpoints.iter().map(|o|o.0.cltv_expiry).min(); | ||||||||||||||||||||||
update_minimum_expiry(local_minimum_expiry, &mut minimum_expiry); | ||||||||||||||||||||||
} | ||||||||||||||||||||||
} | ||||||||||||||||||||||
if let Some(txid) = self.prev_counterparty_commitment_txid { | ||||||||||||||||||||||
if !self.counterparty_claimable_outpoints.get(&txid).unwrap().is_empty() { | ||||||||||||||||||||||
return ConfirmationTarget::UrgentOnChainSweep; | ||||||||||||||||||||||
let claimable_outpoints = self.counterparty_claimable_outpoints.get(&txid).unwrap(); | ||||||||||||||||||||||
if !claimable_outpoints.is_empty() { | ||||||||||||||||||||||
let local_minimum_expiry = claimable_outpoints.iter().map(|o|o.0.cltv_expiry).min(); | ||||||||||||||||||||||
update_minimum_expiry(local_minimum_expiry, &mut minimum_expiry); | ||||||||||||||||||||||
} | ||||||||||||||||||||||
} | ||||||||||||||||||||||
|
||||||||||||||||||||||
if let Some(global_minimum) = minimum_expiry { | ||||||||||||||||||||||
return ConfirmationTarget::UrgentOnChainSweep(Some(global_minimum)) | ||||||||||||||||||||||
} | ||||||||||||||||||||||
|
||||||||||||||||||||||
ConfirmationTarget::OutputSpendingFee | ||||||||||||||||||||||
} | ||||||||||||||||||||||
|
||||||||||||||||||||||
|
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.
Fee estimation is usually based on deltas (and the docs above even point to such).
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, I think I misinterpreted the target time in the issue. Will adjust