Skip to content

Allow forwarding less than the amount in the onion - #2319

Merged
tnull merged 12 commits into
lightningdevkit:mainfrom
valentinewallace:2023-05-forward-less-than-onion
Jun 21, 2023
Merged

Allow forwarding less than the amount in the onion #2319
tnull merged 12 commits into
lightningdevkit:mainfrom
valentinewallace:2023-05-forward-less-than-onion

Conversation

@valentinewallace

@valentinewallacevalentinewallace commented May 25, 2023

Copy link
Copy Markdown
Contributor

Support skimming an additional fee off of intercepted HTLCs, per lightning/blips#25.

V1 of addressing #1999
Based on #2305

@valentinewallace
valentinewallaceforce-pushed the 2023-05-forward-less-than-onion branch from ad259dd to 2a07438CompareMay 25, 2023 18:49
@codecov-commenter

codecov-commenter commented May 25, 2023

Copy link
Copy Markdown

Codecov Report

Patch coverage: 90.61% and project coverage change: +0.15 🎉

Comparison is base (ae9e96e) 90.35% compared to head (2127eb8) 90.50%.

❗ 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 #2319 +/- ##
==========================================
+ Coverage 90.35% 90.50% +0.15% 
==========================================
Files 106 106 Lines 54347 59105 +4758 Branches 54347 59105 +4758 ==========================================
+ Hits 49105 53494 +4389 - Misses 5242 5611 +369 
Impacted FilesCoverage Δ
lightning/src/ln/functional_tests.rs98.34% <ø> (+0.11%)⬆️
lightning/src/ln/channel.rs89.49% <57.89%> (-0.33%)⬇️
lightning/src/events/mod.rs43.58% <90.00%> (+2.17%)⬆️
lightning/src/ln/channelmanager.rs87.79% <94.07%> (+1.21%)⬆️
lightning/src/ln/payment_tests.rs97.66% <98.79%> (+0.04%)⬆️
lightning/src/ln/functional_test_utils.rs87.63% <100.00%> (+0.34%)⬆️
lightning/src/ln/msgs.rs84.59% <100.00%> (+0.01%)⬆️
lightning/src/util/config.rs57.47% <100.00%> (-0.18%)⬇️

... and 11 files with indirect coverage changes

☔ View full report in Codecov by Sentry.
📢 Do you have feedback about the report comment? Let us know in this issue.

@wpaulinowpaulino added this to the 0.0.116 milestone May 25, 2023

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

At first glance this basically looks good I think.

Comment threadlightning/src/ln/channelmanager.rs Outdated
Comment threadlightning/src/ln/channelmanager.rs Outdated
@dunxen
dunxen self-requested a review June 4, 2023 20:24
@valentinewallace
valentinewallaceforce-pushed the 2023-05-forward-less-than-onion branch from 2a07438 to a1cbf67CompareJune 8, 2023 14:18
@valentinewallace
valentinewallace marked this pull request as ready for review June 8, 2023 14:21
@valentinewallace

valentinewallace commented Jun 8, 2023

Copy link
Copy Markdown
ContributorAuthor

I removed phantom support for now. Also noticed that this breaks compat for current users of UserConfig::accept_intercept_htlcs. Not sure if a release note is sufficient so thoughts welcome there. (edit: we now only break compat if the forwarder actually skims a fee)

Comment threadlightning/src/events/mod.rs Outdated
Comment threadlightning/src/ln/channel.rs Outdated
@valentinewallace
valentinewallaceforce-pushed the 2023-05-forward-less-than-onion branch from a1cbf67 to db93d1bCompareJune 9, 2023 14:28
@tnull
tnull self-requested a review June 9, 2023 21:39

@alecchendevalecchendev left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nice!

Comment threadlightning/src/ln/channelmanager.rs Outdated
Comment threadlightning/src/ln/msgs.rs
Comment threadlightning/src/ln/channelmanager.rs Outdated
payment_hash,
purpose: purpose(),
amount_msat,
counterparty_skimmed_fee_msat: total_value.saturating_sub(amount_msat),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

In the case where a counterparty overshoots the amount in the onion, I think this would report the skimmed fee inaccurately? E.g. the counterparty_skimmed_fee_msat would be offset by amount_msat - total_value. It probably wouldn't happen very often and the offset probably wouldn't be much, but figured I'd still make note of it.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Yeah, I think this field will be inaccurate if some non-penultimate intermediate node took took less fee than intended by the sender (if I understand you correctly), but I'm not sure if we're able to detect that? IIUC we only have sender_intended_total and actual_received_total to work off of here, though might be missing something.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think it'd be possible by adding the skimmed fee to PendingHTLCRouting::Receive/ReceiveKeysend (which seems possible since the skimmed fee gets sent through construct_recv_pending_htlc_info), and then probably keeping this on ClaimableHTLC and using those when finally calculating? Not sure if it's worth trying to fit it in here, could maybe be followup

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Yea, I think this would be nice, otherwise an intermediary node can cause a payment to fail by not taking enough fee? Its not itself a super big deal, but I think you could use it to figure out if the destination node is an LSP Client and if so a recent one - eg if you have a guess that the ultimate node is one further than some large LSP you could short yourself 1 msat and see if the payment fails to see if its an LSP client or just a routing node peer?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Nice catch! Fixed. I didn't want to just trust whatever the counterparty set as the skimmed fee since they could technically lie about that, so it's now a mix of the previous and new solution, PTAL.

@tnulltnull left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Looks good to me after a quick initial pass.

I wonder if it would be nice to also expose the counterparty_skimmed_fee_msat field via PaymentClaimed?

Comment threadlightning/src/util/config.rs Outdated
Comment threadlightning/src/util/config.rs Outdated
Comment threadlightning/src/util/config.rs Outdated
@valentinewallace

Copy link
Copy Markdown
ContributorAuthor

I wonder if it would be nice to also expose the counterparty_skimmed_fee_msat field via PaymentClaimed?

Added a TODO for this to #1999

@TheBlueMatt

Copy link
Copy Markdown
Collaborator

Feel free to squash IMO.

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Will need a small rebase after #2077

Comment threadlightning/src/events/mod.rs
Comment threadlightning/src/ln/channelmanager.rs Outdated
payment_hash,
purpose: purpose(),
amount_msat,
counterparty_skimmed_fee_msat: total_value.saturating_sub(amount_msat),

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Yea, I think this would be nice, otherwise an intermediary node can cause a payment to fail by not taking enough fee? Its not itself a super big deal, but I think you could use it to figure out if the destination node is an LSP Client and if so a recent one - eg if you have a guess that the ultimate node is one further than some large LSP you could short yourself 1 msat and see if the payment fails to see if its an LSP client or just a routing node peer?

Comment threadlightning/src/ln/channelmanager.rs Outdated
onion_packet,
short_channel_id: next_hop_scid,
skimmed_fee_msat:
// The minuend here must match the expected forward amount generated for the

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

TIL what minuend means.

Comment threadlightning/src/ln/channelmanager.rs Outdated
skimmed_fee_msat:
// The minuend here must match the expected forward amount generated for the
// HTLCIntercepted event.
Some(payment.forward_info.outgoing_amt_msat.saturating_sub(amt_to_forward_msat)),

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This should be None if we're not subtracting anything. Also do we want to fail if the resulting amount is zero?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Switched to None. I don't think we should fail if we forward more than expected, since the docs already say we allow this?

@valentinewallace

Copy link
Copy Markdown
ContributorAuthor

Rebased on #2077 to get a head start on rebase conflicts.

@valentinewallace
valentinewallaceforce-pushed the 2023-05-forward-less-than-onion branch 2 times, most recently from 45a7180 to 703b03aCompareJune 16, 2023 15:26
Comment threadlightning/src/ln/channelmanager.rs Outdated
Comment threadlightning/src/ln/channelmanager.rs Outdated
Comment threadlightning/src/util/config.rs Outdated
Comment threadpending_changelog/forward-underpaying-htlc.txt
Comment threadlightning/src/ln/channelmanager.rs Outdated
@valentinewallace
valentinewallaceforce-pushed the 2023-05-forward-less-than-onion branch from 703b03a to 1c63f20CompareJune 20, 2023 16:29

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

LGTM, one real comment and a nit, feel free to squash.

Comment threadlightning/src/ln/channelmanager.rs
Comment threadlightning/src/ln/channel.rs
@TheBlueMattTheBlueMatt modified the milestones: 0.0.116, 0.0.116alphaJun 20, 2023

@alecchendevalecchendev left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM I think!

Comment threadlightning/src/util/config.rs Outdated
Comment on lines +412 to +416
/// # Note
/// It's important for payee wallet software to verify that [`PaymentClaimable::amount_msat`] is
/// as-expected if this feature is activated, otherwise they may lose money!
/// [`PaymentClaimable::counterparty_skimmed_fee_msat`] provides the fee taken by the
/// counterparty.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Not sure if it's worth mentioning here or is maybe more fit for an LSP client spec, but I think the attack described in #2319 (comment) is still possible if the payee fails a payment based on the skimmed fee being too high instead of just checking amount_msat and that the sum of amount_msat + counterparty_skimmed_fee_msat add up to at least what they expected. The docs here already only say to check amount_msat so I think it's probably fine as is but figured I'd still make note of it :)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I don't think so? If the fee skimmed is too high that means the immediately-prior node took too much, if a node prior to that in the path took too much it should result in the second-to-last hop taking too little (if they're taking a percentage fee).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Oh my bad, for some reason I was thinking intermediate nodes could still affect the final skimmed fee but that was fixed, oops

@valentinewallace
valentinewallaceforce-pushed the 2023-05-forward-less-than-onion branch 2 times, most recently from 646a030 to 134e631CompareJune 20, 2023 21:57
We need the channel lock for constructing a pending HTLC's status because we
need to know if the channel accepts underpaying HTLCs in upcoming commits.
See ChannelConfig::accept_underpaying_htlcs
Receivers need to use this value to verify incoming payments if
ChannelConfig::accept_underpaying_htlcs is set.
Used to get an accurate skimmed fee in the resulting PaymentClaimable event.
Useful for penultimate hops in routes to take an extra fee, if for example they
opened a JIT channel to the payee and want them to help bear the channel open
cost.
So the receiver can verify it and approve underpaying HTLCs (see
ChannelConfig::accept_underpaying_htlcs).
Make sure the penultimate hop took the amount of fee that they claimed to take.
Without checking this TLV, we're heavily relying on the receiving wallet code
to correctly implement logic to calculate that that the fee is as expected.
@valentinewallace
valentinewallaceforce-pushed the 2023-05-forward-less-than-onion branch from 134e631 to 2127eb8CompareJune 20, 2023 21:57
@valentinewallace

Copy link
Copy Markdown
ContributorAuthor

Squashed.

first_hop_htlc_msat: htlc_msat,
payment_id,
}, onion_packet, &self.logger);
}, onion_packet, None, &self.logger);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

We probably need, as a followup, to support setting this - if you're an LSP and want to be the first payment to a given client you'll need it to take a fee on the first hop. Ideally we'd have something to handle that, but right now I don't think we will let you "just" send a payment to an intercept SCID, which we may consider.

@tnull
tnull merged commit 15b1c9b into lightningdevkit:mainJun 21, 2023
@TheBlueMattTheBlueMatt modified the milestones: 0.0.116alpha, 0.0.116Jun 24, 2023
Sign up for freeto 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.

6 participants

@valentinewallace@codecov-commenter@TheBlueMatt@tnull@alecchendev@wpaulino
, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Allow forwarding less than the amount in the onion by valentinewallace · Pull Request #2319 · lightningdevkit/rust-lightning · GitHub
Skip to content

