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

Separate ChannelDetails' outbound capacity from the next HTLC max #1435

Merged
merged 3 commits into from Apr 28, 2022

Conversation

TheBlueMatt
Copy link
Collaborator

@TheBlueMatt TheBlueMatt commented Apr 20, 2022

ChannelDetails::outbound_capacity_msat describes the total amount
available for sending across several HTLCs, basically just our
balance minus the reserve value maintained by our counterparty.
However, when routing we use it to guess the maximum amount we can
send in a single additional HTLC, which it is not.

There are numerous reasons why our balance may not match the amount
we can send in a single HTLC, whether the HTLC in-flight limit, the
channe's HTLC maximum, or our feerate buffer.

This commit splits the outbound_capacity_msat field into two -
outbound_capacity_msat and outbound_htlc_limit_msat, setting us
up for correctly handling our next-HTLC-limit in the future.

This also addresses the first of the reasons why the values may
not match - the max-in-flight limit. The inaccuracy is ultimately
tracked as #1126.

This is pulled out of #1434 and is really just enough of #1126 fixed so that we can do MPP tests more easily - because we default to a max in-flight limit of 10% of the channel size we need to consider the in-flight limit when routing so that we can really simply just ask the router to give us a route of, eg, 15 sats over two 100 sats channels and get back a valid route (currently it'll give us a route over one channel which will fail).

Also threw in a bonus cause we all like bonuses.

@codecov-commenter
Copy link

codecov-commenter commented Apr 20, 2022

Codecov Report

Merging #1435 (ad683d8) into main (637fb88) will increase coverage by 0.11%.
The diff coverage is 100.00%.

❗ Current head ad683d8 differs from pull request most recent head 61629bc. Consider uploading reports for the commit 61629bc to get more accurate results

@@            Coverage Diff             @@
##             main    #1435      +/-   ##
==========================================
+ Coverage   90.88%   91.00%   +0.11%     
==========================================
  Files          75       75              
  Lines       41474    42633    +1159     
  Branches    41474    42633    +1159     
==========================================
+ Hits        37695    38797    +1102     
- Misses       3779     3836      +57     
Impacted Files Coverage Δ
lightning/src/ln/channel.rs 88.42% <100.00%> (+<0.01%) ⬆️
lightning/src/ln/channelmanager.rs 85.45% <100.00%> (+0.72%) ⬆️
lightning/src/routing/router.rs 92.51% <100.00%> (-0.09%) ⬇️
lightning/src/util/events.rs 33.56% <100.00%> (ø)
lightning/src/chain/mod.rs 59.25% <0.00%> (-1.86%) ⬇️
lightning/src/routing/scoring.rs 94.00% <0.00%> (-0.36%) ⬇️
lightning-invoice/src/utils.rs 96.70% <0.00%> (-0.15%) ⬇️
lightning-background-processor/src/lib.rs 95.11% <0.00%> (-0.11%) ⬇️
lightning/src/ln/functional_tests.rs 97.08% <0.00%> (-0.07%) ⬇️
... and 5 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 637fb88...61629bc. Read the comment docs.

/// to use a limit as close as possible to the HTLC limit we can currently send.
///
/// See also [`ChannelDetails::balance_msat`] and [`ChannelDetails::outbound_capacity_msat`].
pub outbound_htlc_limit_msat: u64,
Copy link
Contributor

Choose a reason for hiding this comment

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

I think outbound_per_htlc_limit_msatwould be clearer, kinda reads as the limit for all htlcs otherwise

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Hmmm, per_htlc reads like a static limit on any HTLC, though, which this is not - its the limit for the next HTLC. Maybe I should add the word "next" again?

Copy link
Contributor

Choose a reason for hiding this comment

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

True. I'd prefer re-adding next

