Skip to content
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

Fix comparison in get_dust_buffer_feerate #2971

Merged
merged 1 commit into from Apr 13, 2024

Conversation

jbesraa
Copy link
Contributor

@jbesraa jbesraa commented Mar 26, 2024

resolve #2815

We managed to fix the ChannelContext::get_dust_buffer_feerate implementation but the tests are still failing.

@jbesraa jbesraa changed the title [WIP] Review club/2815 [WIP] Fix comparison in get_dust_buffer_feerate Mar 26, 2024
@TheBlueMatt TheBlueMatt added this to the 0.0.122 milestone Mar 26, 2024
@TheBlueMatt
Copy link
Collaborator

Nice progress! Are you seeking help with the test changes here or just opening the WIP and will come back to it later this week?

@oleonardolima
Copy link

Nice progress! Are you seeking help with the test changes here or just opening the WIP and will come back to it later this week?

@TheBlueMatt We discussed during today's review-club session on leaving it open to anyone who would like to keep working on this, if nobody works on this we will revisit it on another session Thursday 28th [maybe?]

@oleonardolima
Copy link

oleonardolima commented Mar 27, 2024

--

@jbesraa I've not been able to solve the issue and the current failing test, but I did a little further investigation, here is broadly what I've discovered so far (in case someone also wants to move forward with this issue):

At least for now the failure that we are getting is:

node 0 ERROR [lightning::ln::channelmanager:3489] Got non-closing error: Cannot send less than our next-HTLC minimum - 2391000 msat

It happens here:

let available_balances = self.context.get_available_balances(fee_estimator);
if amount_msat < available_balances.next_outbound_htlc_minimum_msat {
return Err(ChannelError::Ignore(format!("Cannot send less than our next-HTLC minimum - {} msat",
available_balances.next_outbound_htlc_minimum_msat)));
}

It fails because we have amount_msat == 2390000 and the available_balances.next_outbound_htlc_minimum_msat == 2391000

I still need to grasp how/why the calculation for dust is done, both during the test setup and here at channel::get_available_balances

But, it got my attention that the comment also does follow the code on the test setup, why are we have a -1 on open_channel.common_fields.dust_limit_satoshis - 1 ?

Is there any spec or previous discussion that all this dust logic is based on?