Allow forwarding less than the amount in the onion - #2319

Merged
tnull merged 12 commits into
lightningdevkit:mainfrom
valentinewallace:2023-05-forward-less-than-onion
Jun 21, 2023
Merged

Allow forwarding less than the amount in the onion #2319
tnull merged 12 commits into
lightningdevkit:mainfrom
valentinewallace:2023-05-forward-less-than-onion

Conversation

@valentinewallace

@valentinewallacevalentinewallace commented May 25, 2023

Copy link
Copy Markdown
Contributor

Support skimming an additional fee off of intercepted HTLCs, per lightning/blips#25.

V1 of addressing #1999
Based on #2305

@valentinewallace
valentinewallaceforce-pushed the 2023-05-forward-less-than-onion branch from ad259dd to 2a07438CompareMay 25, 2023 18:49
@codecov-commenter

codecov-commenter commented May 25, 2023

Copy link
Copy Markdown

Codecov Report

Patch coverage: 90.61% and project coverage change: +0.15 🎉

Comparison is base (ae9e96e) 90.35% compared to head (2127eb8) 90.50%.

❗ 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 #2319 +/- ##
==========================================
+ Coverage 90.35% 90.50% +0.15% 
==========================================
Files 106 106 Lines 54347 59105 +4758 Branches 54347 59105 +4758 ==========================================
+ Hits 49105 53494 +4389 - Misses 5242 5611 +369 
Impacted FilesCoverage Δ
lightning/src/ln/functional_tests.rs98.34% <ø> (+0.11%)⬆️
lightning/src/ln/channel.rs89.49% <57.89%> (-0.33%)⬇️
lightning/src/events/mod.rs43.58% <90.00%> (+2.17%)⬆️
lightning/src/ln/channelmanager.rs87.79% <94.07%> (+1.21%)⬆️
lightning/src/ln/payment_tests.rs97.66% <98.79%> (+0.04%)⬆️
lightning/src/ln/functional_test_utils.rs87.63% <100.00%> (+0.34%)⬆️
lightning/src/ln/msgs.rs84.59% <100.00%> (+0.01%)⬆️
lightning/src/util/config.rs57.47% <100.00%> (-0.18%)⬇️

... and 11 files with indirect coverage changes

☔ View full report in Codecov by Sentry.
📢 Do you have feedback about the report comment? Let us know in this issue.

@wpaulinowpaulino added this to the 0.0.116 milestone May 25, 2023

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

At first glance this basically looks good I think.

Comment threadlightning/src/ln/channelmanager.rs Outdated
Comment threadlightning/src/ln/channelmanager.rs Outdated
@dunxen
dunxen self-requested a review June 4, 2023 20:24
@valentinewallace
valentinewallaceforce-pushed the 2023-05-forward-less-than-onion branch from 2a07438 to a1cbf67CompareJune 8, 2023 14:18
@valentinewallace
valentinewallace marked this pull request as ready for review June 8, 2023 14:21
@valentinewallace

valentinewallace commented Jun 8, 2023

Copy link
Copy Markdown
ContributorAuthor

I removed phantom support for now. Also noticed that this breaks compat for current users of UserConfig::accept_intercept_htlcs. Not sure if a release note is sufficient so thoughts welcome there. (edit: we now only break compat if the forwarder actually skims a fee)

Comment threadlightning/src/events/mod.rs Outdated
Comment threadlightning/src/ln/channel.rs Outdated
@valentinewallace
valentinewallaceforce-pushed the 2023-05-forward-less-than-onion branch from a1cbf67 to db93d1bCompareJune 9, 2023 14:28
@tnull
tnull self-requested a review June 9, 2023 21:39

@alecchendevalecchendev left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nice!

Comment threadlightning/src/ln/channelmanager.rs Outdated
Comment threadlightning/src/ln/msgs.rs
Comment threadlightning/src/ln/channelmanager.rs Outdated
payment_hash,
purpose: purpose(),
amount_msat,
counterparty_skimmed_fee_msat: total_value.saturating_sub(amount_msat),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

In the case where a counterparty overshoots the amount in the onion, I think this would report the skimmed fee inaccurately? E.g. the counterparty_skimmed_fee_msat would be offset by amount_msat - total_value. It probably wouldn't happen very often and the offset probably wouldn't be much, but figured I'd still make note of it.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Yeah, I think this field will be inaccurate if some non-penultimate intermediate node took took less fee than intended by the sender (if I understand you correctly), but I'm not sure if we're able to detect that? IIUC we only have sender_intended_total and actual_received_total to work off of here, though might be missing something.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think it'd be possible by adding the skimmed fee to PendingHTLCRouting::Receive/ReceiveKeysend (which seems possible since the skimmed fee gets sent through construct_recv_pending_htlc_info), and then probably keeping this on ClaimableHTLC and using those when finally calculating? Not sure if it's worth trying to fit it in here, could maybe be followup

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Yea, I think this would be nice, otherwise an intermediary node can cause a payment to fail by not taking enough fee? Its not itself a super big deal, but I think you could use it to figure out if the destination node is an LSP Client and if so a recent one - eg if you have a guess that the ultimate node is one further than some large LSP you could short yourself 1 msat and see if the payment fails to see if its an LSP client or just a routing node peer?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Nice catch! Fixed. I didn't want to just trust whatever the counterparty set as the skimmed fee since they could technically lie about that, so it's now a mix of the previous and new solution, PTAL.

@tnulltnull left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Looks good to me after a quick initial pass.

I wonder if it would be nice to also expose the counterparty_skimmed_fee_msat field via PaymentClaimed?

Comment threadlightning/src/util/config.rs Outdated
Comment threadlightning/src/util/config.rs Outdated
Comment threadlightning/src/util/config.rs Outdated
@valentinewallace

Copy link
Copy Markdown
ContributorAuthor

I wonder if it would be nice to also expose the counterparty_skimmed_fee_msat field via PaymentClaimed?

Added a TODO for this to #1999

@TheBlueMatt

Copy link
Copy Markdown
Collaborator

Feel free to squash IMO.

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Will need a small rebase after #2077

Comment threadlightning/src/events/mod.rs
Comment threadlightning/src/ln/channelmanager.rs Outdated
payment_hash,
purpose: purpose(),
amount_msat,
counterparty_skimmed_fee_msat: total_value.saturating_sub(amount_msat),

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Yea, I think this would be nice, otherwise an intermediary node can cause a payment to fail by not taking enough fee? Its not itself a super big deal, but I think you could use it to figure out if the destination node is an LSP Client and if so a recent one - eg if you have a guess that the ultimate node is one further than some large LSP you could short yourself 1 msat and see if the payment fails to see if its an LSP client or just a routing node peer?

Comment threadlightning/src/ln/channelmanager.rs Outdated
onion_packet,
short_channel_id: next_hop_scid,
skimmed_fee_msat:
// The minuend here must match the expected forward amount generated for the

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

TIL what minuend means.

Comment threadlightning/src/ln/channelmanager.rs Outdated
skimmed_fee_msat:
// The minuend here must match the expected forward amount generated for the
// HTLCIntercepted event.
Some(payment.forward_info.outgoing_amt_msat.saturating_sub(amt_to_forward_msat)),

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This should be None if we're not subtracting anything. Also do we want to fail if the resulting amount is zero?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Switched to None. I don't think we should fail if we forward more than expected, since the docs already say we allow this?

@valentinewallace

Copy link
Copy Markdown
ContributorAuthor

Rebased on #2077 to get a head start on rebase conflicts.

@valentinewallace
valentinewallaceforce-pushed the 2023-05-forward-less-than-onion branch 2 times, most recently from 45a7180 to 703b03aCompareJune 16, 2023 15:26
Comment threadlightning/src/ln/channelmanager.rs Outdated
Comment threadlightning/src/ln/channelmanager.rs Outdated
Comment threadlightning/src/util/config.rs Outdated
Comment threadpending_changelog/forward-underpaying-htlc.txt
Comment threadlightning/src/ln/channelmanager.rs Outdated
@valentinewallace
valentinewallaceforce-pushed the 2023-05-forward-less-than-onion branch from 703b03a to 1c63f20CompareJune 20, 2023 16:29

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

LGTM, one real comment and a nit, feel free to squash.

Comment threadlightning/src/ln/channelmanager.rs
Comment threadlightning/src/ln/channel.rs
@TheBlueMattTheBlueMatt modified the milestones: 0.0.116, 0.0.116alphaJun 20, 2023

@alecchendevalecchendev left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM I think!

Comment threadlightning/src/util/config.rs Outdated
Comment on lines +412 to +416
/// # Note
/// It's important for payee wallet software to verify that [`PaymentClaimable::amount_msat`] is
/// as-expected if this feature is activated, otherwise they may lose money!
/// [`PaymentClaimable::counterparty_skimmed_fee_msat`] provides the fee taken by the
/// counterparty.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Not sure if it's worth mentioning here or is maybe more fit for an LSP client spec, but I think the attack described in #2319 (comment) is still possible if the payee fails a payment based on the skimmed fee being too high instead of just checking amount_msat and that the sum of amount_msat + counterparty_skimmed_fee_msat add up to at least what they expected. The docs here already only say to check amount_msat so I think it's probably fine as is but figured I'd still make note of it :)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I don't think so? If the fee skimmed is too high that means the immediately-prior node took too much, if a node prior to that in the path took too much it should result in the second-to-last hop taking too little (if they're taking a percentage fee).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Oh my bad, for some reason I was thinking intermediate nodes could still affect the final skimmed fee but that was fixed, oops

@valentinewallace
valentinewallaceforce-pushed the 2023-05-forward-less-than-onion branch 2 times, most recently from 646a030 to 134e631CompareJune 20, 2023 21:57
We need the channel lock for constructing a pending HTLC's status because we
need to know if the channel accepts underpaying HTLCs in upcoming commits.
See ChannelConfig::accept_underpaying_htlcs
Receivers need to use this value to verify incoming payments if
ChannelConfig::accept_underpaying_htlcs is set.
Used to get an accurate skimmed fee in the resulting PaymentClaimable event.
Useful for penultimate hops in routes to take an extra fee, if for example they
opened a JIT channel to the payee and want them to help bear the channel open
cost.
So the receiver can verify it and approve underpaying HTLCs (see
ChannelConfig::accept_underpaying_htlcs).
Make sure the penultimate hop took the amount of fee that they claimed to take.
Without checking this TLV, we're heavily relying on the receiving wallet code
to correctly implement logic to calculate that that the fee is as expected.
@valentinewallace
valentinewallaceforce-pushed the 2023-05-forward-less-than-onion branch from 134e631 to 2127eb8CompareJune 20, 2023 21:57
@valentinewallace

Copy link
Copy Markdown
ContributorAuthor

Squashed.

first_hop_htlc_msat: htlc_msat,
payment_id,
}, onion_packet, &self.logger);
}, onion_packet, None, &self.logger);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

We probably need, as a followup, to support setting this - if you're an LSP and want to be the first payment to a given client you'll need it to take a fee on the first hop. Ideally we'd have something to handle that, but right now I don't think we will let you "just" send a payment to an intercept SCID, which we may consider.

@tnull
tnull merged commit 15b1c9b into lightningdevkit:mainJun 21, 2023
@TheBlueMattTheBlueMatt modified the milestones: 0.0.116alpha, 0.0.116Jun 24, 2023
Sign up for freeto 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.

6 participants

@valentinewallace@codecov-commenter@TheBlueMatt@tnull@alecchendev@wpaulino
, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Allow forwarding less than the amount in the onion by valentinewallace · Pull Request #2319 · lightningdevkit/rust-lightning · GitHub
Skip to content