Comment on lines 2343 to 2345
let outbound_capacity_msat = cmp::max(self.value_to_self_msat as i64
- outbound_stats.pending_htlcs_value_msat as i64
- self.counterparty_selected_channel_reserve_satoshis.unwrap_or(0) as i64 * 1000,
Copy link
Contributor

Choose a reason for hiding this comment

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

Would this ever want to incorporate commit_tx_fee_msat (and/or the fee spike buffer)?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yes, it totally should! I have a WIP commit to do that but haven't had a chance to work on the tests.

lightning/src/ln/channel.rs Outdated Show resolved Hide resolved
lightning/src/routing/router.rs Show resolved Hide resolved
@TheBlueMatt
Copy link
Collaborator Author

Rebased and squashed with only conflicts fixed.

@valentinewallace
Copy link
Contributor

CI sad, will re-ack after that and another reviewer

`ChannelDetails::outbound_capacity_msat` describes the total amount
available for sending across several HTLCs, basically just our
balance minus the reserve value maintained by our counterparty.
However, when routing we use it to guess the maximum amount we can
send in a single additional HTLC, which it is not.

There are numerous reasons why our balance may not match the amount
we can send in a single HTLC, whether the HTLC in-flight limit, the
channe's HTLC maximum, or our feerate buffer.

This commit splits the `outbound_capacity_msat` field into two -
`outbound_capacity_msat` and `outbound_htlc_limit_msat`, setting us
up for correctly handling our next-HTLC-limit in the future.

This also addresses the first of the reasons why the values may
not match - the max-in-flight limit. The inaccuracy is ultimately
tracked as lightningdevkit#1126.
/// Doesn't bother handling the
/// if-we-removed-it-already-but-haven't-fully-resolved-they-can-still-send-an-inbound-HTLC
/// corner case properly.
/// The channel reserve is subtracted from each balance.
/// See also [`Channel::get_balance_msat`]
pub fn get_inbound_outbound_available_balance_msat(&self) -> (u64, u64) {
pub fn get_inbound_outbound_available_balance_msat(&self) -> (u64, u64, u64) {
Copy link
Contributor

Choose a reason for hiding this comment

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

this is getting a bit unwieldy. Tuples are great, but I think we may wanna introduce a custom response struct here with field labels.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Good idea! Went ahead and moved get_balance_msat into the same function while we're at it (and left it as a separate commit for that reason).

@valentinewallace
Copy link
Contributor

CI benchmark sad

@@ -62,6 +62,17 @@ pub struct ChannelValueStat {
pub counterparty_dust_limit_msat: u64,
}

pub struct AvailableBalance {
Copy link
Contributor

Choose a reason for hiding this comment

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

maybe AvailableBalances or AvailableBalanceBreakdown or something, because otherwise the naming is confusing.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Hmm, its not a breakdown, though, is it? They're separate "available balances" not really a breakdown of a "total available balance"

/// The channel reserve is subtracted from each balance.
/// See also [`Channel::get_balance_msat`]
pub fn get_inbound_outbound_available_balance_msat(&self) -> (u64, u64) {
pub fn get_available_balance_msat(&self) -> AvailableBalance {
Copy link
Contributor

Choose a reason for hiding this comment

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

same as above here

arik-so
arik-so previously approved these changes Apr 27, 2022
Copy link
Contributor

@arik-so arik-so left a comment

Choose a reason for hiding this comment

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

Re-ACKing

@TheBlueMatt
Copy link
Collaborator Author

Squashed the fixup commit without changes.

arik-so
arik-so previously approved these changes Apr 27, 2022
lightning/src/ln/channel.rs Outdated Show resolved Hide resolved
Some simple code motion to clean up how channel balances get
fetched.
@TheBlueMatt
Copy link
Collaborator Author

Lol, sorry, the old function docs were stale/wrong, I fixed them now....had to change the docs on the capacity fields:

diff --git a/lightning/src/ln/channel.rs b/lightning/src/ln/channel.rs
index 32478ee31..3a12a2c06 100644
--- a/lightning/src/ln/channel.rs
+++ b/lightning/src/ln/channel.rs
@@ -58,23 +58,23 @@ pub struct ChannelValueStat {
        pub pending_outbound_htlcs_amount_msat: u64,
        pub pending_inbound_htlcs_amount_msat: u64,
        pub holding_cell_outbound_amount_msat: u64,
        pub counterparty_max_htlc_value_in_flight_msat: u64, // outgoing
        pub counterparty_dust_limit_msat: u64,
 }
 
 pub struct AvailableBalances {
        /// The amount that would go to us if we close the channel, ignoring any on-chain fees.
        pub balance_msat: u64,
-       /// Total amount available for our counterparty to send to us, ignoring HTLCs.
+       /// Total amount available for our counterparty to send to us.
        pub inbound_capacity_msat: u64,
-       /// Total amount available for us to send to our counterparty, ignoring HTLCs.
+       /// Total amount available for us to send to our counterparty.
        pub outbound_capacity_msat: u64,
        /// The maximum value we can assign to the next outbound HTLC
        pub next_outbound_htlc_limit_msat: u64,
 }
 
 #[derive(Debug, Clone, Copy, PartialEq)]
 enum FeeUpdateState {
        // Inbound states mirroring InboundHTLCState
        RemoteAnnounced,
        AwaitingRemoteRevokeToAnnounce,

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.

None yet

4 participants