let dust_outbound_htlc_on_holder_tx_msat: u64 = (dust_buffer_feerate * htlc_timeout_tx_weight(&channel_type_features) / 1000 + open_channel.common_fields.dust_limit_satoshis - 1) * 1000;
let dust_outbound_htlc_on_holder_tx: u64 = max_dust_htlc_exposure_msat / dust_outbound_htlc_on_holder_tx_msat;
let dust_inbound_htlc_on_holder_tx_msat: u64 = (dust_buffer_feerate * htlc_success_tx_weight(&channel_type_features) / 1000 + open_channel.common_fields.dust_limit_satoshis - 1) * 1000;
let dust_inbound_htlc_on_holder_tx: u64 = max_dust_htlc_exposure_msat / dust_inbound_htlc_on_holder_tx_msat;
let dust_htlc_on_counterparty_tx: u64 = 4;
let dust_htlc_on_counterparty_tx_msat: u64 = max_dust_htlc_exposure_msat / dust_htlc_on_counterparty_tx;
if on_holder_tx {
if dust_outbound_balance {
// Outbound dust threshold: 2223 sats (`dust_buffer_feerate` * HTLC_TIMEOUT_TX_WEIGHT / 1000 + holder's `dust_limit_satoshis`)
// Outbound dust balance: 4372 sats
// Note, we need sent payment to be above outbound dust threshold on counterparty_tx of 2132 sats
for _ in 0..dust_outbound_htlc_on_holder_tx {
let (route, payment_hash, _, payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[1], dust_outbound_htlc_on_holder_tx_msat);
nodes[0].node.send_payment_with_route(&route, payment_hash,
RecipientOnionFields::secret_only(payment_secret), PaymentId(payment_hash.0)).unwrap();
}

@jbesraa
Copy link
Contributor Author

jbesraa commented Mar 27, 2024

Regarding the tests, what they are trying to do is basically "exhaust" the channel and then make a payment that should fail. basically adding alot of dust htlc until we meet some threshold and then make a payment that is expected to fail.

I think the main thing to look into is that we fixed the dust_feerate calculation and now the fee_rate for dust htlc should be a bit higher, ie its not meeting the requirements of the assertion in the tests where we try to send a payment with an htlc below the minimum. so now the payment we send is valid but the tests expect it to be invalid.

regarding the dust calculation, I am not entirely sure about the - 1/ + 1 but the main thing I got from this is that we have the fee_rate that is multiplied in the htlc weight(success/timeout htlcs have different weights) and then added to some fee the user can be set in different occasions.

@jbesraa jbesraa marked this pull request as ready for review March 27, 2024 12:38
@jbesraa jbesraa changed the title [WIP] Fix comparison in get_dust_buffer_feerate Fix comparison in get_dust_buffer_feerate Mar 27, 2024
@codecov-commenter
Copy link

codecov-commenter commented Mar 27, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 90.02%. Comparing base (3a9fe20) to head (c01745e).
Report is 31 commits behind head on main.

❗ Your organization needs to install the Codecov GitHub app to enable full functionality.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2971      +/-   ##
==========================================
+ Coverage   89.33%   90.02%   +0.69%     
==========================================
  Files         117      117              
  Lines       95618    99768    +4150     
  Branches    95618    99768    +4150     
==========================================
+ Hits        85417    89817    +4400     
+ Misses       7952     7772     -180     
+ Partials     2249     2179      -70     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

MaxDustHTLCExposure::FeeRateMultiplier(5_000_000 / 253)
} else { MaxDustHTLCExposure::FixedLimitMsat(5_000_000) }; // initial default setting value
MaxDustHTLCExposure::FeeRateMultiplier(6_000_000 / 253)
} else { MaxDustHTLCExposure::FixedLimitMsat(6_000_000) }; // initial default setting value
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like you fixed the tests? Care to update the comment here describing the new value selected and revert later changes in the test?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated the comments and added how I did the calculations.
the 1500 here https://github.com/lightningdevkit/rust-lightning/pull/2971/files#diff-b30410f22a759d5e664e05938af7ef2edd244c8a7872e7ada376055ff130088bR9963 looks a bit off for me, is this the right calculation?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment doesn't really explain much for me? The update we made was adding 10 sat/vB, so reading the comment I'd guess we should actually be multiplying by 11 ((253 + 2530)/253). Can you add a bit more detail on what's going on?

@jbesraa jbesraa force-pushed the review-club/2815 branch 2 times, most recently from 97caa10 to 25ffe80 Compare March 28, 2024 08:43
MaxDustHTLCExposure::FeeRateMultiplier(5_000_000 / 253)
} else { MaxDustHTLCExposure::FixedLimitMsat(5_000_000) }; // initial default setting value
MaxDustHTLCExposure::FeeRateMultiplier(6_000_000 / 253)
} else { MaxDustHTLCExposure::FixedLimitMsat(6_000_000) }; // initial default setting value
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is definitely not the default setting value anymore :)

MaxDustHTLCExposure::FeeRateMultiplier(5_000_000 / 253)
} else { MaxDustHTLCExposure::FixedLimitMsat(5_000_000) }; // initial default setting value
MaxDustHTLCExposure::FeeRateMultiplier(6_000_000 / 253)
} else { MaxDustHTLCExposure::FixedLimitMsat(6_000_000) }; // initial default setting value
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment doesn't really explain much for me? The update we made was adding 10 sat/vB, so reading the comment I'd guess we should actually be multiplying by 11 ((253 + 2530)/253). Can you add a bit more detail on what's going on?

MaxDustHTLCExposure::FeeRateMultiplier(5_000_000 / 253)
} else { MaxDustHTLCExposure::FixedLimitMsat(5_000_000) }; // initial default setting value
// Default test fee estimator rate is 253 sat/kw. so we set the multiplier to 6_000_000 /
// 253 to accomdate 253 sat/kw plus an additional 2530 sat/kw for the dust buffer fee rate.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still not sure where you got this number? 6_000_000/253 is 23715, which is quite a ways from 253+2530 (2783).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How would write this?
What I am trying to get to here is that the default test fee rate is 253 and in the dust_buffer_feerate we add to that 10sats/vb (2530 kw) and thats why we set the multiple to this number so we can accommodate whats happening in the tests while reaching dust limits

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But that math doesn't work out? 253 + 2530 is not 6000000/253. Its not that this comment needs to be rewritten to be clearer, its that its currently completely wrong.