Allow forwarding less than the amount in the onion - #2319

Merged
tnull merged 12 commits into
lightningdevkit:mainfrom
valentinewallace:2023-05-forward-less-than-onion
Jun 21, 2023
Merged

Allow forwarding less than the amount in the onion #2319
tnull merged 12 commits into
lightningdevkit:mainfrom
valentinewallace:2023-05-forward-less-than-onion

Conversation

@valentinewallace

@valentinewallacevalentinewallace commented May 25, 2023

Copy link
Copy Markdown
Contributor

Support skimming an additional fee off of intercepted HTLCs, per lightning/blips#25.

V1 of addressing #1999
Based on #2305

@valentinewallace
valentinewallaceforce-pushed the 2023-05-forward-less-than-onion branch from ad259dd to 2a07438CompareMay 25, 2023 18:49
@codecov-commenter

codecov-commenter commented May 25, 2023

Copy link
Copy Markdown

Codecov Report

Patch coverage: 90.61% and project coverage change: +0.15 🎉

Comparison is base (ae9e96e) 90.35% compared to head (2127eb8) 90.50%.

❗ 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 #2319 +/- ##
==========================================
+ Coverage 90.35% 90.50% +0.15% 
==========================================
Files 106 106 Lines 54347 59105 +4758 Branches 54347 59105 +4758 ==========================================
+ Hits 49105 53494 +4389 - Misses 5242 5611 +369 
Impacted FilesCoverage Δ
lightning/src/ln/functional_tests.rs98.34% <ø> (+0.11%)⬆️
lightning/src/ln/channel.rs89.49% <57.89%> (-0.33%)⬇️
lightning/src/events/mod.rs43.58% <90.00%> (+2.17%)⬆️
lightning/src/ln/channelmanager.rs87.79% <94.07%> (+1.21%)⬆️
lightning/src/ln/payment_tests.rs97.66% <98.79%> (+0.04%)⬆️
lightning/src/ln/functional_test_utils.rs87.63% <100.00%> (+0.34%)⬆️
lightning/src/ln/msgs.rs84.59% <100.00%> (+0.01%)⬆️
lightning/src/util/config.rs57.47% <100.00%> (-0.18%)⬇️

... and 11 files with indirect coverage changes

☔ View full report in Codecov by Sentry.
📢 Do you have feedback about the report comment? Let us know in this issue.

@wpaulinowpaulino added this to the 0.0.116 milestone May 25, 2023

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

At first glance this basically looks good I think.

Comment threadlightning/src/ln/channelmanager.rs Outdated
Comment threadlightning/src/ln/channelmanager.rs Outdated
@dunxen
dunxen self-requested a review June 4, 2023 20:24
@valentinewallace
valentinewallaceforce-pushed the 2023-05-forward-less-than-onion branch from 2a07438 to a1cbf67CompareJune 8, 2023 14:18
@valentinewallace
valentinewallace marked this pull request as ready for review June 8, 2023 14:21
@valentinewallace

valentinewallace commented Jun 8, 2023

Copy link
Copy Markdown
ContributorAuthor

I removed phantom support for now. Also noticed that this breaks compat for current users of UserConfig::accept_intercept_htlcs. Not sure if a release note is sufficient so thoughts welcome there. (edit: we now only break compat if the forwarder actually skims a fee)

Comment threadlightning/src/events/mod.rs Outdated
Comment threadlightning/src/ln/channel.rs Outdated
@valentinewallace
valentinewallaceforce-pushed the 2023-05-forward-less-than-onion branch from a1cbf67 to db93d1bCompareJune 9, 2023 14:28
@tnull
tnull self-requested a review June 9, 2023 21:39

@alecchendevalecchendev left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nice!

Comment threadlightning/src/ln/channelmanager.rs Outdated
Comment threadlightning/src/ln/msgs.rs
Comment threadlightning/src/ln/channelmanager.rs Outdated
payment_hash,
purpose: purpose(),
amount_msat,
counterparty_skimmed_fee_msat: total_value.saturating_sub(amount_msat),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

In the case where a counterparty overshoots the amount in the onion, I think this would report the skimmed fee inaccurately? E.g. the counterparty_skimmed_fee_msat would be offset by amount_msat - total_value. It probably wouldn't happen very often and the offset probably wouldn't be much, but figured I'd still make note of it.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Yeah, I think this field will be inaccurate if some non-penultimate intermediate node took took less fee than intended by the sender (if I understand you correctly), but I'm not sure if we're able to detect that? IIUC we only have sender_intended_total and actual_received_total to work off of here, though might be missing something.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think it'd be possible by adding the skimmed fee to PendingHTLCRouting::Receive/ReceiveKeysend (which seems possible since the skimmed fee gets sent through construct_recv_pending_htlc_info), and then probably keeping this on ClaimableHTLC and using those when finally calculating? Not sure if it's worth trying to fit it in here, could maybe be followup

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Yea, I think this would be nice, otherwise an intermediary node can cause a payment to fail by not taking enough fee? Its not itself a super big deal, but I think you could use it to figure out if the destination node is an LSP Client and if so a recent one - eg if you have a guess that the ultimate node is one further than some large LSP you could short yourself 1 msat and see if the payment fails to see if its an LSP client or just a routing node peer?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Nice catch! Fixed. I didn't want to just trust whatever the counterparty set as the skimmed fee since they could technically lie about that, so it's now a mix of the previous and new solution, PTAL.

@tnulltnull left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Looks good to me after a quick initial pass.

I wonder if it would be nice to also expose the counterparty_skimmed_fee_msat field via PaymentClaimed?

Comment threadlightning/src/util/config.rs Outdated
Comment threadlightning/src/util/config.rs Outdated
Comment threadlightning/src/util/config.rs Outdated
@valentinewallace

Copy link
Copy Markdown
ContributorAuthor

I wonder if it would be nice to also expose the counterparty_skimmed_fee_msat field via PaymentClaimed?

Added a TODO for this to #1999

@TheBlueMatt

Copy link
Copy Markdown
Collaborator

Feel free to squash IMO.

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Will need a small rebase after #2077

Comment threadlightning/src/events/mod.rs
Comment threadlightning/src/ln/channelmanager.rs Outdated
payment_hash,
purpose: purpose(),
amount_msat,
counterparty_skimmed_fee_msat: total_value.saturating_sub(amount_msat),

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Yea, I think this would be nice, otherwise an intermediary node can cause a payment to fail by not taking enough fee? Its not itself a super big deal, but I think you could use it to figure out if the destination node is an LSP Client and if so a recent one - eg if you have a guess that the ultimate node is one further than some large LSP you could short yourself 1 msat and see if the payment fails to see if its an LSP client or just a routing node peer?

Comment threadlightning/src/ln/channelmanager.rs Outdated
onion_packet,
short_channel_id: next_hop_scid,
skimmed_fee_msat:
// The minuend here must match the expected forward amount generated for the

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

TIL what minuend means.

Comment threadlightning/src/ln/channelmanager.rs Outdated
skimmed_fee_msat:
// The minuend here must match the expected forward amount generated for the
// HTLCIntercepted event.
Some(payment.forward_info.outgoing_amt_msat.saturating_sub(amt_to_forward_msat)),

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This should be None if we're not subtracting anything. Also do we want to fail if the resulting amount is zero?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Switched to None. I don't think we should fail if we forward more than expected, since the docs already say we allow this?

@valentinewallace

Copy link
Copy Markdown
ContributorAuthor

Rebased on #2077 to get a head start on rebase conflicts.

@valentinewallace
valentinewallaceforce-pushed the 2023-05-forward-less-than-onion branch 2 times, most recently from 45a7180 to 703b03aCompareJune 16, 2023 15:26
Comment threadlightning/src/ln/channelmanager.rs Outdated
Comment threadlightning/src/ln/channelmanager.rs Outdated
Comment threadlightning/src/util/config.rs Outdated
Comment threadpending_changelog/forward-underpaying-htlc.txt
Comment threadlightning/src/ln/channelmanager.rs Outdated
@valentinewallace
valentinewallaceforce-pushed the 2023-05-forward-less-than-onion branch from 703b03a to 1c63f20CompareJune 20, 2023 16:29

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

LGTM, one real comment and a nit, feel free to squash.

Comment threadlightning/src/ln/channelmanager.rs
Comment threadlightning/src/ln/channel.rs
@TheBlueMattTheBlueMatt modified the milestones: 0.0.116, 0.0.116alphaJun 20, 2023

@alecchendevalecchendev left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM I think!

Comment threadlightning/src/util/config.rs Outdated
Comment on lines +412 to +416
/// # Note
/// It's important for payee wallet software to verify that [`PaymentClaimable::amount_msat`] is
/// as-expected if this feature is activated, otherwise they may lose money!
/// [`PaymentClaimable::counterparty_skimmed_fee_msat`] provides the fee taken by the
/// counterparty.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Not sure if it's worth mentioning here or is maybe more fit for an LSP client spec, but I think the attack described in #2319 (comment) is still possible if the payee fails a payment based on the skimmed fee being too high instead of just checking amount_msat and that the sum of amount_msat + counterparty_skimmed_fee_msat add up to at least what they expected. The docs here already only say to check amount_msat so I think it's probably fine as is but figured I'd still make note of it :)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I don't think so? If the fee skimmed is too high that means the immediately-prior node took too much, if a node prior to that in the path took too much it should result in the second-to-last hop taking too little (if they're taking a percentage fee).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Oh my bad, for some reason I was thinking intermediate nodes could still affect the final skimmed fee but that was fixed, oops

@valentinewallace
valentinewallaceforce-pushed the 2023-05-forward-less-than-onion branch 2 times, most recently from 646a030 to 134e631CompareJune 20, 2023 21:57
We need the channel lock for constructing a pending HTLC's status because we
need to know if the channel accepts underpaying HTLCs in upcoming commits.
See ChannelConfig::accept_underpaying_htlcs
Receivers need to use this value to verify incoming payments if
ChannelConfig::accept_underpaying_htlcs is set.
Used to get an accurate skimmed fee in the resulting PaymentClaimable event.
Useful for penultimate hops in routes to take an extra fee, if for example they
opened a JIT channel to the payee and want them to help bear the channel open
cost.
So the receiver can verify it and approve underpaying HTLCs (see
ChannelConfig::accept_underpaying_htlcs).
Make sure the penultimate hop took the amount of fee that they claimed to take.
Without checking this TLV, we're heavily relying on the receiving wallet code
to correctly implement logic to calculate that that the fee is as expected.
@valentinewallace
valentinewallaceforce-pushed the 2023-05-forward-less-than-onion branch from 134e631 to 2127eb8CompareJune 20, 2023 21:57
@valentinewallace

Copy link
Copy Markdown
ContributorAuthor

Squashed.

first_hop_htlc_msat: htlc_msat,
payment_id,
}, onion_packet, &self.logger);
}, onion_packet, None, &self.logger);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

We probably need, as a followup, to support setting this - if you're an LSP and want to be the first payment to a given client you'll need it to take a fee on the first hop. Ideally we'd have something to handle that, but right now I don't think we will let you "just" send a payment to an intercept SCID, which we may consider.

@tnull
tnull merged commit 15b1c9b into lightningdevkit:mainJun 21, 2023
@TheBlueMattTheBlueMatt modified the milestones: 0.0.116alpha, 0.0.116Jun 24, 2023
Sign up for freeto 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.

6 participants

@valentinewallace@codecov-commenter@TheBlueMatt@tnull@alecchendev@wpaulino
, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Allow forwarding less than the amount in the onion by valentinewallace · Pull Request #2319 · lightningdevkit/rust-lightning · GitHub
Skip to content

