-
Notifications
You must be signed in to change notification settings - Fork 366
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
Integrate BumpTransactionEventHandler into existing anchor tests #2403
Integrate BumpTransactionEventHandler into existing anchor tests #2403
Conversation
Codecov ReportPatch coverage:
❗ Your organization is not using the GitHub App Integration. As a result you may experience degraded service beginning May 15th. Please install the Github App Integration for your organization. Read more. Additional details and impacted files@@ Coverage Diff @@
## main #2403 +/- ##
==========================================
+ Coverage 90.26% 90.28% +0.02%
==========================================
Files 106 106
Lines 55188 55657 +469
Branches 55188 55657 +469
==========================================
+ Hits 49815 50251 +436
- Misses 5373 5406 +33
☔ View full report in Codecov by Sentry. |
Needs rebase now that #2393 landed. |
6e932b6
to
2c6ac88
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.
LGTM, mod @tnull's comments.
let conf_target = ConfirmationTarget::HighPriority; | ||
let package_target_feerate_sat_per_1000_weight = cached_request | ||
.compute_package_feerate(fee_estimator, conf_target, force_feerate_bump); | ||
if let Some(input_amount_sat) = output.funding_amount { |
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.
Hmmm, I think we should keep yielding commitment transaction even if they meet the sufficient feerate. A commitment transaction attached with a ConfirmationTarget::HighPriority
can be a hint you’re under pinning attacks or even that your transaction-relay eclipsed.
This information could be consumed by an anomalie detection module (Eclair has one for block-relay though I don’t know a Lightning implem which has one for transaction-relay, as it has been discussed in the past).
I would rather handle it back to the user and instead extend our documentation, or what do you think ? Is yielding a lot of ChannelClose
raising issues in term of higher-level API ?
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'm not sure how generating the events helps with that, though - we could have the same issue with anchors or non-anchors, and if you want to detect it you can do it at the transaction-broadcaster level. Most likely, the user has the events hooked into the BumpTransactionEventHandler
anyway, which doesn't have any such handling and we're back to square one.
If we want some kind of big warning that something isn't confirming when we expected it to, it needs to be a separate piece of logic that handles both anchor and non-anchor channels and exists independently.
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.
If the following comment can be added above ChannelClose
(alternatively a earliest_cltv_expiry
can be added in ChannelClose
generation in ChannelMonitor::get_repeated_events
though won’t be used for now).
diff --git a/lightning/src/events/bump_transaction.rs b/lightning/src/events/bump_transaction.rs
index cbd5becd..097e868b 100644
--- a/lightning/src/events/bump_transaction.rs
+++ b/lightning/src/events/bump_transaction.rs
@@ -262,6 +262,12 @@ pub enum BumpTransactionEvent {
/// for users to override LDK's behavior. On commitments with no HTLCs (indicated by those with
/// an empty `pending_htlcs`), confirmation of the commitment transaction can be considered to
/// be not urgent.
+ ///
+ /// Note if the commitment transaction has pending HTLC outputs that we can satisfies with valid
+ /// witnesses, the module responsible for broadcast should be ready to take corrective actions
+ /// if the local mempool is partitioned, or full-node transaction-relay capabilities tampered
+ /// by an eclipse attack. Those corrective actions should be take on the earliest `cltv_expiry`
+ /// of the set of pending htlcs.
///
/// [`EcdsaChannelSigner`]: crate::sign::EcdsaChannelSigner
/// [`EcdsaChannelSigner::sign_holder_anchor_input`]: crate::sign::EcdsaChannelSigner::sign_holder_anchor_input
If we want some kind of big warning that something isn't confirming when we expected it to, it needs to be a separate piece of logic that handles both anchor and non-anchor channels and exists independently.
Yeah I thought above that type of automatic anomalie detection logic in the past, see bitcoin/bitcoin#18987. Good if we start to document or indicate where can be the hooks points on our side, as probably you won’t have the same logic for mobile clients vs servers (or at the very least not the same reaction policy).
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.
Again, this isn't specific to anchor, and I don't see how its related to this PR. If you want to add a similar comment to the broadcaster (or, better, a much longer-form discussion of risks of transaction relay and the lightning security model relying on it) that would be very welcome, but I'm not sure why it has to be on the anchor-specific bumper?
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.
but I'm not sure why it has to be on the anchor-specific bumper?
The anomalie detection module should be based on the frequency of the anchor-specific bumper, as the “ideal" frequency should be the one of a confirmation in normal mempols propagation and the anomalie detection works compared from discrepancies of its “ideal”, so yeah to me changing the ChannelClose
announcement is a loss of relevant information.
All that said, we can move it elsewhere, let’s not invalidate the review so far.
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.
Why? It doesn't matter how many times we bump, we only get useful information once per block, so if you're trying to figure out if a transaction isn't getting confirmed, you only need to look once per block, since that's the only time your transaction can get confirmed :)
commitment_tx_fee_sat, commitment_tx.weight() as u64, | ||
); | ||
let anchor_target_feerate_sat_per_1000_weight = core::cmp::max( | ||
package_target_feerate_sat_per_1000_weight - commitment_tx_sat_per_1000_weight, |
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.
IIUC here we’re subtracting the commitment transaction feerate sat per 1000 weight from the anchor feerate sat per 1000 weight. If the commitment transaction is 10 times bigger than the child, the anchor feerate might not be sufficient to meet efficient propagation and selection in network mempools.
I think this should rather go to 1) compute the commitment transaction absolute fee with its current feerate, 2) compute the commitment transaction absolute fee with ConfirmationTarget::HighPriority
, 3) subtract result one from result two, 4) select enough UTXO value to meet the gap assuming some anchor transaction number of inputs (as it’s the variable, all other transaction fields are invariant).
So I understand the concern laid about “we don’t yet know the anchor transaction size” though I would rather go the direction of modifying select_confirmed_utxos
to take a satoshis_value_to_complete
and parameterize with per_additional_feerate_sat_per_1000_weight
.
Current state of code sounds to me we might propagate time-sensitive commitment transaction that broadcast feerate inefficient txn, like FEERATE_FLOOR_SATS_PER_KW
is only a belt-and-suspender for min_relay_tx_fee iirc.
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.
The must_spend set that we pass to the user has both the commitment transaction and the input as its satisfaction_weight - thus even if the commitment transaction is huge, its still considered in the counting of the anchor-spending transaction. We'll always overshoot using this math, but we won't overshoot by as much.
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.
thus even if the commitment transaction is huge,
In a world where an adversary can route update_add_htlc
over your node to inflate the size of your commitment transaction, I think we would be better to be careful to have precise bounds on how much we overshoot (and a drain vector on our fee-bumping reserves).
I think this would benefit to have a functional test to get in sync on the feerate math here, and the overshoot bounds.
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.
The total effective fee is the weight-weighted average of the feerates across the commitment and anchor transactions. Currently we simply ask the user to match the sought feerate, which may result in substantially under-shooting the sought feerate if the commitment transaction is large. You make a good point that overshooting may exhaust our available funds for anchoring, but I'd much rather that than substantially undershoot our fee estimator and end up not getting our transactions confirmed.
Luckily we don't overshoot by that much - we overshoot the desired feerate by commitment_fee / commitment_weight - commitment_fee / (commitment_weight + anchor_weight)
sat/vB [1]. Thus, if the commitment transaction is huge, we don't really overshoot at all. If the commitment transaction is tiny and it has a pretty high fee relative to how much we want to pay, we may overshoot by more, but I think at least in that scenario we're okay paying some more.
[1] math:
base definitions
- (_fr = fee rate, _f = fee, _w = weight)
- (com_ = commitment tx, anc_ = anchor tx)
- (actual = what we paid, sought = what we wanted to pay)
# the definition of actual feerate across the package
actual_fr = (com_f + anc_f) / (com_w + anc_w)
# the tx anchor fee, i.e. what we told the user to put on the anchor tx
anc_f = (sought_fr - (com_f / com_w)) * (com_w + anc_w)
# now sub second equasion into the first and simplify:
actual = (com_f + (sought_fr - (com_f / com_w)) * (com_w + anc_w)) / (com_w + anc_w)
actual_fr = com_f / (com_w + anc_w) + (sought_fr - (com_f / com_w)) * (com_w + anc_w)) / (com_w + anc_w)
actual_fr = com_f / (com_w + anc_w) + (sought_fr - (com_f / com_w))
actual_fr = com_f / (com_w + anc_w) + sought_fr - (com_f / com_w)
actual_fr - sought_fr = com_f / (com_w + anc_w) - (com_f / com_w)
sought_fr - actual_fr (i.e. how much we overpay, as a *rate*) = com_f / com_w - com_f / (com_w + anc_w)
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.
Currently we simply ask the user to match the sought feerate, which may result in substantially under-shooting the sought feerate if the commitment transaction is large.
This is correct from looking at code at (8e2b70d9
) neither current CoinSelectionSource::select_confirmed_utxos
’s target_feerate_sat_per_1000_weight
or BumpTransactionEventHandler::build_anchor_tx
document clearly what is included in their respective target_feerate_sat_per_1000_weight
from what I can grep. Note how it can be confusing as you have HTLCResolution::target_feerate_sat_per_1000_weight
and ChannelClose::package_target_feerate_per_1000_weight
.
So yes if you don’t include the commitment weight in your weight computation I agree you will undershoot and your transaction won’t propagate (fuck with all my respect for Wilmer hard work during the past year here, this API gently sucks in its current state for something which is safety critical).
You make a good point that overshooting may exhaust our available funds for anchoring, but I'd much rather that than substantially undershoot our fee estimator and end up not getting our transactions confirmed.
Well I observe again than fee-bumping reserves are supposed to be under your local LN node control though note the commitment weight is not due to how forwarding works (or at least unless in the bounds of your channel policy parameters…). I don’t know what is worst, this is depend the deployment.
Thanks for the math, I’ll argue the API suggested above with code-enforced bounds on the commitment weight is better, so now I'm thinking we might have to leak the channel policy parameters there in CoinSelectionSource
so I think conversation can be moved in its own issue / PR.
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.
This is correct from looking at code at (8e2b70d)
Oops, I'm sorry, I misspoke, we definitely don't undershoot today, but we substantially overshoot, and this change is making it so that we barely overshoot :).
fuck with all my respect for Wilmer hard work during the past year here, this API gently sucks in its current state for something which is safety critical
I'm sorry, what? The API is quite clear that you have to consider the satisfaction rate when you're building the transaction to meet the given weight. The naive user implementation works exactly correctly. More generally, please leave the insults elsewhere, there's no need for hostility here.
2c6ac88
to
922db51
Compare
Looks like the current code doesn't build. |
We plan to use these outside of the `bump_transaction` module in the next commit, and they really should belong in the same module as `FeeEstimator`.
There's no need to yield such an event when the commitment transaction already meets the target feerate on its own, so we can simply broadcast it without an anchor child transaction. This may be a common occurrence until we are less aggressive about feerate updates.
With anchors, we've yet to change the frequency or aggressiveness of feerate updates, so it's likely that commitment transactions have a good enough feerate to confirm on its own. In any case, when producing a child anchor transaction, we should already take into account the fees paid by the commitment transaction itself, allowing the user to save some satoshis. Unfortunately, in its current form, this will still result in overpaying by a small margin at the expense of making the coin selection API more complex.
This ensures our estimates are correct by never underestimating and only allowing overestimations by a margin of 1%.
This is a useful primitive to have that formats the contents of the iterator as a comma-separated list.
922db51
to
ff474ba
Compare
Squashed and switched the logger macro to use iterators instead:
|
See comment here #2403 (comment) it sounds to me a bit as a safety regression, at the very least it would be good to know our “worst-case overshoot bound” or see if my proposed method of computing feerate isn’t a better belt-and-suspender If the changes here are blocker for advance in |
Its not a regression if its better than the current code :). |
See my answer comment, this could be legendary bike-shedding in function of the deployment / channel policy parameters considered and so in function of those criterias, it might be a regression. Anyway anchor output is still beta for 0.0.116 and fee-bumping reserves management can be more focus in 0.0.117 to finally have a default sane anchor output API so I’m fine with it :) Reviewing the code again. |
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.
Code Review ACK 2c6ac88b
, comments are not blocking. Have not exercised the modified code paths to check accurate test coverage.
Feel free to address remaining comments in a followup. |
This PR integrates the
BumpTransactionEventHandler
into existing anchor tests to get some free coverage. Along the way, we address a few inefficiencies around bumping commitment transactions, add debug assertions for weight estimates, and improve logging within the event handler.Depends on #2393.