@@ -10054,12 +10053,12 @@ fn do_test_max_dust_htlc_exposure(dust_outbound_balance: bool, exposure_breach_e
fn do_test_max_dust_htlc_exposure_by_threshold_type(multiplier_dust_limit: bool) {
do_test_max_dust_htlc_exposure(true, ExposureEvent::AtHTLCForward, true, multiplier_dust_limit);
do_test_max_dust_htlc_exposure(false, ExposureEvent::AtHTLCForward, true, multiplier_dust_limit);
do_test_max_dust_htlc_exposure(false, ExposureEvent::AtHTLCForward, false, multiplier_dust_limit);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why move these around?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ordering by ExposureEvent type ...

@jbesraa
Copy link
Contributor Author

jbesraa commented Apr 8, 2024

@TheBlueMatt may I ask how 5_000_000 was initially calculated?

@TheBlueMatt
Copy link
Collaborator

TheBlueMatt commented Apr 8, 2024

It was a bit of a rough estimate of where we thought that constant made sense. I intend to change it for the 0.0.123 release as a part of #2922, however. I don't think that should impact the test, though? The point of the changes to the test is just to keep a consistent value vs what it was when the test was written, not really to have a "good" value.

Comment on lines 9891 to 9895
// Default test fee estimator rate is 253 sat/kw plus 2530
// sat/kw buffer added by `get_dust_buffer_feerate`, so we
// set the multiplier to 5_002_500 / 253 to get roughly
// the same initial value as the default setting when this
// test was originally written.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand this, can you clarify the math? 5_002_500 / 253 is 19k, not 2783?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

umm why do you expect it to be 2783? shouldn't our goal here be to calculate the multiplier to 2783?

My main motivation here was to raise the total dust limit taking into account the additional 1 sat/vb that is now added to the fee rate. The test below fills out the full dust capacity and then tries to route payments expecting them to fail but they were successful in some cases.
Maybe its getting tricky here because its not very clear to me how the initial 5_000_000 / 253 was decided on and passing the test ends up being fixing the numbers.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm expecting that based on your comment. I have no specific expectation for what it should be, but your comment seems to imply I should expect it to be 2783. Can you write the comment so the math checks out?

@@ -10032,7 +10034,7 @@ fn do_test_max_dust_htlc_exposure(dust_outbound_balance: bool, exposure_breach_e
// For the multiplier dust exposure limit, since it scales with feerate,
// we need to add a lot of HTLCs that will become dust at the new feerate
// to cross the threshold.
for _ in 0..20 {
for _ in 0..30 {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like this isn't needed anymore.

TheBlueMatt
TheBlueMatt previously approved these changes Apr 12, 2024
@@ -9950,7 +9950,7 @@ fn do_test_max_dust_htlc_exposure(dust_outbound_balance: bool, exposure_breach_e
let dust_outbound_htlc_on_holder_tx_msat: u64 = (dust_buffer_feerate * htlc_timeout_tx_weight(&channel_type_features) / 1000 + open_channel.common_fields.dust_limit_satoshis - 1) * 1000;
let dust_outbound_htlc_on_holder_tx: u64 = max_dust_htlc_exposure_msat / dust_outbound_htlc_on_holder_tx_msat;

let dust_inbound_htlc_on_holder_tx_msat: u64 = (dust_buffer_feerate * htlc_success_tx_weight(&channel_type_features) / 1000 + open_channel.common_fields.dust_limit_satoshis - 1) * 1000;
let dust_inbound_htlc_on_holder_tx_msat: u64 = (dust_buffer_feerate * htlc_success_tx_weight(&channel_type_features) / 1000 + open_channel.common_fields.dust_limit_satoshis - if multiplier_dust_limit { 3 } else { 2 }) * 1000;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we comment about the choice of these values?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a comment

  The current `cmp::max` doesnt align with the function comment, ie its
  comparing 2530 and `feerate_plus_quarter` instead of `feerate_per_kw
  + 2530` and `feerate_plus_quarter` which is fixed in this commit
@TheBlueMatt TheBlueMatt merged commit bc4a5ea into lightningdevkit:main Apr 13, 2024
15 of 16 checks passed
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.

Channel::get_dust_buffer_feerate comment doesn't match code
5 participants