Allow forwarding less than the amount in the onion - #2319

Merged
tnull merged 12 commits into
lightningdevkit:mainfrom
valentinewallace:2023-05-forward-less-than-onion
Jun 21, 2023
Merged

Allow forwarding less than the amount in the onion #2319
tnull merged 12 commits into
lightningdevkit:mainfrom
valentinewallace:2023-05-forward-less-than-onion

Conversation

@valentinewallace

@valentinewallacevalentinewallace commented May 25, 2023

Copy link
Copy Markdown
Contributor

Support skimming an additional fee off of intercepted HTLCs, per lightning/blips#25.

V1 of addressing #1999
Based on #2305

@valentinewallace
valentinewallaceforce-pushed the 2023-05-forward-less-than-onion branch from ad259dd to 2a07438CompareMay 25, 2023 18:49
@codecov-commenter

codecov-commenter commented May 25, 2023

Copy link
Copy Markdown

Codecov Report

Patch coverage: 90.61% and project coverage change: +0.15 🎉

Comparison is base (ae9e96e) 90.35% compared to head (2127eb8) 90.50%.

❗ 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 #2319 +/- ##
==========================================
+ Coverage 90.35% 90.50% +0.15% 
==========================================
Files 106 106 Lines 54347 59105 +4758 Branches 54347 59105 +4758 ==========================================
+ Hits 49105 53494 +4389 - Misses 5242 5611 +369 
Impacted FilesCoverage Δ
lightning/src/ln/functional_tests.rs98.34% <ø> (+0.11%)⬆️
lightning/src/ln/channel.rs89.49% <57.89%> (-0.33%)⬇️
lightning/src/events/mod.rs43.58% <90.00%> (+2.17%)⬆️
lightning/src/ln/channelmanager.rs87.79% <94.07%> (+1.21%)⬆️
lightning/src/ln/payment_tests.rs97.66% <98.79%> (+0.04%)⬆️
lightning/src/ln/functional_test_utils.rs87.63% <100.00%> (+0.34%)⬆️
lightning/src/ln/msgs.rs84.59% <100.00%> (+0.01%)⬆️
lightning/src/util/config.rs57.47% <100.00%> (-0.18%)⬇️

... and 11 files with indirect coverage changes

☔ View full report in Codecov by Sentry.
📢 Do you have feedback about the report comment? Let us know in this issue.

@wpaulinowpaulino added this to the 0.0.116 milestone May 25, 2023

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

At first glance this basically looks good I think.

Comment threadlightning/src/ln/channelmanager.rs Outdated
Comment threadlightning/src/ln/channelmanager.rs Outdated
@dunxen
dunxen self-requested a review June 4, 2023 20:24
@valentinewallace
valentinewallaceforce-pushed the 2023-05-forward-less-than-onion branch from 2a07438 to a1cbf67CompareJune 8, 2023 14:18
@valentinewallace
valentinewallace marked this pull request as ready for review June 8, 2023 14:21
@valentinewallace

valentinewallace commented Jun 8, 2023

Copy link
Copy Markdown
ContributorAuthor

I removed phantom support for now. Also noticed that this breaks compat for current users of UserConfig::accept_intercept_htlcs. Not sure if a release note is sufficient so thoughts welcome there. (edit: we now only break compat if the forwarder actually skims a fee)

Comment threadlightning/src/events/mod.rs Outdated
Comment threadlightning/src/ln/channel.rs Outdated
@valentinewallace
valentinewallaceforce-pushed the 2023-05-forward-less-than-onion branch from a1cbf67 to db93d1bCompareJune 9, 2023 14:28
@tnull
tnull self-requested a review June 9, 2023 21:39

@alecchendevalecchendev left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nice!

Comment threadlightning/src/ln/channelmanager.rs Outdated
Comment threadlightning/src/ln/msgs.rs
Comment threadlightning/src/ln/channelmanager.rs Outdated
payment_hash,
purpose: purpose(),
amount_msat,
counterparty_skimmed_fee_msat: total_value.saturating_sub(amount_msat),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

In the case where a counterparty overshoots the amount in the onion, I think this would report the skimmed fee inaccurately? E.g. the counterparty_skimmed_fee_msat would be offset by amount_msat - total_value. It probably wouldn't happen very often and the offset probably wouldn't be much, but figured I'd still make note of it.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Yeah, I think this field will be inaccurate if some non-penultimate intermediate node took took less fee than intended by the sender (if I understand you correctly), but I'm not sure if we're able to detect that? IIUC we only have sender_intended_total and actual_received_total to work off of here, though might be missing something.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think it'd be possible by adding the skimmed fee to PendingHTLCRouting::Receive/ReceiveKeysend (which seems possible since the skimmed fee gets sent through construct_recv_pending_htlc_info), and then probably keeping this on ClaimableHTLC and using those when finally calculating? Not sure if it's worth trying to fit it in here, could maybe be followup

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Yea, I think this would be nice, otherwise an intermediary node can cause a payment to fail by not taking enough fee? Its not itself a super big deal, but I think you could use it to figure out if the destination node is an LSP Client and if so a recent one - eg if you have a guess that the ultimate node is one further than some large LSP you could short yourself 1 msat and see if the payment fails to see if its an LSP client or just a routing node peer?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Nice catch! Fixed. I didn't want to just trust whatever the counterparty set as the skimmed fee since they could technically lie about that, so it's now a mix of the previous and new solution, PTAL.

@tnulltnull left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Looks good to me after a quick initial pass.

I wonder if it would be nice to also expose the counterparty_skimmed_fee_msat field via PaymentClaimed?

Comment threadlightning/src/util/config.rs Outdated
Comment threadlightning/src/util/config.rs Outdated
Comment threadlightning/src/util/config.rs Outdated
@valentinewallace

Copy link
Copy Markdown
ContributorAuthor

I wonder if it would be nice to also expose the counterparty_skimmed_fee_msat field via PaymentClaimed?

Added a TODO for this to #1999

@TheBlueMatt

Copy link
Copy Markdown
Collaborator

Feel free to squash IMO.

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Will need a small rebase after #2077

Comment threadlightning/src/events/mod.rs
Comment threadlightning/src/ln/channelmanager.rs Outdated
payment_hash,
purpose: purpose(),
amount_msat,
counterparty_skimmed_fee_msat: total_value.saturating_sub(amount_msat),

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Yea, I think this would be nice, otherwise an intermediary node can cause a payment to fail by not taking enough fee? Its not itself a super big deal, but I think you could use it to figure out if the destination node is an LSP Client and if so a recent one - eg if you have a guess that the ultimate node is one further than some large LSP you could short yourself 1 msat and see if the payment fails to see if its an LSP client or just a routing node peer?

Comment threadlightning/src/ln/channelmanager.rs Outdated
onion_packet,
short_channel_id: next_hop_scid,
skimmed_fee_msat:
// The minuend here must match the expected forward amount generated for the

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

TIL what minuend means.

Comment threadlightning/src/ln/channelmanager.rs Outdated
skimmed_fee_msat:
// The minuend here must match the expected forward amount generated for the
// HTLCIntercepted event.
Some(payment.forward_info.outgoing_amt_msat.saturating_sub(amt_to_forward_msat)),

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This should be None if we're not subtracting anything. Also do we want to fail if the resulting amount is zero?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Switched to None. I don't think we should fail if we forward more than expected, since the docs already say we allow this?

@valentinewallace

Copy link
Copy Markdown
ContributorAuthor

Rebased on #2077 to get a head start on rebase conflicts.

@valentinewallace
valentinewallaceforce-pushed the 2023-05-forward-less-than-onion branch 2 times, most recently from 45a7180 to 703b03aCompareJune 16, 2023 15:26
Comment threadlightning/src/ln/channelmanager.rs Outdated
Comment threadlightning/src/ln/channelmanager.rs Outdated
Comment threadlightning/src/util/config.rs Outdated
Comment threadpending_changelog/forward-underpaying-htlc.txt
Comment threadlightning/src/ln/channelmanager.rs Outdated
@valentinewallace
valentinewallaceforce-pushed the 2023-05-forward-less-than-onion branch from 703b03a to 1c63f20CompareJune 20, 2023 16:29

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

LGTM, one real comment and a nit, feel free to squash.

Comment threadlightning/src/ln/channelmanager.rs
Comment threadlightning/src/ln/channel.rs
@TheBlueMattTheBlueMatt modified the milestones: 0.0.116, 0.0.116alphaJun 20, 2023

@alecchendevalecchendev left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM I think!

Comment threadlightning/src/util/config.rs Outdated
Comment on lines +412 to +416
/// # Note
/// It's important for payee wallet software to verify that [`PaymentClaimable::amount_msat`] is
/// as-expected if this feature is activated, otherwise they may lose money!
/// [`PaymentClaimable::counterparty_skimmed_fee_msat`] provides the fee taken by the
/// counterparty.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Not sure if it's worth mentioning here or is maybe more fit for an LSP client spec, but I think the attack described in #2319 (comment) is still possible if the payee fails a payment based on the skimmed fee being too high instead of just checking amount_msat and that the sum of amount_msat + counterparty_skimmed_fee_msat add up to at least what they expected. The docs here already only say to check amount_msat so I think it's probably fine as is but figured I'd still make note of it :)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I don't think so? If the fee skimmed is too high that means the immediately-prior node took too much, if a node prior to that in the path took too much it should result in the second-to-last hop taking too little (if they're taking a percentage fee).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Oh my bad, for some reason I was thinking intermediate nodes could still affect the final skimmed fee but that was fixed, oops

@valentinewallace
valentinewallaceforce-pushed the 2023-05-forward-less-than-onion branch 2 times, most recently from 646a030 to 134e631CompareJune 20, 2023 21:57
We need the channel lock for constructing a pending HTLC's status because we
need to know if the channel accepts underpaying HTLCs in upcoming commits.
See ChannelConfig::accept_underpaying_htlcs
Receivers need to use this value to verify incoming payments if
ChannelConfig::accept_underpaying_htlcs is set.
Used to get an accurate skimmed fee in the resulting PaymentClaimable event.
Useful for penultimate hops in routes to take an extra fee, if for example they
opened a JIT channel to the payee and want them to help bear the channel open
cost.
So the receiver can verify it and approve underpaying HTLCs (see
ChannelConfig::accept_underpaying_htlcs).
Make sure the penultimate hop took the amount of fee that they claimed to take.
Without checking this TLV, we're heavily relying on the receiving wallet code
to correctly implement logic to calculate that that the fee is as expected.
@valentinewallace
valentinewallaceforce-pushed the 2023-05-forward-less-than-onion branch from 134e631 to 2127eb8CompareJune 20, 2023 21:57
@valentinewallace

Copy link
Copy Markdown
ContributorAuthor

Squashed.

first_hop_htlc_msat: htlc_msat,
payment_id,
}, onion_packet, &self.logger);
}, onion_packet, None, &self.logger);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

We probably need, as a followup, to support setting this - if you're an LSP and want to be the first payment to a given client you'll need it to take a fee on the first hop. Ideally we'd have something to handle that, but right now I don't think we will let you "just" send a payment to an intercept SCID, which we may consider.

@tnull
tnull merged commit 15b1c9b into lightningdevkit:mainJun 21, 2023
@TheBlueMattTheBlueMatt modified the milestones: 0.0.116alpha, 0.0.116Jun 24, 2023
Sign up for freeto 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.

6 participants

@valentinewallace@codecov-commenter@TheBlueMatt@tnull@alecchendev@wpaulino
, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' Allow forwarding less than the amount in the onion by valentinewallace · Pull Request #2319 · lightningdevkit/rust-lightning · GitHub
Skip to content

Allow forwarding less than the amount in the onion - #2319

Merged
tnull merged 12 commits into
lightningdevkit:mainfrom
valentinewallace:2023-05-forward-less-than-onion
Jun 21, 2023
Merged

Allow forwarding less than the amount in the onion #2319
tnull merged 12 commits into
lightningdevkit:mainfrom
valentinewallace:2023-05-forward-less-than-onion

Conversation

@valentinewallace

@valentinewallacevalentinewallace commented May 25, 2023

Copy link
Copy Markdown
Contributor

Support skimming an additional fee off of intercepted HTLCs, per lightning/blips#25.

V1 of addressing #1999
Based on #2305

@valentinewallace
valentinewallaceforce-pushed the 2023-05-forward-less-than-onion branch from ad259dd to 2a07438CompareMay 25, 2023 18:49
@codecov-commenter

codecov-commenter commented May 25, 2023

Copy link
Copy Markdown

Codecov Report

Patch coverage: 90.61% and project coverage change: +0.15 🎉

Comparison is base (ae9e96e) 90.35% compared to head (2127eb8) 90.50%.

❗ 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 #2319 +/- ##
==========================================
+ Coverage 90.35% 90.50% +0.15% 
==========================================
Files 106 106 Lines 54347 59105 +4758 Branches 54347 59105 +4758 ==========================================
+ Hits 49105 53494 +4389 - Misses 5242 5611 +369 
Impacted FilesCoverage Δ
lightning/src/ln/functional_tests.rs98.34% <ø> (+0.11%)⬆️
lightning/src/ln/channel.rs89.49% <57.89%> (-0.33%)⬇️
lightning/src/events/mod.rs43.58% <90.00%> (+2.17%)⬆️
lightning/src/ln/channelmanager.rs87.79% <94.07%> (+1.21%)⬆️
lightning/src/ln/payment_tests.rs97.66% <98.79%> (+0.04%)⬆️
lightning/src/ln/functional_test_utils.rs87.63% <100.00%> (+0.34%)⬆️
lightning/src/ln/msgs.rs84.59% <100.00%> (+0.01%)⬆️
lightning/src/util/config.rs57.47% <100.00%> (-0.18%)⬇️

... and 11 files with indirect coverage changes

☔ View full report in Codecov by Sentry.
📢 Do you have feedback about the report comment? Let us know in this issue.

@wpaulinowpaulino added this to the 0.0.116 milestone May 25, 2023

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

At first glance this basically looks good I think.

Comment threadlightning/src/ln/channelmanager.rs Outdated
Comment threadlightning/src/ln/channelmanager.rs Outdated
@dunxen
dunxen self-requested a review June 4, 2023 20:24
@valentinewallace
valentinewallaceforce-pushed the 2023-05-forward-less-than-onion branch from 2a07438 to a1cbf67CompareJune 8, 2023 14:18
@valentinewallace
valentinewallace marked this pull request as ready for review June 8, 2023 14:21
@valentinewallace

valentinewallace commented Jun 8, 2023

Copy link
Copy Markdown
ContributorAuthor

I removed phantom support for now. Also noticed that this breaks compat for current users of UserConfig::accept_intercept_htlcs. Not sure if a release note is sufficient so thoughts welcome there. (edit: we now only break compat if the forwarder actually skims a fee)

Comment threadlightning/src/events/mod.rs Outdated
Comment threadlightning/src/ln/channel.rs Outdated
@valentinewallace
valentinewallaceforce-pushed the 2023-05-forward-less-than-onion branch from a1cbf67 to db93d1bCompareJune 9, 2023 14:28
@tnull
tnull self-requested a review June 9, 2023 21:39

@alecchendevalecchendev left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nice!

Comment threadlightning/src/ln/channelmanager.rs Outdated
Comment threadlightning/src/ln/msgs.rs
Comment threadlightning/src/ln/channelmanager.rs Outdated
payment_hash,
purpose: purpose(),
amount_msat,
counterparty_skimmed_fee_msat: total_value.saturating_sub(amount_msat),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

In the case where a counterparty overshoots the amount in the onion, I think this would report the skimmed fee inaccurately? E.g. the counterparty_skimmed_fee_msat would be offset by amount_msat - total_value. It probably wouldn't happen very often and the offset probably wouldn't be much, but figured I'd still make note of it.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Yeah, I think this field will be inaccurate if some non-penultimate intermediate node took took less fee than intended by the sender (if I understand you correctly), but I'm not sure if we're able to detect that? IIUC we only have sender_intended_total and actual_received_total to work off of here, though might be missing something.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think it'd be possible by adding the skimmed fee to PendingHTLCRouting::Receive/ReceiveKeysend (which seems possible since the skimmed fee gets sent through construct_recv_pending_htlc_info), and then probably keeping this on ClaimableHTLC and using those when finally calculating? Not sure if it's worth trying to fit it in here, could maybe be followup

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Yea, I think this would be nice, otherwise an intermediary node can cause a payment to fail by not taking enough fee? Its not itself a super big deal, but I think you could use it to figure out if the destination node is an LSP Client and if so a recent one - eg if you have a guess that the ultimate node is one further than some large LSP you could short yourself 1 msat and see if the payment fails to see if its an LSP client or just a routing node peer?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Nice catch! Fixed. I didn't want to just trust whatever the counterparty set as the skimmed fee since they could technically lie about that, so it's now a mix of the previous and new solution, PTAL.

@tnulltnull left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Looks good to me after a quick initial pass.

I wonder if it would be nice to also expose the counterparty_skimmed_fee_msat field via PaymentClaimed?

Comment threadlightning/src/util/config.rs Outdated
Comment threadlightning/src/util/config.rs Outdated
Comment threadlightning/src/util/config.rs Outdated
@valentinewallace

Copy link
Copy Markdown
ContributorAuthor

I wonder if it would be nice to also expose the counterparty_skimmed_fee_msat field via PaymentClaimed?

Added a TODO for this to #1999

@TheBlueMatt

Copy link
Copy Markdown
Collaborator

Feel free to squash IMO.

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Will need a small rebase after #2077

Comment threadlightning/src/events/mod.rs
Comment threadlightning/src/ln/channelmanager.rs Outdated
payment_hash,
purpose: purpose(),
amount_msat,
counterparty_skimmed_fee_msat: total_value.saturating_sub(amount_msat),

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Yea, I think this would be nice, otherwise an intermediary node can cause a payment to fail by not taking enough fee? Its not itself a super big deal, but I think you could use it to figure out if the destination node is an LSP Client and if so a recent one - eg if you have a guess that the ultimate node is one further than some large LSP you could short yourself 1 msat and see if the payment fails to see if its an LSP client or just a routing node peer?

Comment threadlightning/src/ln/channelmanager.rs Outdated
onion_packet,
short_channel_id: next_hop_scid,
skimmed_fee_msat:
// The minuend here must match the expected forward amount generated for the

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

TIL what minuend means.

Comment threadlightning/src/ln/channelmanager.rs Outdated
skimmed_fee_msat:
// The minuend here must match the expected forward amount generated for the
// HTLCIntercepted event.
Some(payment.forward_info.outgoing_amt_msat.saturating_sub(amt_to_forward_msat)),

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This should be None if we're not subtracting anything. Also do we want to fail if the resulting amount is zero?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Switched to None. I don't think we should fail if we forward more than expected, since the docs already say we allow this?

@valentinewallace

Copy link
Copy Markdown
ContributorAuthor

Rebased on #2077 to get a head start on rebase conflicts.

@valentinewallace
valentinewallaceforce-pushed the 2023-05-forward-less-than-onion branch 2 times, most recently from 45a7180 to 703b03aCompareJune 16, 2023 15:26
Comment threadlightning/src/ln/channelmanager.rs Outdated
Comment threadlightning/src/ln/channelmanager.rs Outdated
Comment threadlightning/src/util/config.rs Outdated
Comment threadpending_changelog/forward-underpaying-htlc.txt
Comment threadlightning/src/ln/channelmanager.rs Outdated
@valentinewallace
valentinewallaceforce-pushed the 2023-05-forward-less-than-onion branch from 703b03a to 1c63f20CompareJune 20, 2023 16:29

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

LGTM, one real comment and a nit, feel free to squash.

Comment threadlightning/src/ln/channelmanager.rs
Comment threadlightning/src/ln/channel.rs
@TheBlueMattTheBlueMatt modified the milestones: 0.0.116, 0.0.116alphaJun 20, 2023

@alecchendevalecchendev left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM I think!

Comment threadlightning/src/util/config.rs Outdated
Comment on lines +412 to +416
/// # Note
/// It's important for payee wallet software to verify that [`PaymentClaimable::amount_msat`] is
/// as-expected if this feature is activated, otherwise they may lose money!
/// [`PaymentClaimable::counterparty_skimmed_fee_msat`] provides the fee taken by the
/// counterparty.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Not sure if it's worth mentioning here or is maybe more fit for an LSP client spec, but I think the attack described in #2319 (comment) is still possible if the payee fails a payment based on the skimmed fee being too high instead of just checking amount_msat and that the sum of amount_msat + counterparty_skimmed_fee_msat add up to at least what they expected. The docs here already only say to check amount_msat so I think it's probably fine as is but figured I'd still make note of it :)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I don't think so? If the fee skimmed is too high that means the immediately-prior node took too much, if a node prior to that in the path took too much it should result in the second-to-last hop taking too little (if they're taking a percentage fee).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Oh my bad, for some reason I was thinking intermediate nodes could still affect the final skimmed fee but that was fixed, oops

@valentinewallace
valentinewallaceforce-pushed the 2023-05-forward-less-than-onion branch 2 times, most recently from 646a030 to 134e631CompareJune 20, 2023 21:57
We need the channel lock for constructing a pending HTLC's status because we
need to know if the channel accepts underpaying HTLCs in upcoming commits.
See ChannelConfig::accept_underpaying_htlcs
Receivers need to use this value to verify incoming payments if
ChannelConfig::accept_underpaying_htlcs is set.
Used to get an accurate skimmed fee in the resulting PaymentClaimable event.
Useful for penultimate hops in routes to take an extra fee, if for example they
opened a JIT channel to the payee and want them to help bear the channel open
cost.
So the receiver can verify it and approve underpaying HTLCs (see
ChannelConfig::accept_underpaying_htlcs).
Make sure the penultimate hop took the amount of fee that they claimed to take.
Without checking this TLV, we're heavily relying on the receiving wallet code
to correctly implement logic to calculate that that the fee is as expected.
@valentinewallace
valentinewallaceforce-pushed the 2023-05-forward-less-than-onion branch from 134e631 to 2127eb8CompareJune 20, 2023 21:57
@valentinewallace

Copy link
Copy Markdown
ContributorAuthor

Squashed.

first_hop_htlc_msat: htlc_msat,
payment_id,
}, onion_packet, &self.logger);
}, onion_packet, None, &self.logger);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

We probably need, as a followup, to support setting this - if you're an LSP and want to be the first payment to a given client you'll need it to take a fee on the first hop. Ideally we'd have something to handle that, but right now I don't think we will let you "just" send a payment to an intercept SCID, which we may consider.

@tnull
tnull merged commit 15b1c9b into lightningdevkit:mainJun 21, 2023
@TheBlueMattTheBlueMatt modified the milestones: 0.0.116alpha, 0.0.116Jun 24, 2023
Sign up for freeto 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.

6 participants

@valentinewallace@codecov-commenter@TheBlueMatt@tnull@alecchendev@wpaulino
, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Allow forwarding less than the amount in the onion by valentinewallace · Pull Request #2319 · lightningdevkit/rust-lightning · GitHub
Skip to content

Allow forwarding less than the amount in the onion - #2319

Merged
tnull merged 12 commits into
lightningdevkit:mainfrom
valentinewallace:2023-05-forward-less-than-onion
Jun 21, 2023
Merged

Allow forwarding less than the amount in the onion #2319
tnull merged 12 commits into
lightningdevkit:mainfrom
valentinewallace:2023-05-forward-less-than-onion

Conversation

@valentinewallace

@valentinewallacevalentinewallace commented May 25, 2023

Copy link
Copy Markdown
Contributor

Support skimming an additional fee off of intercepted HTLCs, per lightning/blips#25.

V1 of addressing #1999
Based on #2305

@valentinewallace
valentinewallaceforce-pushed the 2023-05-forward-less-than-onion branch from ad259dd to 2a07438CompareMay 25, 2023 18:49
@codecov-commenter

codecov-commenter commented May 25, 2023

Copy link
Copy Markdown

Codecov Report

Patch coverage: 90.61% and project coverage change: +0.15 🎉

Comparison is base (ae9e96e) 90.35% compared to head (2127eb8) 90.50%.

❗ 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 #2319 +/- ##
==========================================
+ Coverage 90.35% 90.50% +0.15% 
==========================================
Files 106 106 Lines 54347 59105 +4758 Branches 54347 59105 +4758 ==========================================
+ Hits 49105 53494 +4389 - Misses 5242 5611 +369 
Impacted FilesCoverage Δ
lightning/src/ln/functional_tests.rs98.34% <ø> (+0.11%)⬆️
lightning/src/ln/channel.rs89.49% <57.89%> (-0.33%)⬇️
lightning/src/events/mod.rs43.58% <90.00%> (+2.17%)⬆️
lightning/src/ln/channelmanager.rs87.79% <94.07%> (+1.21%)⬆️
lightning/src/ln/payment_tests.rs97.66% <98.79%> (+0.04%)⬆️
lightning/src/ln/functional_test_utils.rs87.63% <100.00%> (+0.34%)⬆️
lightning/src/ln/msgs.rs84.59% <100.00%> (+0.01%)⬆️
lightning/src/util/config.rs57.47% <100.00%> (-0.18%)⬇️

... and 11 files with indirect coverage changes

☔ View full report in Codecov by Sentry.
📢 Do you have feedback about the report comment? Let us know in this issue.

@wpaulinowpaulino added this to the 0.0.116 milestone May 25, 2023

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

At first glance this basically looks good I think.

Comment threadlightning/src/ln/channelmanager.rs Outdated
Comment threadlightning/src/ln/channelmanager.rs Outdated
@dunxen
dunxen self-requested a review June 4, 2023 20:24
@valentinewallace
valentinewallaceforce-pushed the 2023-05-forward-less-than-onion branch from 2a07438 to a1cbf67CompareJune 8, 2023 14:18
@valentinewallace
valentinewallace marked this pull request as ready for review June 8, 2023 14:21
@valentinewallace

valentinewallace commented Jun 8, 2023

Copy link
Copy Markdown
ContributorAuthor

I removed phantom support for now. Also noticed that this breaks compat for current users of UserConfig::accept_intercept_htlcs. Not sure if a release note is sufficient so thoughts welcome there. (edit: we now only break compat if the forwarder actually skims a fee)

Comment threadlightning/src/events/mod.rs Outdated
Comment threadlightning/src/ln/channel.rs Outdated
@valentinewallace
valentinewallaceforce-pushed the 2023-05-forward-less-than-onion branch from a1cbf67 to db93d1bCompareJune 9, 2023 14:28
@tnull
tnull self-requested a review June 9, 2023 21:39

@alecchendevalecchendev left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nice!

Comment threadlightning/src/ln/channelmanager.rs Outdated
Comment threadlightning/src/ln/msgs.rs
Comment threadlightning/src/ln/channelmanager.rs Outdated
payment_hash,
purpose: purpose(),
amount_msat,
counterparty_skimmed_fee_msat: total_value.saturating_sub(amount_msat),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

In the case where a counterparty overshoots the amount in the onion, I think this would report the skimmed fee inaccurately? E.g. the counterparty_skimmed_fee_msat would be offset by amount_msat - total_value. It probably wouldn't happen very often and the offset probably wouldn't be much, but figured I'd still make note of it.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Yeah, I think this field will be inaccurate if some non-penultimate intermediate node took took less fee than intended by the sender (if I understand you correctly), but I'm not sure if we're able to detect that? IIUC we only have sender_intended_total and actual_received_total to work off of here, though might be missing something.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think it'd be possible by adding the skimmed fee to PendingHTLCRouting::Receive/ReceiveKeysend (which seems possible since the skimmed fee gets sent through construct_recv_pending_htlc_info), and then probably keeping this on ClaimableHTLC and using those when finally calculating? Not sure if it's worth trying to fit it in here, could maybe be followup

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Yea, I think this would be nice, otherwise an intermediary node can cause a payment to fail by not taking enough fee? Its not itself a super big deal, but I think you could use it to figure out if the destination node is an LSP Client and if so a recent one - eg if you have a guess that the ultimate node is one further than some large LSP you could short yourself 1 msat and see if the payment fails to see if its an LSP client or just a routing node peer?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Nice catch! Fixed. I didn't want to just trust whatever the counterparty set as the skimmed fee since they could technically lie about that, so it's now a mix of the previous and new solution, PTAL.

@tnulltnull left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Looks good to me after a quick initial pass.

I wonder if it would be nice to also expose the counterparty_skimmed_fee_msat field via PaymentClaimed?

Comment threadlightning/src/util/config.rs Outdated
Comment threadlightning/src/util/config.rs Outdated
Comment threadlightning/src/util/config.rs Outdated
@valentinewallace

Copy link
Copy Markdown
ContributorAuthor

I wonder if it would be nice to also expose the counterparty_skimmed_fee_msat field via PaymentClaimed?

Added a TODO for this to #1999

@TheBlueMatt

Copy link
Copy Markdown
Collaborator

Feel free to squash IMO.

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Will need a small rebase after #2077

Comment threadlightning/src/events/mod.rs
Comment threadlightning/src/ln/channelmanager.rs Outdated
payment_hash,
purpose: purpose(),
amount_msat,
counterparty_skimmed_fee_msat: total_value.saturating_sub(amount_msat),

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Yea, I think this would be nice, otherwise an intermediary node can cause a payment to fail by not taking enough fee? Its not itself a super big deal, but I think you could use it to figure out if the destination node is an LSP Client and if so a recent one - eg if you have a guess that the ultimate node is one further than some large LSP you could short yourself 1 msat and see if the payment fails to see if its an LSP client or just a routing node peer?

Comment threadlightning/src/ln/channelmanager.rs Outdated
onion_packet,
short_channel_id: next_hop_scid,
skimmed_fee_msat:
// The minuend here must match the expected forward amount generated for the

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

TIL what minuend means.

Comment threadlightning/src/ln/channelmanager.rs Outdated
skimmed_fee_msat:
// The minuend here must match the expected forward amount generated for the
// HTLCIntercepted event.
Some(payment.forward_info.outgoing_amt_msat.saturating_sub(amt_to_forward_msat)),

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This should be None if we're not subtracting anything. Also do we want to fail if the resulting amount is zero?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Switched to None. I don't think we should fail if we forward more than expected, since the docs already say we allow this?

@valentinewallace

Copy link
Copy Markdown
ContributorAuthor

Rebased on #2077 to get a head start on rebase conflicts.

@valentinewallace
valentinewallaceforce-pushed the 2023-05-forward-less-than-onion branch 2 times, most recently from 45a7180 to 703b03aCompareJune 16, 2023 15:26
Comment threadlightning/src/ln/channelmanager.rs Outdated
Comment threadlightning/src/ln/channelmanager.rs Outdated
Comment threadlightning/src/util/config.rs Outdated
Comment threadpending_changelog/forward-underpaying-htlc.txt
Comment threadlightning/src/ln/channelmanager.rs Outdated
@valentinewallace
valentinewallaceforce-pushed the 2023-05-forward-less-than-onion branch from 703b03a to 1c63f20CompareJune 20, 2023 16:29

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

LGTM, one real comment and a nit, feel free to squash.

Comment threadlightning/src/ln/channelmanager.rs
Comment threadlightning/src/ln/channel.rs
@TheBlueMattTheBlueMatt modified the milestones: 0.0.116, 0.0.116alphaJun 20, 2023

@alecchendevalecchendev left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM I think!

Comment threadlightning/src/util/config.rs Outdated
Comment on lines +412 to +416
/// # Note
/// It's important for payee wallet software to verify that [`PaymentClaimable::amount_msat`] is
/// as-expected if this feature is activated, otherwise they may lose money!
/// [`PaymentClaimable::counterparty_skimmed_fee_msat`] provides the fee taken by the
/// counterparty.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Not sure if it's worth mentioning here or is maybe more fit for an LSP client spec, but I think the attack described in #2319 (comment) is still possible if the payee fails a payment based on the skimmed fee being too high instead of just checking amount_msat and that the sum of amount_msat + counterparty_skimmed_fee_msat add up to at least what they expected. The docs here already only say to check amount_msat so I think it's probably fine as is but figured I'd still make note of it :)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I don't think so? If the fee skimmed is too high that means the immediately-prior node took too much, if a node prior to that in the path took too much it should result in the second-to-last hop taking too little (if they're taking a percentage fee).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Oh my bad, for some reason I was thinking intermediate nodes could still affect the final skimmed fee but that was fixed, oops

@valentinewallace
valentinewallaceforce-pushed the 2023-05-forward-less-than-onion branch 2 times, most recently from 646a030 to 134e631CompareJune 20, 2023 21:57
We need the channel lock for constructing a pending HTLC's status because we
need to know if the channel accepts underpaying HTLCs in upcoming commits.
See ChannelConfig::accept_underpaying_htlcs
Receivers need to use this value to verify incoming payments if
ChannelConfig::accept_underpaying_htlcs is set.
Used to get an accurate skimmed fee in the resulting PaymentClaimable event.
Useful for penultimate hops in routes to take an extra fee, if for example they
opened a JIT channel to the payee and want them to help bear the channel open
cost.
So the receiver can verify it and approve underpaying HTLCs (see
ChannelConfig::accept_underpaying_htlcs).
Make sure the penultimate hop took the amount of fee that they claimed to take.
Without checking this TLV, we're heavily relying on the receiving wallet code
to correctly implement logic to calculate that that the fee is as expected.
@valentinewallace
valentinewallaceforce-pushed the 2023-05-forward-less-than-onion branch from 134e631 to 2127eb8CompareJune 20, 2023 21:57
@valentinewallace

Copy link
Copy Markdown
ContributorAuthor

Squashed.

first_hop_htlc_msat: htlc_msat,
payment_id,
}, onion_packet, &self.logger);
}, onion_packet, None, &self.logger);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

We probably need, as a followup, to support setting this - if you're an LSP and want to be the first payment to a given client you'll need it to take a fee on the first hop. Ideally we'd have something to handle that, but right now I don't think we will let you "just" send a payment to an intercept SCID, which we may consider.

@tnull
tnull merged commit 15b1c9b into lightningdevkit:mainJun 21, 2023
@TheBlueMattTheBlueMatt modified the milestones: 0.0.116alpha, 0.0.116Jun 24, 2023
Sign up for freeto 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.

6 participants

@valentinewallace@codecov-commenter@TheBlueMatt@tnull@alecchendev@wpaulino
, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Allow forwarding less than the amount in the onion by valentinewallace · Pull Request #2319 · lightningdevkit/rust-lightning · GitHub
Skip to content

Allow forwarding less than the amount in the onion - #2319

Merged
tnull merged 12 commits into
lightningdevkit:mainfrom
valentinewallace:2023-05-forward-less-than-onion
Jun 21, 2023
Merged

Allow forwarding less than the amount in the onion #2319
tnull merged 12 commits into
lightningdevkit:mainfrom
valentinewallace:2023-05-forward-less-than-onion

Conversation

@valentinewallace

@valentinewallacevalentinewallace commented May 25, 2023

Copy link
Copy Markdown
Contributor

Support skimming an additional fee off of intercepted HTLCs, per lightning/blips#25.

V1 of addressing #1999
Based on #2305

@valentinewallace
valentinewallaceforce-pushed the 2023-05-forward-less-than-onion branch from ad259dd to 2a07438CompareMay 25, 2023 18:49
@codecov-commenter

codecov-commenter commented May 25, 2023

Copy link
Copy Markdown

Codecov Report

Patch coverage: 90.61% and project coverage change: +0.15 🎉

Comparison is base (ae9e96e) 90.35% compared to head (2127eb8) 90.50%.

❗ 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 #2319 +/- ##
==========================================
+ Coverage 90.35% 90.50% +0.15% 
==========================================
Files 106 106 Lines 54347 59105 +4758 Branches 54347 59105 +4758 ==========================================
+ Hits 49105 53494 +4389 - Misses 5242 5611 +369 
Impacted FilesCoverage Δ
lightning/src/ln/functional_tests.rs98.34% <ø> (+0.11%)⬆️
lightning/src/ln/channel.rs89.49% <57.89%> (-0.33%)⬇️
lightning/src/events/mod.rs43.58% <90.00%> (+2.17%)⬆️
lightning/src/ln/channelmanager.rs87.79% <94.07%> (+1.21%)⬆️
lightning/src/ln/payment_tests.rs97.66% <98.79%> (+0.04%)⬆️
lightning/src/ln/functional_test_utils.rs87.63% <100.00%> (+0.34%)⬆️
lightning/src/ln/msgs.rs84.59% <100.00%> (+0.01%)⬆️
lightning/src/util/config.rs57.47% <100.00%> (-0.18%)⬇️

... and 11 files with indirect coverage changes

☔ View full report in Codecov by Sentry.
📢 Do you have feedback about the report comment? Let us know in this issue.

@wpaulinowpaulino added this to the 0.0.116 milestone May 25, 2023

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

At first glance this basically looks good I think.

Comment threadlightning/src/ln/channelmanager.rs Outdated
Comment threadlightning/src/ln/channelmanager.rs Outdated
@dunxen
dunxen self-requested a review June 4, 2023 20:24
@valentinewallace
valentinewallaceforce-pushed the 2023-05-forward-less-than-onion branch from 2a07438 to a1cbf67CompareJune 8, 2023 14:18
@valentinewallace
valentinewallace marked this pull request as ready for review June 8, 2023 14:21
@valentinewallace

valentinewallace commented Jun 8, 2023

Copy link
Copy Markdown
ContributorAuthor

I removed phantom support for now. Also noticed that this breaks compat for current users of UserConfig::accept_intercept_htlcs. Not sure if a release note is sufficient so thoughts welcome there. (edit: we now only break compat if the forwarder actually skims a fee)

Comment threadlightning/src/events/mod.rs Outdated
Comment threadlightning/src/ln/channel.rs Outdated
@valentinewallace
valentinewallaceforce-pushed the 2023-05-forward-less-than-onion branch from a1cbf67 to db93d1bCompareJune 9, 2023 14:28
@tnull
tnull self-requested a review June 9, 2023 21:39

@alecchendevalecchendev left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nice!

Comment threadlightning/src/ln/channelmanager.rs Outdated
Comment threadlightning/src/ln/msgs.rs
Comment threadlightning/src/ln/channelmanager.rs Outdated
payment_hash,
purpose: purpose(),
amount_msat,
counterparty_skimmed_fee_msat: total_value.saturating_sub(amount_msat),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

In the case where a counterparty overshoots the amount in the onion, I think this would report the skimmed fee inaccurately? E.g. the counterparty_skimmed_fee_msat would be offset by amount_msat - total_value. It probably wouldn't happen very often and the offset probably wouldn't be much, but figured I'd still make note of it.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Yeah, I think this field will be inaccurate if some non-penultimate intermediate node took took less fee than intended by the sender (if I understand you correctly), but I'm not sure if we're able to detect that? IIUC we only have sender_intended_total and actual_received_total to work off of here, though might be missing something.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think it'd be possible by adding the skimmed fee to PendingHTLCRouting::Receive/ReceiveKeysend (which seems possible since the skimmed fee gets sent through construct_recv_pending_htlc_info), and then probably keeping this on ClaimableHTLC and using those when finally calculating? Not sure if it's worth trying to fit it in here, could maybe be followup

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Yea, I think this would be nice, otherwise an intermediary node can cause a payment to fail by not taking enough fee? Its not itself a super big deal, but I think you could use it to figure out if the destination node is an LSP Client and if so a recent one - eg if you have a guess that the ultimate node is one further than some large LSP you could short yourself 1 msat and see if the payment fails to see if its an LSP client or just a routing node peer?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Nice catch! Fixed. I didn't want to just trust whatever the counterparty set as the skimmed fee since they could technically lie about that, so it's now a mix of the previous and new solution, PTAL.

@tnulltnull left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Looks good to me after a quick initial pass.

I wonder if it would be nice to also expose the counterparty_skimmed_fee_msat field via PaymentClaimed?

Comment threadlightning/src/util/config.rs Outdated
Comment threadlightning/src/util/config.rs Outdated
Comment threadlightning/src/util/config.rs Outdated
@valentinewallace

Copy link
Copy Markdown
ContributorAuthor

I wonder if it would be nice to also expose the counterparty_skimmed_fee_msat field via PaymentClaimed?

Added a TODO for this to #1999

@TheBlueMatt

Copy link
Copy Markdown
Collaborator

Feel free to squash IMO.

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Will need a small rebase after #2077

Comment threadlightning/src/events/mod.rs
Comment threadlightning/src/ln/channelmanager.rs Outdated
payment_hash,
purpose: purpose(),
amount_msat,
counterparty_skimmed_fee_msat: total_value.saturating_sub(amount_msat),

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Yea, I think this would be nice, otherwise an intermediary node can cause a payment to fail by not taking enough fee? Its not itself a super big deal, but I think you could use it to figure out if the destination node is an LSP Client and if so a recent one - eg if you have a guess that the ultimate node is one further than some large LSP you could short yourself 1 msat and see if the payment fails to see if its an LSP client or just a routing node peer?

Comment threadlightning/src/ln/channelmanager.rs Outdated
onion_packet,
short_channel_id: next_hop_scid,
skimmed_fee_msat:
// The minuend here must match the expected forward amount generated for the

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

TIL what minuend means.

Comment threadlightning/src/ln/channelmanager.rs Outdated
skimmed_fee_msat:
// The minuend here must match the expected forward amount generated for the
// HTLCIntercepted event.
Some(payment.forward_info.outgoing_amt_msat.saturating_sub(amt_to_forward_msat)),

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This should be None if we're not subtracting anything. Also do we want to fail if the resulting amount is zero?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Switched to None. I don't think we should fail if we forward more than expected, since the docs already say we allow this?

@valentinewallace

Copy link
Copy Markdown
ContributorAuthor

Rebased on #2077 to get a head start on rebase conflicts.

@valentinewallace
valentinewallaceforce-pushed the 2023-05-forward-less-than-onion branch 2 times, most recently from 45a7180 to 703b03aCompareJune 16, 2023 15:26
Comment threadlightning/src/ln/channelmanager.rs Outdated
Comment threadlightning/src/ln/channelmanager.rs Outdated
Comment threadlightning/src/util/config.rs Outdated
Comment threadpending_changelog/forward-underpaying-htlc.txt
Comment threadlightning/src/ln/channelmanager.rs Outdated
@valentinewallace
valentinewallaceforce-pushed the 2023-05-forward-less-than-onion branch from 703b03a to 1c63f20CompareJune 20, 2023 16:29

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

LGTM, one real comment and a nit, feel free to squash.

Comment threadlightning/src/ln/channelmanager.rs
Comment threadlightning/src/ln/channel.rs
@TheBlueMattTheBlueMatt modified the milestones: 0.0.116, 0.0.116alphaJun 20, 2023

@alecchendevalecchendev left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM I think!

Comment threadlightning/src/util/config.rs Outdated
Comment on lines +412 to +416
/// # Note
/// It's important for payee wallet software to verify that [`PaymentClaimable::amount_msat`] is
/// as-expected if this feature is activated, otherwise they may lose money!
/// [`PaymentClaimable::counterparty_skimmed_fee_msat`] provides the fee taken by the
/// counterparty.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Not sure if it's worth mentioning here or is maybe more fit for an LSP client spec, but I think the attack described in #2319 (comment) is still possible if the payee fails a payment based on the skimmed fee being too high instead of just checking amount_msat and that the sum of amount_msat + counterparty_skimmed_fee_msat add up to at least what they expected. The docs here already only say to check amount_msat so I think it's probably fine as is but figured I'd still make note of it :)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I don't think so? If the fee skimmed is too high that means the immediately-prior node took too much, if a node prior to that in the path took too much it should result in the second-to-last hop taking too little (if they're taking a percentage fee).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Oh my bad, for some reason I was thinking intermediate nodes could still affect the final skimmed fee but that was fixed, oops

@valentinewallace
valentinewallaceforce-pushed the 2023-05-forward-less-than-onion branch 2 times, most recently from 646a030 to 134e631CompareJune 20, 2023 21:57
We need the channel lock for constructing a pending HTLC's status because we
need to know if the channel accepts underpaying HTLCs in upcoming commits.
See ChannelConfig::accept_underpaying_htlcs
Receivers need to use this value to verify incoming payments if
ChannelConfig::accept_underpaying_htlcs is set.
Used to get an accurate skimmed fee in the resulting PaymentClaimable event.
Useful for penultimate hops in routes to take an extra fee, if for example they
opened a JIT channel to the payee and want them to help bear the channel open
cost.
So the receiver can verify it and approve underpaying HTLCs (see
ChannelConfig::accept_underpaying_htlcs).
Make sure the penultimate hop took the amount of fee that they claimed to take.
Without checking this TLV, we're heavily relying on the receiving wallet code
to correctly implement logic to calculate that that the fee is as expected.
@valentinewallace
valentinewallaceforce-pushed the 2023-05-forward-less-than-onion branch from 134e631 to 2127eb8CompareJune 20, 2023 21:57
@valentinewallace

Copy link
Copy Markdown
ContributorAuthor

Squashed.

first_hop_htlc_msat: htlc_msat,
payment_id,
}, onion_packet, &self.logger);
}, onion_packet, None, &self.logger);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

We probably need, as a followup, to support setting this - if you're an LSP and want to be the first payment to a given client you'll need it to take a fee on the first hop. Ideally we'd have something to handle that, but right now I don't think we will let you "just" send a payment to an intercept SCID, which we may consider.

@tnull
tnull merged commit 15b1c9b into lightningdevkit:mainJun 21, 2023
@TheBlueMattTheBlueMatt modified the milestones: 0.0.116alpha, 0.0.116Jun 24, 2023
Sign up for freeto 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.

6 participants

@valentinewallace@codecov-commenter@TheBlueMatt@tnull@alecchendev@wpaulino
, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); Allow forwarding less than the amount in the onion by valentinewallace · Pull Request #2319 · lightningdevkit/rust-lightning · GitHub
Skip to content

Allow forwarding less than the amount in the onion - #2319

Merged
tnull merged 12 commits into
lightningdevkit:mainfrom
valentinewallace:2023-05-forward-less-than-onion
Jun 21, 2023
Merged

Allow forwarding less than the amount in the onion #2319
tnull merged 12 commits into
lightningdevkit:mainfrom
valentinewallace:2023-05-forward-less-than-onion

Conversation

@valentinewallace

@valentinewallacevalentinewallace commented May 25, 2023

Copy link
Copy Markdown
Contributor

Support skimming an additional fee off of intercepted HTLCs, per lightning/blips#25.

V1 of addressing #1999
Based on #2305

@valentinewallace
valentinewallaceforce-pushed the 2023-05-forward-less-than-onion branch from ad259dd to 2a07438CompareMay 25, 2023 18:49
@codecov-commenter

codecov-commenter commented May 25, 2023

Copy link
Copy Markdown

Codecov Report

Patch coverage: 90.61% and project coverage change: +0.15 🎉

Comparison is base (ae9e96e) 90.35% compared to head (2127eb8) 90.50%.

❗ 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 #2319 +/- ##
==========================================
+ Coverage 90.35% 90.50% +0.15% 
==========================================
Files 106 106 Lines 54347 59105 +4758 Branches 54347 59105 +4758 ==========================================
+ Hits 49105 53494 +4389 - Misses 5242 5611 +369 
Impacted FilesCoverage Δ
lightning/src/ln/functional_tests.rs98.34% <ø> (+0.11%)⬆️
lightning/src/ln/channel.rs89.49% <57.89%> (-0.33%)⬇️
lightning/src/events/mod.rs43.58% <90.00%> (+2.17%)⬆️
lightning/src/ln/channelmanager.rs87.79% <94.07%> (+1.21%)⬆️
lightning/src/ln/payment_tests.rs97.66% <98.79%> (+0.04%)⬆️
lightning/src/ln/functional_test_utils.rs87.63% <100.00%> (+0.34%)⬆️
lightning/src/ln/msgs.rs84.59% <100.00%> (+0.01%)⬆️
lightning/src/util/config.rs57.47% <100.00%> (-0.18%)⬇️

... and 11 files with indirect coverage changes

☔ View full report in Codecov by Sentry.
📢 Do you have feedback about the report comment? Let us know in this issue.

@wpaulinowpaulino added this to the 0.0.116 milestone May 25, 2023

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

At first glance this basically looks good I think.

Comment threadlightning/src/ln/channelmanager.rs Outdated
Comment threadlightning/src/ln/channelmanager.rs Outdated
@dunxen
dunxen self-requested a review June 4, 2023 20:24
@valentinewallace
valentinewallaceforce-pushed the 2023-05-forward-less-than-onion branch from 2a07438 to a1cbf67CompareJune 8, 2023 14:18
@valentinewallace
valentinewallace marked this pull request as ready for review June 8, 2023 14:21
@valentinewallace

valentinewallace commented Jun 8, 2023

Copy link
Copy Markdown
ContributorAuthor

I removed phantom support for now. Also noticed that this breaks compat for current users of UserConfig::accept_intercept_htlcs. Not sure if a release note is sufficient so thoughts welcome there. (edit: we now only break compat if the forwarder actually skims a fee)

Comment threadlightning/src/events/mod.rs Outdated
Comment threadlightning/src/ln/channel.rs Outdated
@valentinewallace
valentinewallaceforce-pushed the 2023-05-forward-less-than-onion branch from a1cbf67 to db93d1bCompareJune 9, 2023 14:28
@tnull
tnull self-requested a review June 9, 2023 21:39

@alecchendevalecchendev left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nice!

Comment threadlightning/src/ln/channelmanager.rs Outdated
Comment threadlightning/src/ln/msgs.rs
Comment threadlightning/src/ln/channelmanager.rs Outdated
payment_hash,
purpose: purpose(),
amount_msat,
counterparty_skimmed_fee_msat: total_value.saturating_sub(amount_msat),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

In the case where a counterparty overshoots the amount in the onion, I think this would report the skimmed fee inaccurately? E.g. the counterparty_skimmed_fee_msat would be offset by amount_msat - total_value. It probably wouldn't happen very often and the offset probably wouldn't be much, but figured I'd still make note of it.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Yeah, I think this field will be inaccurate if some non-penultimate intermediate node took took less fee than intended by the sender (if I understand you correctly), but I'm not sure if we're able to detect that? IIUC we only have sender_intended_total and actual_received_total to work off of here, though might be missing something.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think it'd be possible by adding the skimmed fee to PendingHTLCRouting::Receive/ReceiveKeysend (which seems possible since the skimmed fee gets sent through construct_recv_pending_htlc_info), and then probably keeping this on ClaimableHTLC and using those when finally calculating? Not sure if it's worth trying to fit it in here, could maybe be followup

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Yea, I think this would be nice, otherwise an intermediary node can cause a payment to fail by not taking enough fee? Its not itself a super big deal, but I think you could use it to figure out if the destination node is an LSP Client and if so a recent one - eg if you have a guess that the ultimate node is one further than some large LSP you could short yourself 1 msat and see if the payment fails to see if its an LSP client or just a routing node peer?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Nice catch! Fixed. I didn't want to just trust whatever the counterparty set as the skimmed fee since they could technically lie about that, so it's now a mix of the previous and new solution, PTAL.

@tnulltnull left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Looks good to me after a quick initial pass.

I wonder if it would be nice to also expose the counterparty_skimmed_fee_msat field via PaymentClaimed?

Comment threadlightning/src/util/config.rs Outdated
Comment threadlightning/src/util/config.rs Outdated
Comment threadlightning/src/util/config.rs Outdated
@valentinewallace

Copy link
Copy Markdown
ContributorAuthor

I wonder if it would be nice to also expose the counterparty_skimmed_fee_msat field via PaymentClaimed?

Added a TODO for this to #1999

@TheBlueMatt

Copy link
Copy Markdown
Collaborator

Feel free to squash IMO.

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Will need a small rebase after #2077

Comment threadlightning/src/events/mod.rs
Comment threadlightning/src/ln/channelmanager.rs Outdated
payment_hash,
purpose: purpose(),
amount_msat,
counterparty_skimmed_fee_msat: total_value.saturating_sub(amount_msat),

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Yea, I think this would be nice, otherwise an intermediary node can cause a payment to fail by not taking enough fee? Its not itself a super big deal, but I think you could use it to figure out if the destination node is an LSP Client and if so a recent one - eg if you have a guess that the ultimate node is one further than some large LSP you could short yourself 1 msat and see if the payment fails to see if its an LSP client or just a routing node peer?

Comment threadlightning/src/ln/channelmanager.rs Outdated
onion_packet,
short_channel_id: next_hop_scid,
skimmed_fee_msat:
// The minuend here must match the expected forward amount generated for the

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

TIL what minuend means.

Comment threadlightning/src/ln/channelmanager.rs Outdated
skimmed_fee_msat:
// The minuend here must match the expected forward amount generated for the
// HTLCIntercepted event.
Some(payment.forward_info.outgoing_amt_msat.saturating_sub(amt_to_forward_msat)),

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This should be None if we're not subtracting anything. Also do we want to fail if the resulting amount is zero?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Switched to None. I don't think we should fail if we forward more than expected, since the docs already say we allow this?

@valentinewallace

Copy link
Copy Markdown
ContributorAuthor

Rebased on #2077 to get a head start on rebase conflicts.

@valentinewallace
valentinewallaceforce-pushed the 2023-05-forward-less-than-onion branch 2 times, most recently from 45a7180 to 703b03aCompareJune 16, 2023 15:26
Comment threadlightning/src/ln/channelmanager.rs Outdated
Comment threadlightning/src/ln/channelmanager.rs Outdated
Comment threadlightning/src/util/config.rs Outdated
Comment threadpending_changelog/forward-underpaying-htlc.txt
Comment threadlightning/src/ln/channelmanager.rs Outdated
@valentinewallace
valentinewallaceforce-pushed the 2023-05-forward-less-than-onion branch from 703b03a to 1c63f20CompareJune 20, 2023 16:29

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

LGTM, one real comment and a nit, feel free to squash.

Comment threadlightning/src/ln/channelmanager.rs
Comment threadlightning/src/ln/channel.rs
@TheBlueMattTheBlueMatt modified the milestones: 0.0.116, 0.0.116alphaJun 20, 2023

@alecchendevalecchendev left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM I think!

Comment threadlightning/src/util/config.rs Outdated
Comment on lines +412 to +416
/// # Note
/// It's important for payee wallet software to verify that [`PaymentClaimable::amount_msat`] is
/// as-expected if this feature is activated, otherwise they may lose money!
/// [`PaymentClaimable::counterparty_skimmed_fee_msat`] provides the fee taken by the
/// counterparty.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Not sure if it's worth mentioning here or is maybe more fit for an LSP client spec, but I think the attack described in #2319 (comment) is still possible if the payee fails a payment based on the skimmed fee being too high instead of just checking amount_msat and that the sum of amount_msat + counterparty_skimmed_fee_msat add up to at least what they expected. The docs here already only say to check amount_msat so I think it's probably fine as is but figured I'd still make note of it :)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I don't think so? If the fee skimmed is too high that means the immediately-prior node took too much, if a node prior to that in the path took too much it should result in the second-to-last hop taking too little (if they're taking a percentage fee).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Oh my bad, for some reason I was thinking intermediate nodes could still affect the final skimmed fee but that was fixed, oops

@valentinewallace
valentinewallaceforce-pushed the 2023-05-forward-less-than-onion branch 2 times, most recently from 646a030 to 134e631CompareJune 20, 2023 21:57
We need the channel lock for constructing a pending HTLC's status because we
need to know if the channel accepts underpaying HTLCs in upcoming commits.
See ChannelConfig::accept_underpaying_htlcs
Receivers need to use this value to verify incoming payments if
ChannelConfig::accept_underpaying_htlcs is set.
Used to get an accurate skimmed fee in the resulting PaymentClaimable event.
Useful for penultimate hops in routes to take an extra fee, if for example they
opened a JIT channel to the payee and want them to help bear the channel open
cost.
So the receiver can verify it and approve underpaying HTLCs (see
ChannelConfig::accept_underpaying_htlcs).
Make sure the penultimate hop took the amount of fee that they claimed to take.
Without checking this TLV, we're heavily relying on the receiving wallet code
to correctly implement logic to calculate that that the fee is as expected.
@valentinewallace
valentinewallaceforce-pushed the 2023-05-forward-less-than-onion branch from 134e631 to 2127eb8CompareJune 20, 2023 21:57
@valentinewallace

Copy link
Copy Markdown
ContributorAuthor

Squashed.

first_hop_htlc_msat: htlc_msat,
payment_id,
}, onion_packet, &self.logger);
}, onion_packet, None, &self.logger);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

We probably need, as a followup, to support setting this - if you're an LSP and want to be the first payment to a given client you'll need it to take a fee on the first hop. Ideally we'd have something to handle that, but right now I don't think we will let you "just" send a payment to an intercept SCID, which we may consider.

@tnull
tnull merged commit 15b1c9b into lightningdevkit:mainJun 21, 2023
@TheBlueMattTheBlueMatt modified the milestones: 0.0.116alpha, 0.0.116Jun 24, 2023
Sign up for freeto 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.

6 participants

@valentinewallace@codecov-commenter@TheBlueMatt@tnull@alecchendev@wpaulino