Fix some onion errors and assert their length is correct - #1895

Merged
TheBlueMatt merged 12 commits into
lightningdevkit:mainfrom
TheBlueMatt:2022-12-fix-missing-data
Dec 6, 2022
Merged

Fix some onion errors and assert their length is correct#1895
TheBlueMatt merged 12 commits into
lightningdevkit:mainfrom
TheBlueMatt:2022-12-fix-missing-data

Conversation

@TheBlueMatt

Copy link
Copy Markdown
Collaborator

When we're constructing an HTLCFailReason, we should check that we
set the data to at least the correct length for the given failure
code, which we do here.

First we move HTLCFailReason into onion_utils and encapsulate it a bit better, making channelmanager just a bit smaller. Then we can assert the length, but only after fixing a few issues.

Fixes#1879 but I'm frankly a bit confused - I don't see the 14@valentinewallace claimed was being used incorrectly in phantom failures - maybe it was already fixed?

@TheBlueMattTheBlueMatt added this to the 0.0.113 milestone Dec 1, 2022
@TheBlueMatt
TheBlueMattforce-pushed the 2022-12-fix-missing-data branch from 7e29b27 to db345a5CompareDecember 1, 2022 21:54
@valentinewallace

Copy link
Copy Markdown
Contributor

I think this was it, so | 13: https://github.com/lightningdevkit/rust-lightning/blob/main/lightning/src/ln/channelmanager.rs#L2301. That scope will also set chan_update_opt to None, would have to check if any of the expiry checks below are reachable for phantom payments

@codecov-commenter

codecov-commenter commented Dec 1, 2022

Copy link
Copy Markdown

Codecov Report

Base: 90.69% // Head: 90.63% // Decreases project coverage by -0.05%⚠️

Coverage data is based on head (878a41f) compared to base (4dafa43).
Patch coverage: 92.69% of modified lines in pull request are covered.

❗ Current head 878a41f differs from pull request most recent head c9fe69f. Consider uploading reports for the commit c9fe69f to get more accurate results

Additional details and impacted files
@@ Coverage Diff @@## main #1895 +/- ##
==========================================
- Coverage 90.69% 90.63% -0.06% 
==========================================
Files 91 91 Lines 48404 51171 +2767 Branches 48404 51171 +2767 ==========================================
+ Hits 43898 46380 +2482 - Misses 4506 4791 +285 
Impacted FilesCoverage Δ
lightning/src/ln/channel.rs89.14% <ø> (+0.29%)⬆️
lightning/src/util/ser_macros.rs87.19% <0.00%> (ø)
lightning/src/ln/onion_utils.rs93.56% <86.58%> (-1.37%)⬇️
lightning/src/ln/channelmanager.rs87.15% <97.43%> (+0.88%)⬆️
lightning/src/ln/onion_route_tests.rs97.65% <100.00%> (+0.16%)⬆️
lightning/src/util/persist.rs94.44% <0.00%> (-0.80%)⬇️
lightning/src/util/events.rs24.56% <0.00%> (-0.44%)⬇️
lightning/src/ln/payment_tests.rs98.45% <0.00%> (-0.28%)⬇️
lightning/src/ln/functional_tests.rs96.96% <0.00%> (-0.12%)⬇️
... and 9 more

Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here.

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

@TheBlueMatt
TheBlueMattforce-pushed the 2022-12-fix-missing-data branch from db345a5 to 99c91bdCompareDecember 1, 2022 23:42
@TheBlueMatt

Copy link
Copy Markdown
CollaboratorAuthor

Ah, thanks, fixed.

@TheBlueMatt
TheBlueMattforce-pushed the 2022-12-fix-missing-data branch from 99c91bd to 22d94a8CompareDecember 2, 2022 01:23
Comment threadlightning/src/ln/channelmanager.rs Outdated
Comment on lines 51 to +52
use crate::ln::onion_utils;
use crate::ln::onion_utils::HTLCFailReason;

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.

nit:

Suggested change
usecrate::ln::onion_utils;
usecrate::ln::onion_utils::HTLCFailReason;
usecrate::ln::onion_utils::{self,HTLCFailReason};

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

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

I find the original more readable 🤷

Comment threadlightning/src/ln/onion_utils.rs Outdated
Comment threadlightning/src/ln/onion_utils.rs Outdated
Comment threadlightning/src/ln/channelmanager.rs
Comment threadlightning/src/ln/onion_utils.rs Outdated
Comment on lines +666 to +672
// we get a fail_malformed_htlc from the first hop
// TODO: We'd like to generate a NetworkUpdate for temporary
// failures here, but that would be insufficient as find_route
// generally ignores its view of our own channels as we provide them via
// ChannelDetails.
// TODO: For non-temporary failures, we really should be closing the
// channel here as we apparently can't relay through them anyway.

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.

Do these comments still make sense here, or should they stay in fail_backwards_internal?

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

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

The first TODO belongs here I think - it talks about building a NetworkUpdate which this fn is responsible for. The second we could debate but there's already a TODO that is equivalent at the callsite talking about if we blame our own channel.

@TheBlueMatt
TheBlueMattforce-pushed the 2022-12-fix-missing-data branch from 22d94a8 to af89d18CompareDecember 2, 2022 20:42
@valentinewallace

Copy link
Copy Markdown
Contributor

This test hits one of the new debug panics in HTLCFailReason::reason:

#[test]
fn test_phantom_failure_expires_too_soon() {
// Test that we fail back phantoms if the upstream node fiddled with the CLTV too much with the
// correct error code.
let chanmon_cfgs = create_chanmon_cfgs(2);
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
let channel = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
// Get the route.
let recv_value_msat = 10_000;
let (_, payment_hash, payment_secret) = get_payment_preimage_hash!(nodes[1], Some(recv_value_msat));
let (mut route, phantom_scid) = get_phantom_route!(nodes, recv_value_msat, channel);
// Route the HTLC through to the destination.
nodes[0].node.send_payment(&route, payment_hash, &Some(payment_secret), PaymentId(payment_hash.0)).unwrap();
check_added_monitors!(nodes[0], 1);
let update_0 = get_htlc_update_msgs!(nodes[0], nodes[1].node.get_our_node_id());
let mut update_add = update_0.update_add_htlcs[0].clone();
// Modify the route to have a too-low cltv.
// update_add.cltv_expiry += CLTV_FAR_FAR_AWAY;
connect_blocks(&nodes[1], 72);
nodes[1].node.handle_update_add_htlc(&nodes[0].node.get_our_node_id(), &update_add);
commitment_signed_dance!(nodes[1], nodes[0], &update_0.commitment_signed, false, true);
let update_1 = get_htlc_update_msgs!(nodes[1], nodes[0].node.get_our_node_id());
assert!(update_1.update_fail_htlcs.len() == 1);
let fail_msg = update_1.update_fail_htlcs[0].clone();
nodes[0].node.handle_update_fail_htlc(&nodes[1].node.get_our_node_id(), &fail_msg);
commitment_signed_dance!(nodes[0], nodes[1], update_1.commitment_signed, false);
// Ensure the payment fails with the expected error.
let mut fail_conditions = PaymentFailedConditions::new()
.blamed_scid(phantom_scid)
.expected_htlc_error_data(0x1000 | 14, &[]);
expect_payment_failed_conditions(&nodes[0], payment_hash, false, fail_conditions);
}

I think the other phantom 0x1000|14 error would hit the panic as well. I guess the lack of test coverage here is on me 😅

@valentinewallacevalentinewallace 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.

Really nice cleanup, basically LGTM

Comment threadlightning/src/ln/channelmanager.rs Outdated
Comment threadlightning/src/ln/onion_route_tests.rs Outdated
Comment threadlightning/src/ln/onion_utils.rs Outdated
// ChannelDetails.
if let &HTLCSource::OutboundRoute { ref path, .. } = htlc_source {
(None, Some(path.first().unwrap().short_channel_id), true, Some(*failure_code), Some(data.clone()))
} else { unreachable!(); }

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.

It'd remove some unreachables to make HTLCSource::OutboundRoute have an inner struct, but I think that'd be a future consideration

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

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

Yea, we should, agree it doesnt need to happen here.

@TheBlueMatt
TheBlueMattforce-pushed the 2022-12-fix-missing-data branch from a663ab2 to 35d8eb3CompareDecember 5, 2022 19:13
Comment threadlightning/src/ln/onion_utils.rs

@valentinewallacevalentinewallace 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 after squash

Now that it's entirely abstracted, there's no reason for
`HTLCFailReason` to be in `channelmanager`, it's really an
onion-level abstraction.
Now that `HTLCFailReason` is opaque and in `onion_utils`, we should
encapsulate it so that `ChannelManager` can no longer directly
access its inner fields.
This replaces `final_expiry_too_soon` with
`incorrect_or_unknown_payment` as was done in
lightning/bolts#608. Note that the
rationale for this (that it may expose whether you are the final
recipient for the payment or not) does not currently apply to us -
we don't apply different final CLTV values to different payments.
However, we might in the future, and this will make us slightly
more consistent with other nodes.
The spec mandates that we copy the `sha256_hash_of_onion` field
from the `UpdateFailMalformedHTLC` message into the error message
we send back to the sender, however we simply ignored it. Here we
copy it into the message correctly.
When we're constructing an HTLCFailReason, we should check that we
set the data to at least the correct length for the given failure
code, which we do here.
When we receive a phantom HTLC with a bogus/modified CLTV, we
should fail back with `incorrect_cltv_expiry`, but that requires a
`channel_update`, which we cannot generate for a phantom HTLC which
has no corresponding channel. Thus, instead, we have to fall back
to `incorrect_cltv_expiry`.
Fixeslightningdevkit#1879
This ensures we always hit our new debug assertions while building
failure packets in the immediately-fail pipeline while processing
an inbound HTLC.
If we try to send any onion error with the `UPDATE` flag in
response to a phantom receipt, we should always swap it for
something generic that doesn't require a `channel_update` in it.
Here we use `temporary_node_failure`.
Test provided by Valentine Wallace <vwallace@protonmail.com>
@TheBlueMatt
TheBlueMattforce-pushed the 2022-12-fix-missing-data branch from 878a41f to c9fe69fCompareDecember 6, 2022 20:00
@TheBlueMatt

Copy link
Copy Markdown
CollaboratorAuthor

Squashed without further changes.

@TheBlueMatt
TheBlueMatt merged commit 2390dbc into lightningdevkit:mainDec 6, 2022
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.

Ensure UPDATE errors have an update

4 participants

@TheBlueMatt@valentinewallace@codecov-commenter@wpaulino
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n 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;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Fix some onion errors and assert their length is correct - #1895

Merged
TheBlueMatt merged 12 commits into
lightningdevkit:mainfrom
TheBlueMatt:2022-12-fix-missing-data
Dec 6, 2022
Merged

Fix some onion errors and assert their length is correct#1895
TheBlueMatt merged 12 commits into
lightningdevkit:mainfrom
TheBlueMatt:2022-12-fix-missing-data

Conversation

@TheBlueMatt

Copy link
Copy Markdown
Collaborator

When we're constructing an HTLCFailReason, we should check that we
set the data to at least the correct length for the given failure
code, which we do here.

First we move HTLCFailReason into onion_utils and encapsulate it a bit better, making channelmanager just a bit smaller. Then we can assert the length, but only after fixing a few issues.

Fixes#1879 but I'm frankly a bit confused - I don't see the 14@valentinewallace claimed was being used incorrectly in phantom failures - maybe it was already fixed?

@TheBlueMattTheBlueMatt added this to the 0.0.113 milestone Dec 1, 2022
@TheBlueMatt
TheBlueMattforce-pushed the 2022-12-fix-missing-data branch from 7e29b27 to db345a5CompareDecember 1, 2022 21:54
@valentinewallace

Copy link
Copy Markdown
Contributor

I think this was it, so | 13: https://github.com/lightningdevkit/rust-lightning/blob/main/lightning/src/ln/channelmanager.rs#L2301. That scope will also set chan_update_opt to None, would have to check if any of the expiry checks below are reachable for phantom payments

@codecov-commenter

codecov-commenter commented Dec 1, 2022

Copy link
Copy Markdown

Codecov Report

Base: 90.69% // Head: 90.63% // Decreases project coverage by -0.05%⚠️

Coverage data is based on head (878a41f) compared to base (4dafa43).
Patch coverage: 92.69% of modified lines in pull request are covered.

❗ Current head 878a41f differs from pull request most recent head c9fe69f. Consider uploading reports for the commit c9fe69f to get more accurate results

Additional details and impacted files
@@ Coverage Diff @@## main #1895 +/- ##
==========================================
- Coverage 90.69% 90.63% -0.06% 
==========================================
Files 91 91 Lines 48404 51171 +2767 Branches 48404 51171 +2767 ==========================================
+ Hits 43898 46380 +2482 - Misses 4506 4791 +285 
Impacted FilesCoverage Δ
lightning/src/ln/channel.rs89.14% <ø> (+0.29%)⬆️
lightning/src/util/ser_macros.rs87.19% <0.00%> (ø)
lightning/src/ln/onion_utils.rs93.56% <86.58%> (-1.37%)⬇️
lightning/src/ln/channelmanager.rs87.15% <97.43%> (+0.88%)⬆️
lightning/src/ln/onion_route_tests.rs97.65% <100.00%> (+0.16%)⬆️
lightning/src/util/persist.rs94.44% <0.00%> (-0.80%)⬇️
lightning/src/util/events.rs24.56% <0.00%> (-0.44%)⬇️
lightning/src/ln/payment_tests.rs98.45% <0.00%> (-0.28%)⬇️
lightning/src/ln/functional_tests.rs96.96% <0.00%> (-0.12%)⬇️
... and 9 more

Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here.

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

@TheBlueMatt
TheBlueMattforce-pushed the 2022-12-fix-missing-data branch from db345a5 to 99c91bdCompareDecember 1, 2022 23:42
@TheBlueMatt

Copy link
Copy Markdown
CollaboratorAuthor

Ah, thanks, fixed.

@TheBlueMatt
TheBlueMattforce-pushed the 2022-12-fix-missing-data branch from 99c91bd to 22d94a8CompareDecember 2, 2022 01:23
Comment threadlightning/src/ln/channelmanager.rs Outdated
Comment on lines 51 to +52
use crate::ln::onion_utils;
use crate::ln::onion_utils::HTLCFailReason;

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.

nit:

Suggested change
usecrate::ln::onion_utils;
usecrate::ln::onion_utils::HTLCFailReason;
usecrate::ln::onion_utils::{self,HTLCFailReason};

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

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

I find the original more readable 🤷

Comment threadlightning/src/ln/onion_utils.rs Outdated
Comment threadlightning/src/ln/onion_utils.rs Outdated
Comment threadlightning/src/ln/channelmanager.rs
Comment threadlightning/src/ln/onion_utils.rs Outdated
Comment on lines +666 to +672
// we get a fail_malformed_htlc from the first hop
// TODO: We'd like to generate a NetworkUpdate for temporary
// failures here, but that would be insufficient as find_route
// generally ignores its view of our own channels as we provide them via
// ChannelDetails.
// TODO: For non-temporary failures, we really should be closing the
// channel here as we apparently can't relay through them anyway.

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.

Do these comments still make sense here, or should they stay in fail_backwards_internal?

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

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

The first TODO belongs here I think - it talks about building a NetworkUpdate which this fn is responsible for. The second we could debate but there's already a TODO that is equivalent at the callsite talking about if we blame our own channel.

@TheBlueMatt
TheBlueMattforce-pushed the 2022-12-fix-missing-data branch from 22d94a8 to af89d18CompareDecember 2, 2022 20:42
@valentinewallace

Copy link
Copy Markdown
Contributor

This test hits one of the new debug panics in HTLCFailReason::reason:

#[test]
fn test_phantom_failure_expires_too_soon() {
// Test that we fail back phantoms if the upstream node fiddled with the CLTV too much with the
// correct error code.
let chanmon_cfgs = create_chanmon_cfgs(2);
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
let channel = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
// Get the route.
let recv_value_msat = 10_000;
let (_, payment_hash, payment_secret) = get_payment_preimage_hash!(nodes[1], Some(recv_value_msat));
let (mut route, phantom_scid) = get_phantom_route!(nodes, recv_value_msat, channel);
// Route the HTLC through to the destination.
nodes[0].node.send_payment(&route, payment_hash, &Some(payment_secret), PaymentId(payment_hash.0)).unwrap();
check_added_monitors!(nodes[0], 1);
let update_0 = get_htlc_update_msgs!(nodes[0], nodes[1].node.get_our_node_id());
let mut update_add = update_0.update_add_htlcs[0].clone();
// Modify the route to have a too-low cltv.
// update_add.cltv_expiry += CLTV_FAR_FAR_AWAY;
connect_blocks(&nodes[1], 72);
nodes[1].node.handle_update_add_htlc(&nodes[0].node.get_our_node_id(), &update_add);
commitment_signed_dance!(nodes[1], nodes[0], &update_0.commitment_signed, false, true);
let update_1 = get_htlc_update_msgs!(nodes[1], nodes[0].node.get_our_node_id());
assert!(update_1.update_fail_htlcs.len() == 1);
let fail_msg = update_1.update_fail_htlcs[0].clone();
nodes[0].node.handle_update_fail_htlc(&nodes[1].node.get_our_node_id(), &fail_msg);
commitment_signed_dance!(nodes[0], nodes[1], update_1.commitment_signed, false);
// Ensure the payment fails with the expected error.
let mut fail_conditions = PaymentFailedConditions::new()
.blamed_scid(phantom_scid)
.expected_htlc_error_data(0x1000 | 14, &[]);
expect_payment_failed_conditions(&nodes[0], payment_hash, false, fail_conditions);
}

I think the other phantom 0x1000|14 error would hit the panic as well. I guess the lack of test coverage here is on me 😅

@valentinewallacevalentinewallace 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.

Really nice cleanup, basically LGTM

Comment threadlightning/src/ln/channelmanager.rs Outdated
Comment threadlightning/src/ln/onion_route_tests.rs Outdated
Comment threadlightning/src/ln/onion_utils.rs Outdated
// ChannelDetails.
if let &HTLCSource::OutboundRoute { ref path, .. } = htlc_source {
(None, Some(path.first().unwrap().short_channel_id), true, Some(*failure_code), Some(data.clone()))
} else { unreachable!(); }

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.

It'd remove some unreachables to make HTLCSource::OutboundRoute have an inner struct, but I think that'd be a future consideration

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

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

Yea, we should, agree it doesnt need to happen here.

@TheBlueMatt
TheBlueMattforce-pushed the 2022-12-fix-missing-data branch from a663ab2 to 35d8eb3CompareDecember 5, 2022 19:13
Comment threadlightning/src/ln/onion_utils.rs

@valentinewallacevalentinewallace 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 after squash

Now that it's entirely abstracted, there's no reason for
`HTLCFailReason` to be in `channelmanager`, it's really an
onion-level abstraction.
Now that `HTLCFailReason` is opaque and in `onion_utils`, we should
encapsulate it so that `ChannelManager` can no longer directly
access its inner fields.
This replaces `final_expiry_too_soon` with
`incorrect_or_unknown_payment` as was done in
lightning/bolts#608. Note that the
rationale for this (that it may expose whether you are the final
recipient for the payment or not) does not currently apply to us -
we don't apply different final CLTV values to different payments.
However, we might in the future, and this will make us slightly
more consistent with other nodes.
The spec mandates that we copy the `sha256_hash_of_onion` field
from the `UpdateFailMalformedHTLC` message into the error message
we send back to the sender, however we simply ignored it. Here we
copy it into the message correctly.
When we're constructing an HTLCFailReason, we should check that we
set the data to at least the correct length for the given failure
code, which we do here.
When we receive a phantom HTLC with a bogus/modified CLTV, we
should fail back with `incorrect_cltv_expiry`, but that requires a
`channel_update`, which we cannot generate for a phantom HTLC which
has no corresponding channel. Thus, instead, we have to fall back
to `incorrect_cltv_expiry`.
Fixeslightningdevkit#1879
This ensures we always hit our new debug assertions while building
failure packets in the immediately-fail pipeline while processing
an inbound HTLC.
If we try to send any onion error with the `UPDATE` flag in
response to a phantom receipt, we should always swap it for
something generic that doesn't require a `channel_update` in it.
Here we use `temporary_node_failure`.
Test provided by Valentine Wallace <vwallace@protonmail.com>
@TheBlueMatt
TheBlueMattforce-pushed the 2022-12-fix-missing-data branch from 878a41f to c9fe69fCompareDecember 6, 2022 20:00
@TheBlueMatt

Copy link
Copy Markdown
CollaboratorAuthor

Squashed without further changes.

@TheBlueMatt
TheBlueMatt merged commit 2390dbc into lightningdevkit:mainDec 6, 2022
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.

Ensure UPDATE errors have an update

4 participants

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

Fix some onion errors and assert their length is correct - #1895

Merged
TheBlueMatt merged 12 commits into
lightningdevkit:mainfrom
TheBlueMatt:2022-12-fix-missing-data
Dec 6, 2022
Merged

Fix some onion errors and assert their length is correct#1895
TheBlueMatt merged 12 commits into
lightningdevkit:mainfrom
TheBlueMatt:2022-12-fix-missing-data

Conversation

@TheBlueMatt

Copy link
Copy Markdown
Collaborator

When we're constructing an HTLCFailReason, we should check that we
set the data to at least the correct length for the given failure
code, which we do here.

First we move HTLCFailReason into onion_utils and encapsulate it a bit better, making channelmanager just a bit smaller. Then we can assert the length, but only after fixing a few issues.

Fixes#1879 but I'm frankly a bit confused - I don't see the 14@valentinewallace claimed was being used incorrectly in phantom failures - maybe it was already fixed?

@TheBlueMattTheBlueMatt added this to the 0.0.113 milestone Dec 1, 2022
@TheBlueMatt
TheBlueMattforce-pushed the 2022-12-fix-missing-data branch from 7e29b27 to db345a5CompareDecember 1, 2022 21:54
@valentinewallace

Copy link
Copy Markdown
Contributor

I think this was it, so | 13: https://github.com/lightningdevkit/rust-lightning/blob/main/lightning/src/ln/channelmanager.rs#L2301. That scope will also set chan_update_opt to None, would have to check if any of the expiry checks below are reachable for phantom payments

@codecov-commenter

codecov-commenter commented Dec 1, 2022

Copy link
Copy Markdown

Codecov Report

Base: 90.69% // Head: 90.63% // Decreases project coverage by -0.05%⚠️

Coverage data is based on head (878a41f) compared to base (4dafa43).
Patch coverage: 92.69% of modified lines in pull request are covered.

❗ Current head 878a41f differs from pull request most recent head c9fe69f. Consider uploading reports for the commit c9fe69f to get more accurate results

Additional details and impacted files
@@ Coverage Diff @@## main #1895 +/- ##
==========================================
- Coverage 90.69% 90.63% -0.06% 
==========================================
Files 91 91 Lines 48404 51171 +2767 Branches 48404 51171 +2767 ==========================================
+ Hits 43898 46380 +2482 - Misses 4506 4791 +285 
Impacted FilesCoverage Δ
lightning/src/ln/channel.rs89.14% <ø> (+0.29%)⬆️
lightning/src/util/ser_macros.rs87.19% <0.00%> (ø)
lightning/src/ln/onion_utils.rs93.56% <86.58%> (-1.37%)⬇️
lightning/src/ln/channelmanager.rs87.15% <97.43%> (+0.88%)⬆️
lightning/src/ln/onion_route_tests.rs97.65% <100.00%> (+0.16%)⬆️
lightning/src/util/persist.rs94.44% <0.00%> (-0.80%)⬇️
lightning/src/util/events.rs24.56% <0.00%> (-0.44%)⬇️
lightning/src/ln/payment_tests.rs98.45% <0.00%> (-0.28%)⬇️
lightning/src/ln/functional_tests.rs96.96% <0.00%> (-0.12%)⬇️
... and 9 more

Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here.

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

@TheBlueMatt
TheBlueMattforce-pushed the 2022-12-fix-missing-data branch from db345a5 to 99c91bdCompareDecember 1, 2022 23:42
@TheBlueMatt

Copy link
Copy Markdown
CollaboratorAuthor

Ah, thanks, fixed.

@TheBlueMatt
TheBlueMattforce-pushed the 2022-12-fix-missing-data branch from 99c91bd to 22d94a8CompareDecember 2, 2022 01:23
Comment threadlightning/src/ln/channelmanager.rs Outdated
Comment on lines 51 to +52
use crate::ln::onion_utils;
use crate::ln::onion_utils::HTLCFailReason;

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.

nit:

Suggested change
usecrate::ln::onion_utils;
usecrate::ln::onion_utils::HTLCFailReason;
usecrate::ln::onion_utils::{self,HTLCFailReason};

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

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

I find the original more readable 🤷

Comment threadlightning/src/ln/onion_utils.rs Outdated
Comment threadlightning/src/ln/onion_utils.rs Outdated
Comment threadlightning/src/ln/channelmanager.rs
Comment threadlightning/src/ln/onion_utils.rs Outdated
Comment on lines +666 to +672
// we get a fail_malformed_htlc from the first hop
// TODO: We'd like to generate a NetworkUpdate for temporary
// failures here, but that would be insufficient as find_route
// generally ignores its view of our own channels as we provide them via
// ChannelDetails.
// TODO: For non-temporary failures, we really should be closing the
// channel here as we apparently can't relay through them anyway.

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.

Do these comments still make sense here, or should they stay in fail_backwards_internal?

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

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

The first TODO belongs here I think - it talks about building a NetworkUpdate which this fn is responsible for. The second we could debate but there's already a TODO that is equivalent at the callsite talking about if we blame our own channel.

@TheBlueMatt
TheBlueMattforce-pushed the 2022-12-fix-missing-data branch from 22d94a8 to af89d18CompareDecember 2, 2022 20:42
@valentinewallace

Copy link
Copy Markdown
Contributor

This test hits one of the new debug panics in HTLCFailReason::reason:

#[test]
fn test_phantom_failure_expires_too_soon() {
// Test that we fail back phantoms if the upstream node fiddled with the CLTV too much with the
// correct error code.
let chanmon_cfgs = create_chanmon_cfgs(2);
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
let channel = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
// Get the route.
let recv_value_msat = 10_000;
let (_, payment_hash, payment_secret) = get_payment_preimage_hash!(nodes[1], Some(recv_value_msat));
let (mut route, phantom_scid) = get_phantom_route!(nodes, recv_value_msat, channel);
// Route the HTLC through to the destination.
nodes[0].node.send_payment(&route, payment_hash, &Some(payment_secret), PaymentId(payment_hash.0)).unwrap();
check_added_monitors!(nodes[0], 1);
let update_0 = get_htlc_update_msgs!(nodes[0], nodes[1].node.get_our_node_id());
let mut update_add = update_0.update_add_htlcs[0].clone();
// Modify the route to have a too-low cltv.
// update_add.cltv_expiry += CLTV_FAR_FAR_AWAY;
connect_blocks(&nodes[1], 72);
nodes[1].node.handle_update_add_htlc(&nodes[0].node.get_our_node_id(), &update_add);
commitment_signed_dance!(nodes[1], nodes[0], &update_0.commitment_signed, false, true);
let update_1 = get_htlc_update_msgs!(nodes[1], nodes[0].node.get_our_node_id());
assert!(update_1.update_fail_htlcs.len() == 1);
let fail_msg = update_1.update_fail_htlcs[0].clone();
nodes[0].node.handle_update_fail_htlc(&nodes[1].node.get_our_node_id(), &fail_msg);
commitment_signed_dance!(nodes[0], nodes[1], update_1.commitment_signed, false);
// Ensure the payment fails with the expected error.
let mut fail_conditions = PaymentFailedConditions::new()
.blamed_scid(phantom_scid)
.expected_htlc_error_data(0x1000 | 14, &[]);
expect_payment_failed_conditions(&nodes[0], payment_hash, false, fail_conditions);
}

I think the other phantom 0x1000|14 error would hit the panic as well. I guess the lack of test coverage here is on me 😅

@valentinewallacevalentinewallace 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.

Really nice cleanup, basically LGTM

Comment threadlightning/src/ln/channelmanager.rs Outdated
Comment threadlightning/src/ln/onion_route_tests.rs Outdated
Comment threadlightning/src/ln/onion_utils.rs Outdated
// ChannelDetails.
if let &HTLCSource::OutboundRoute { ref path, .. } = htlc_source {
(None, Some(path.first().unwrap().short_channel_id), true, Some(*failure_code), Some(data.clone()))
} else { unreachable!(); }

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.

It'd remove some unreachables to make HTLCSource::OutboundRoute have an inner struct, but I think that'd be a future consideration

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

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

Yea, we should, agree it doesnt need to happen here.

@TheBlueMatt
TheBlueMattforce-pushed the 2022-12-fix-missing-data branch from a663ab2 to 35d8eb3CompareDecember 5, 2022 19:13
Comment threadlightning/src/ln/onion_utils.rs

@valentinewallacevalentinewallace 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 after squash

Now that it's entirely abstracted, there's no reason for
`HTLCFailReason` to be in `channelmanager`, it's really an
onion-level abstraction.
Now that `HTLCFailReason` is opaque and in `onion_utils`, we should
encapsulate it so that `ChannelManager` can no longer directly
access its inner fields.
This replaces `final_expiry_too_soon` with
`incorrect_or_unknown_payment` as was done in
lightning/bolts#608. Note that the
rationale for this (that it may expose whether you are the final
recipient for the payment or not) does not currently apply to us -
we don't apply different final CLTV values to different payments.
However, we might in the future, and this will make us slightly
more consistent with other nodes.
The spec mandates that we copy the `sha256_hash_of_onion` field
from the `UpdateFailMalformedHTLC` message into the error message
we send back to the sender, however we simply ignored it. Here we
copy it into the message correctly.
When we're constructing an HTLCFailReason, we should check that we
set the data to at least the correct length for the given failure
code, which we do here.
When we receive a phantom HTLC with a bogus/modified CLTV, we
should fail back with `incorrect_cltv_expiry`, but that requires a
`channel_update`, which we cannot generate for a phantom HTLC which
has no corresponding channel. Thus, instead, we have to fall back
to `incorrect_cltv_expiry`.
Fixeslightningdevkit#1879
This ensures we always hit our new debug assertions while building
failure packets in the immediately-fail pipeline while processing
an inbound HTLC.
If we try to send any onion error with the `UPDATE` flag in
response to a phantom receipt, we should always swap it for
something generic that doesn't require a `channel_update` in it.
Here we use `temporary_node_failure`.
Test provided by Valentine Wallace <vwallace@protonmail.com>
@TheBlueMatt
TheBlueMattforce-pushed the 2022-12-fix-missing-data branch from 878a41f to c9fe69fCompareDecember 6, 2022 20:00
@TheBlueMatt

Copy link
Copy Markdown
CollaboratorAuthor

Squashed without further changes.

@TheBlueMatt
TheBlueMatt merged commit 2390dbc into lightningdevkit:mainDec 6, 2022
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.

Ensure UPDATE errors have an update

4 participants

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

Fix some onion errors and assert their length is correct - #1895

Merged
TheBlueMatt merged 12 commits into
lightningdevkit:mainfrom
TheBlueMatt:2022-12-fix-missing-data
Dec 6, 2022
Merged

Fix some onion errors and assert their length is correct#1895
TheBlueMatt merged 12 commits into
lightningdevkit:mainfrom
TheBlueMatt:2022-12-fix-missing-data

Conversation

@TheBlueMatt

Copy link
Copy Markdown
Collaborator

When we're constructing an HTLCFailReason, we should check that we
set the data to at least the correct length for the given failure
code, which we do here.

First we move HTLCFailReason into onion_utils and encapsulate it a bit better, making channelmanager just a bit smaller. Then we can assert the length, but only after fixing a few issues.

Fixes#1879 but I'm frankly a bit confused - I don't see the 14@valentinewallace claimed was being used incorrectly in phantom failures - maybe it was already fixed?

@TheBlueMattTheBlueMatt added this to the 0.0.113 milestone Dec 1, 2022
@TheBlueMatt
TheBlueMattforce-pushed the 2022-12-fix-missing-data branch from 7e29b27 to db345a5CompareDecember 1, 2022 21:54
@valentinewallace

Copy link
Copy Markdown
Contributor

I think this was it, so | 13: https://github.com/lightningdevkit/rust-lightning/blob/main/lightning/src/ln/channelmanager.rs#L2301. That scope will also set chan_update_opt to None, would have to check if any of the expiry checks below are reachable for phantom payments

@codecov-commenter

codecov-commenter commented Dec 1, 2022

Copy link
Copy Markdown

Codecov Report

Base: 90.69% // Head: 90.63% // Decreases project coverage by -0.05%⚠️

Coverage data is based on head (878a41f) compared to base (4dafa43).
Patch coverage: 92.69% of modified lines in pull request are covered.

❗ Current head 878a41f differs from pull request most recent head c9fe69f. Consider uploading reports for the commit c9fe69f to get more accurate results

Additional details and impacted files
@@ Coverage Diff @@## main #1895 +/- ##
==========================================
- Coverage 90.69% 90.63% -0.06% 
==========================================
Files 91 91 Lines 48404 51171 +2767 Branches 48404 51171 +2767 ==========================================
+ Hits 43898 46380 +2482 - Misses 4506 4791 +285 
Impacted FilesCoverage Δ
lightning/src/ln/channel.rs89.14% <ø> (+0.29%)⬆️
lightning/src/util/ser_macros.rs87.19% <0.00%> (ø)
lightning/src/ln/onion_utils.rs93.56% <86.58%> (-1.37%)⬇️
lightning/src/ln/channelmanager.rs87.15% <97.43%> (+0.88%)⬆️
lightning/src/ln/onion_route_tests.rs97.65% <100.00%> (+0.16%)⬆️
lightning/src/util/persist.rs94.44% <0.00%> (-0.80%)⬇️
lightning/src/util/events.rs24.56% <0.00%> (-0.44%)⬇️
lightning/src/ln/payment_tests.rs98.45% <0.00%> (-0.28%)⬇️
lightning/src/ln/functional_tests.rs96.96% <0.00%> (-0.12%)⬇️
... and 9 more

Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here.

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

@TheBlueMatt
TheBlueMattforce-pushed the 2022-12-fix-missing-data branch from db345a5 to 99c91bdCompareDecember 1, 2022 23:42
@TheBlueMatt

Copy link
Copy Markdown
CollaboratorAuthor

Ah, thanks, fixed.

@TheBlueMatt
TheBlueMattforce-pushed the 2022-12-fix-missing-data branch from 99c91bd to 22d94a8CompareDecember 2, 2022 01:23
Comment threadlightning/src/ln/channelmanager.rs Outdated
Comment on lines 51 to +52
use crate::ln::onion_utils;
use crate::ln::onion_utils::HTLCFailReason;

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.

nit:

Suggested change
usecrate::ln::onion_utils;
usecrate::ln::onion_utils::HTLCFailReason;
usecrate::ln::onion_utils::{self,HTLCFailReason};

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

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

I find the original more readable 🤷

Comment threadlightning/src/ln/onion_utils.rs Outdated
Comment threadlightning/src/ln/onion_utils.rs Outdated
Comment threadlightning/src/ln/channelmanager.rs
Comment threadlightning/src/ln/onion_utils.rs Outdated
Comment on lines +666 to +672
// we get a fail_malformed_htlc from the first hop
// TODO: We'd like to generate a NetworkUpdate for temporary
// failures here, but that would be insufficient as find_route
// generally ignores its view of our own channels as we provide them via
// ChannelDetails.
// TODO: For non-temporary failures, we really should be closing the
// channel here as we apparently can't relay through them anyway.

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.

Do these comments still make sense here, or should they stay in fail_backwards_internal?

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

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

The first TODO belongs here I think - it talks about building a NetworkUpdate which this fn is responsible for. The second we could debate but there's already a TODO that is equivalent at the callsite talking about if we blame our own channel.

@TheBlueMatt
TheBlueMattforce-pushed the 2022-12-fix-missing-data branch from 22d94a8 to af89d18CompareDecember 2, 2022 20:42
@valentinewallace

Copy link
Copy Markdown
Contributor

This test hits one of the new debug panics in HTLCFailReason::reason:

#[test]
fn test_phantom_failure_expires_too_soon() {
// Test that we fail back phantoms if the upstream node fiddled with the CLTV too much with the
// correct error code.
let chanmon_cfgs = create_chanmon_cfgs(2);
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
let channel = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
// Get the route.
let recv_value_msat = 10_000;
let (_, payment_hash, payment_secret) = get_payment_preimage_hash!(nodes[1], Some(recv_value_msat));
let (mut route, phantom_scid) = get_phantom_route!(nodes, recv_value_msat, channel);
// Route the HTLC through to the destination.
nodes[0].node.send_payment(&route, payment_hash, &Some(payment_secret), PaymentId(payment_hash.0)).unwrap();
check_added_monitors!(nodes[0], 1);
let update_0 = get_htlc_update_msgs!(nodes[0], nodes[1].node.get_our_node_id());
let mut update_add = update_0.update_add_htlcs[0].clone();
// Modify the route to have a too-low cltv.
// update_add.cltv_expiry += CLTV_FAR_FAR_AWAY;
connect_blocks(&nodes[1], 72);
nodes[1].node.handle_update_add_htlc(&nodes[0].node.get_our_node_id(), &update_add);
commitment_signed_dance!(nodes[1], nodes[0], &update_0.commitment_signed, false, true);
let update_1 = get_htlc_update_msgs!(nodes[1], nodes[0].node.get_our_node_id());
assert!(update_1.update_fail_htlcs.len() == 1);
let fail_msg = update_1.update_fail_htlcs[0].clone();
nodes[0].node.handle_update_fail_htlc(&nodes[1].node.get_our_node_id(), &fail_msg);
commitment_signed_dance!(nodes[0], nodes[1], update_1.commitment_signed, false);
// Ensure the payment fails with the expected error.
let mut fail_conditions = PaymentFailedConditions::new()
.blamed_scid(phantom_scid)
.expected_htlc_error_data(0x1000 | 14, &[]);
expect_payment_failed_conditions(&nodes[0], payment_hash, false, fail_conditions);
}

I think the other phantom 0x1000|14 error would hit the panic as well. I guess the lack of test coverage here is on me 😅

@valentinewallacevalentinewallace 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.

Really nice cleanup, basically LGTM

Comment threadlightning/src/ln/channelmanager.rs Outdated
Comment threadlightning/src/ln/onion_route_tests.rs Outdated
Comment threadlightning/src/ln/onion_utils.rs Outdated
// ChannelDetails.
if let &HTLCSource::OutboundRoute { ref path, .. } = htlc_source {
(None, Some(path.first().unwrap().short_channel_id), true, Some(*failure_code), Some(data.clone()))
} else { unreachable!(); }

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.

It'd remove some unreachables to make HTLCSource::OutboundRoute have an inner struct, but I think that'd be a future consideration

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

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

Yea, we should, agree it doesnt need to happen here.

@TheBlueMatt
TheBlueMattforce-pushed the 2022-12-fix-missing-data branch from a663ab2 to 35d8eb3CompareDecember 5, 2022 19:13
Comment threadlightning/src/ln/onion_utils.rs

@valentinewallacevalentinewallace 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 after squash

Now that it's entirely abstracted, there's no reason for
`HTLCFailReason` to be in `channelmanager`, it's really an
onion-level abstraction.
Now that `HTLCFailReason` is opaque and in `onion_utils`, we should
encapsulate it so that `ChannelManager` can no longer directly
access its inner fields.
This replaces `final_expiry_too_soon` with
`incorrect_or_unknown_payment` as was done in
lightning/bolts#608. Note that the
rationale for this (that it may expose whether you are the final
recipient for the payment or not) does not currently apply to us -
we don't apply different final CLTV values to different payments.
However, we might in the future, and this will make us slightly
more consistent with other nodes.
The spec mandates that we copy the `sha256_hash_of_onion` field
from the `UpdateFailMalformedHTLC` message into the error message
we send back to the sender, however we simply ignored it. Here we
copy it into the message correctly.
When we're constructing an HTLCFailReason, we should check that we
set the data to at least the correct length for the given failure
code, which we do here.
When we receive a phantom HTLC with a bogus/modified CLTV, we
should fail back with `incorrect_cltv_expiry`, but that requires a
`channel_update`, which we cannot generate for a phantom HTLC which
has no corresponding channel. Thus, instead, we have to fall back
to `incorrect_cltv_expiry`.
Fixeslightningdevkit#1879
This ensures we always hit our new debug assertions while building
failure packets in the immediately-fail pipeline while processing
an inbound HTLC.
If we try to send any onion error with the `UPDATE` flag in
response to a phantom receipt, we should always swap it for
something generic that doesn't require a `channel_update` in it.
Here we use `temporary_node_failure`.
Test provided by Valentine Wallace <vwallace@protonmail.com>
@TheBlueMatt
TheBlueMattforce-pushed the 2022-12-fix-missing-data branch from 878a41f to c9fe69fCompareDecember 6, 2022 20:00
@TheBlueMatt

Copy link
Copy Markdown
CollaboratorAuthor

Squashed without further changes.

@TheBlueMatt
TheBlueMatt merged commit 2390dbc into lightningdevkit:mainDec 6, 2022
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.

Ensure UPDATE errors have an update

4 participants

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

Fix some onion errors and assert their length is correct - #1895

Merged
TheBlueMatt merged 12 commits into
lightningdevkit:mainfrom
TheBlueMatt:2022-12-fix-missing-data
Dec 6, 2022
Merged

Fix some onion errors and assert their length is correct#1895
TheBlueMatt merged 12 commits into
lightningdevkit:mainfrom
TheBlueMatt:2022-12-fix-missing-data

Conversation

@TheBlueMatt

Copy link
Copy Markdown
Collaborator

When we're constructing an HTLCFailReason, we should check that we
set the data to at least the correct length for the given failure
code, which we do here.

First we move HTLCFailReason into onion_utils and encapsulate it a bit better, making channelmanager just a bit smaller. Then we can assert the length, but only after fixing a few issues.

Fixes#1879 but I'm frankly a bit confused - I don't see the 14@valentinewallace claimed was being used incorrectly in phantom failures - maybe it was already fixed?

@TheBlueMattTheBlueMatt added this to the 0.0.113 milestone Dec 1, 2022
@TheBlueMatt
TheBlueMattforce-pushed the 2022-12-fix-missing-data branch from 7e29b27 to db345a5CompareDecember 1, 2022 21:54
@valentinewallace

Copy link
Copy Markdown
Contributor

I think this was it, so | 13: https://github.com/lightningdevkit/rust-lightning/blob/main/lightning/src/ln/channelmanager.rs#L2301. That scope will also set chan_update_opt to None, would have to check if any of the expiry checks below are reachable for phantom payments

@codecov-commenter

codecov-commenter commented Dec 1, 2022

Copy link
Copy Markdown

Codecov Report

Base: 90.69% // Head: 90.63% // Decreases project coverage by -0.05%⚠️

Coverage data is based on head (878a41f) compared to base (4dafa43).
Patch coverage: 92.69% of modified lines in pull request are covered.

❗ Current head 878a41f differs from pull request most recent head c9fe69f. Consider uploading reports for the commit c9fe69f to get more accurate results

Additional details and impacted files
@@ Coverage Diff @@## main #1895 +/- ##
==========================================
- Coverage 90.69% 90.63% -0.06% 
==========================================
Files 91 91 Lines 48404 51171 +2767 Branches 48404 51171 +2767 ==========================================
+ Hits 43898 46380 +2482 - Misses 4506 4791 +285 
Impacted FilesCoverage Δ
lightning/src/ln/channel.rs89.14% <ø> (+0.29%)⬆️
lightning/src/util/ser_macros.rs87.19% <0.00%> (ø)
lightning/src/ln/onion_utils.rs93.56% <86.58%> (-1.37%)⬇️
lightning/src/ln/channelmanager.rs87.15% <97.43%> (+0.88%)⬆️
lightning/src/ln/onion_route_tests.rs97.65% <100.00%> (+0.16%)⬆️
lightning/src/util/persist.rs94.44% <0.00%> (-0.80%)⬇️
lightning/src/util/events.rs24.56% <0.00%> (-0.44%)⬇️
lightning/src/ln/payment_tests.rs98.45% <0.00%> (-0.28%)⬇️
lightning/src/ln/functional_tests.rs96.96% <0.00%> (-0.12%)⬇️
... and 9 more

Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here.

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

@TheBlueMatt
TheBlueMattforce-pushed the 2022-12-fix-missing-data branch from db345a5 to 99c91bdCompareDecember 1, 2022 23:42
@TheBlueMatt

Copy link
Copy Markdown
CollaboratorAuthor

Ah, thanks, fixed.

@TheBlueMatt
TheBlueMattforce-pushed the 2022-12-fix-missing-data branch from 99c91bd to 22d94a8CompareDecember 2, 2022 01:23
Comment threadlightning/src/ln/channelmanager.rs Outdated
Comment on lines 51 to +52
use crate::ln::onion_utils;
use crate::ln::onion_utils::HTLCFailReason;

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.

nit:

Suggested change
usecrate::ln::onion_utils;
usecrate::ln::onion_utils::HTLCFailReason;
usecrate::ln::onion_utils::{self,HTLCFailReason};

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

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

I find the original more readable 🤷

Comment threadlightning/src/ln/onion_utils.rs Outdated
Comment threadlightning/src/ln/onion_utils.rs Outdated
Comment threadlightning/src/ln/channelmanager.rs
Comment threadlightning/src/ln/onion_utils.rs Outdated
Comment on lines +666 to +672
// we get a fail_malformed_htlc from the first hop
// TODO: We'd like to generate a NetworkUpdate for temporary
// failures here, but that would be insufficient as find_route
// generally ignores its view of our own channels as we provide them via
// ChannelDetails.
// TODO: For non-temporary failures, we really should be closing the
// channel here as we apparently can't relay through them anyway.

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.

Do these comments still make sense here, or should they stay in fail_backwards_internal?

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

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

The first TODO belongs here I think - it talks about building a NetworkUpdate which this fn is responsible for. The second we could debate but there's already a TODO that is equivalent at the callsite talking about if we blame our own channel.

@TheBlueMatt
TheBlueMattforce-pushed the 2022-12-fix-missing-data branch from 22d94a8 to af89d18CompareDecember 2, 2022 20:42
@valentinewallace

Copy link
Copy Markdown
Contributor

This test hits one of the new debug panics in HTLCFailReason::reason:

#[test]
fn test_phantom_failure_expires_too_soon() {
// Test that we fail back phantoms if the upstream node fiddled with the CLTV too much with the
// correct error code.
let chanmon_cfgs = create_chanmon_cfgs(2);
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
let channel = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
// Get the route.
let recv_value_msat = 10_000;
let (_, payment_hash, payment_secret) = get_payment_preimage_hash!(nodes[1], Some(recv_value_msat));
let (mut route, phantom_scid) = get_phantom_route!(nodes, recv_value_msat, channel);
// Route the HTLC through to the destination.
nodes[0].node.send_payment(&route, payment_hash, &Some(payment_secret), PaymentId(payment_hash.0)).unwrap();
check_added_monitors!(nodes[0], 1);
let update_0 = get_htlc_update_msgs!(nodes[0], nodes[1].node.get_our_node_id());
let mut update_add = update_0.update_add_htlcs[0].clone();
// Modify the route to have a too-low cltv.
// update_add.cltv_expiry += CLTV_FAR_FAR_AWAY;
connect_blocks(&nodes[1], 72);
nodes[1].node.handle_update_add_htlc(&nodes[0].node.get_our_node_id(), &update_add);
commitment_signed_dance!(nodes[1], nodes[0], &update_0.commitment_signed, false, true);
let update_1 = get_htlc_update_msgs!(nodes[1], nodes[0].node.get_our_node_id());
assert!(update_1.update_fail_htlcs.len() == 1);
let fail_msg = update_1.update_fail_htlcs[0].clone();
nodes[0].node.handle_update_fail_htlc(&nodes[1].node.get_our_node_id(), &fail_msg);
commitment_signed_dance!(nodes[0], nodes[1], update_1.commitment_signed, false);
// Ensure the payment fails with the expected error.
let mut fail_conditions = PaymentFailedConditions::new()
.blamed_scid(phantom_scid)
.expected_htlc_error_data(0x1000 | 14, &[]);
expect_payment_failed_conditions(&nodes[0], payment_hash, false, fail_conditions);
}

I think the other phantom 0x1000|14 error would hit the panic as well. I guess the lack of test coverage here is on me 😅

@valentinewallacevalentinewallace 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.

Really nice cleanup, basically LGTM

Comment threadlightning/src/ln/channelmanager.rs Outdated
Comment threadlightning/src/ln/onion_route_tests.rs Outdated
Comment threadlightning/src/ln/onion_utils.rs Outdated
// ChannelDetails.
if let &HTLCSource::OutboundRoute { ref path, .. } = htlc_source {
(None, Some(path.first().unwrap().short_channel_id), true, Some(*failure_code), Some(data.clone()))
} else { unreachable!(); }

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.

It'd remove some unreachables to make HTLCSource::OutboundRoute have an inner struct, but I think that'd be a future consideration

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

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

Yea, we should, agree it doesnt need to happen here.

@TheBlueMatt
TheBlueMattforce-pushed the 2022-12-fix-missing-data branch from a663ab2 to 35d8eb3CompareDecember 5, 2022 19:13
Comment threadlightning/src/ln/onion_utils.rs

@valentinewallacevalentinewallace 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 after squash

Now that it's entirely abstracted, there's no reason for
`HTLCFailReason` to be in `channelmanager`, it's really an
onion-level abstraction.
Now that `HTLCFailReason` is opaque and in `onion_utils`, we should
encapsulate it so that `ChannelManager` can no longer directly
access its inner fields.
This replaces `final_expiry_too_soon` with
`incorrect_or_unknown_payment` as was done in
lightning/bolts#608. Note that the
rationale for this (that it may expose whether you are the final
recipient for the payment or not) does not currently apply to us -
we don't apply different final CLTV values to different payments.
However, we might in the future, and this will make us slightly
more consistent with other nodes.
The spec mandates that we copy the `sha256_hash_of_onion` field
from the `UpdateFailMalformedHTLC` message into the error message
we send back to the sender, however we simply ignored it. Here we
copy it into the message correctly.
When we're constructing an HTLCFailReason, we should check that we
set the data to at least the correct length for the given failure
code, which we do here.
When we receive a phantom HTLC with a bogus/modified CLTV, we
should fail back with `incorrect_cltv_expiry`, but that requires a
`channel_update`, which we cannot generate for a phantom HTLC which
has no corresponding channel. Thus, instead, we have to fall back
to `incorrect_cltv_expiry`.
Fixeslightningdevkit#1879
This ensures we always hit our new debug assertions while building
failure packets in the immediately-fail pipeline while processing
an inbound HTLC.
If we try to send any onion error with the `UPDATE` flag in
response to a phantom receipt, we should always swap it for
something generic that doesn't require a `channel_update` in it.
Here we use `temporary_node_failure`.
Test provided by Valentine Wallace <vwallace@protonmail.com>
@TheBlueMatt
TheBlueMattforce-pushed the 2022-12-fix-missing-data branch from 878a41f to c9fe69fCompareDecember 6, 2022 20:00
@TheBlueMatt

Copy link
Copy Markdown
CollaboratorAuthor

Squashed without further changes.

@TheBlueMatt
TheBlueMatt merged commit 2390dbc into lightningdevkit:mainDec 6, 2022
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.

Ensure UPDATE errors have an update

4 participants

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

Fix some onion errors and assert their length is correct - #1895

Merged
TheBlueMatt merged 12 commits into
lightningdevkit:mainfrom
TheBlueMatt:2022-12-fix-missing-data
Dec 6, 2022
Merged

Fix some onion errors and assert their length is correct#1895
TheBlueMatt merged 12 commits into
lightningdevkit:mainfrom
TheBlueMatt:2022-12-fix-missing-data

Conversation

@TheBlueMatt

Copy link
Copy Markdown
Collaborator

When we're constructing an HTLCFailReason, we should check that we
set the data to at least the correct length for the given failure
code, which we do here.

First we move HTLCFailReason into onion_utils and encapsulate it a bit better, making channelmanager just a bit smaller. Then we can assert the length, but only after fixing a few issues.

Fixes#1879 but I'm frankly a bit confused - I don't see the 14@valentinewallace claimed was being used incorrectly in phantom failures - maybe it was already fixed?

@TheBlueMattTheBlueMatt added this to the 0.0.113 milestone Dec 1, 2022
@TheBlueMatt
TheBlueMattforce-pushed the 2022-12-fix-missing-data branch from 7e29b27 to db345a5CompareDecember 1, 2022 21:54
@valentinewallace

Copy link
Copy Markdown
Contributor

I think this was it, so | 13: https://github.com/lightningdevkit/rust-lightning/blob/main/lightning/src/ln/channelmanager.rs#L2301. That scope will also set chan_update_opt to None, would have to check if any of the expiry checks below are reachable for phantom payments

@codecov-commenter

codecov-commenter commented Dec 1, 2022

Copy link
Copy Markdown

Codecov Report

Base: 90.69% // Head: 90.63% // Decreases project coverage by -0.05%⚠️

Coverage data is based on head (878a41f) compared to base (4dafa43).
Patch coverage: 92.69% of modified lines in pull request are covered.

❗ Current head 878a41f differs from pull request most recent head c9fe69f. Consider uploading reports for the commit c9fe69f to get more accurate results

Additional details and impacted files
@@ Coverage Diff @@## main #1895 +/- ##
==========================================
- Coverage 90.69% 90.63% -0.06% 
==========================================
Files 91 91 Lines 48404 51171 +2767 Branches 48404 51171 +2767 ==========================================
+ Hits 43898 46380 +2482 - Misses 4506 4791 +285 
Impacted FilesCoverage Δ
lightning/src/ln/channel.rs89.14% <ø> (+0.29%)⬆️
lightning/src/util/ser_macros.rs87.19% <0.00%> (ø)
lightning/src/ln/onion_utils.rs93.56% <86.58%> (-1.37%)⬇️
lightning/src/ln/channelmanager.rs87.15% <97.43%> (+0.88%)⬆️
lightning/src/ln/onion_route_tests.rs97.65% <100.00%> (+0.16%)⬆️
lightning/src/util/persist.rs94.44% <0.00%> (-0.80%)⬇️
lightning/src/util/events.rs24.56% <0.00%> (-0.44%)⬇️
lightning/src/ln/payment_tests.rs98.45% <0.00%> (-0.28%)⬇️
lightning/src/ln/functional_tests.rs96.96% <0.00%> (-0.12%)⬇️
... and 9 more

Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here.

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

@TheBlueMatt
TheBlueMattforce-pushed the 2022-12-fix-missing-data branch from db345a5 to 99c91bdCompareDecember 1, 2022 23:42
@TheBlueMatt

Copy link
Copy Markdown
CollaboratorAuthor

Ah, thanks, fixed.

@TheBlueMatt
TheBlueMattforce-pushed the 2022-12-fix-missing-data branch from 99c91bd to 22d94a8CompareDecember 2, 2022 01:23
Comment threadlightning/src/ln/channelmanager.rs Outdated
Comment on lines 51 to +52
use crate::ln::onion_utils;
use crate::ln::onion_utils::HTLCFailReason;

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.

nit:

Suggested change
usecrate::ln::onion_utils;
usecrate::ln::onion_utils::HTLCFailReason;
usecrate::ln::onion_utils::{self,HTLCFailReason};

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

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

I find the original more readable 🤷

Comment threadlightning/src/ln/onion_utils.rs Outdated
Comment threadlightning/src/ln/onion_utils.rs Outdated
Comment threadlightning/src/ln/channelmanager.rs
Comment threadlightning/src/ln/onion_utils.rs Outdated
Comment on lines +666 to +672
// we get a fail_malformed_htlc from the first hop
// TODO: We'd like to generate a NetworkUpdate for temporary
// failures here, but that would be insufficient as find_route
// generally ignores its view of our own channels as we provide them via
// ChannelDetails.
// TODO: For non-temporary failures, we really should be closing the
// channel here as we apparently can't relay through them anyway.

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.

Do these comments still make sense here, or should they stay in fail_backwards_internal?

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

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

The first TODO belongs here I think - it talks about building a NetworkUpdate which this fn is responsible for. The second we could debate but there's already a TODO that is equivalent at the callsite talking about if we blame our own channel.

@TheBlueMatt
TheBlueMattforce-pushed the 2022-12-fix-missing-data branch from 22d94a8 to af89d18CompareDecember 2, 2022 20:42
@valentinewallace

Copy link
Copy Markdown
Contributor

This test hits one of the new debug panics in HTLCFailReason::reason:

#[test]
fn test_phantom_failure_expires_too_soon() {
// Test that we fail back phantoms if the upstream node fiddled with the CLTV too much with the
// correct error code.
let chanmon_cfgs = create_chanmon_cfgs(2);
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
let channel = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
// Get the route.
let recv_value_msat = 10_000;
let (_, payment_hash, payment_secret) = get_payment_preimage_hash!(nodes[1], Some(recv_value_msat));
let (mut route, phantom_scid) = get_phantom_route!(nodes, recv_value_msat, channel);
// Route the HTLC through to the destination.
nodes[0].node.send_payment(&route, payment_hash, &Some(payment_secret), PaymentId(payment_hash.0)).unwrap();
check_added_monitors!(nodes[0], 1);
let update_0 = get_htlc_update_msgs!(nodes[0], nodes[1].node.get_our_node_id());
let mut update_add = update_0.update_add_htlcs[0].clone();
// Modify the route to have a too-low cltv.
// update_add.cltv_expiry += CLTV_FAR_FAR_AWAY;
connect_blocks(&nodes[1], 72);
nodes[1].node.handle_update_add_htlc(&nodes[0].node.get_our_node_id(), &update_add);
commitment_signed_dance!(nodes[1], nodes[0], &update_0.commitment_signed, false, true);
let update_1 = get_htlc_update_msgs!(nodes[1], nodes[0].node.get_our_node_id());
assert!(update_1.update_fail_htlcs.len() == 1);
let fail_msg = update_1.update_fail_htlcs[0].clone();
nodes[0].node.handle_update_fail_htlc(&nodes[1].node.get_our_node_id(), &fail_msg);
commitment_signed_dance!(nodes[0], nodes[1], update_1.commitment_signed, false);
// Ensure the payment fails with the expected error.
let mut fail_conditions = PaymentFailedConditions::new()
.blamed_scid(phantom_scid)
.expected_htlc_error_data(0x1000 | 14, &[]);
expect_payment_failed_conditions(&nodes[0], payment_hash, false, fail_conditions);
}

I think the other phantom 0x1000|14 error would hit the panic as well. I guess the lack of test coverage here is on me 😅

@valentinewallacevalentinewallace 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.

Really nice cleanup, basically LGTM

Comment threadlightning/src/ln/channelmanager.rs Outdated
Comment threadlightning/src/ln/onion_route_tests.rs Outdated
Comment threadlightning/src/ln/onion_utils.rs Outdated
// ChannelDetails.
if let &HTLCSource::OutboundRoute { ref path, .. } = htlc_source {
(None, Some(path.first().unwrap().short_channel_id), true, Some(*failure_code), Some(data.clone()))
} else { unreachable!(); }

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.

It'd remove some unreachables to make HTLCSource::OutboundRoute have an inner struct, but I think that'd be a future consideration

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

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

Yea, we should, agree it doesnt need to happen here.

@TheBlueMatt
TheBlueMattforce-pushed the 2022-12-fix-missing-data branch from a663ab2 to 35d8eb3CompareDecember 5, 2022 19:13
Comment threadlightning/src/ln/onion_utils.rs

@valentinewallacevalentinewallace 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 after squash

Now that it's entirely abstracted, there's no reason for
`HTLCFailReason` to be in `channelmanager`, it's really an
onion-level abstraction.
Now that `HTLCFailReason` is opaque and in `onion_utils`, we should
encapsulate it so that `ChannelManager` can no longer directly
access its inner fields.
This replaces `final_expiry_too_soon` with
`incorrect_or_unknown_payment` as was done in
lightning/bolts#608. Note that the
rationale for this (that it may expose whether you are the final
recipient for the payment or not) does not currently apply to us -
we don't apply different final CLTV values to different payments.
However, we might in the future, and this will make us slightly
more consistent with other nodes.
The spec mandates that we copy the `sha256_hash_of_onion` field
from the `UpdateFailMalformedHTLC` message into the error message
we send back to the sender, however we simply ignored it. Here we
copy it into the message correctly.
When we're constructing an HTLCFailReason, we should check that we
set the data to at least the correct length for the given failure
code, which we do here.
When we receive a phantom HTLC with a bogus/modified CLTV, we
should fail back with `incorrect_cltv_expiry`, but that requires a
`channel_update`, which we cannot generate for a phantom HTLC which
has no corresponding channel. Thus, instead, we have to fall back
to `incorrect_cltv_expiry`.
Fixeslightningdevkit#1879
This ensures we always hit our new debug assertions while building
failure packets in the immediately-fail pipeline while processing
an inbound HTLC.
If we try to send any onion error with the `UPDATE` flag in
response to a phantom receipt, we should always swap it for
something generic that doesn't require a `channel_update` in it.
Here we use `temporary_node_failure`.
Test provided by Valentine Wallace <vwallace@protonmail.com>
@TheBlueMatt
TheBlueMattforce-pushed the 2022-12-fix-missing-data branch from 878a41f to c9fe69fCompareDecember 6, 2022 20:00
@TheBlueMatt

Copy link
Copy Markdown
CollaboratorAuthor

Squashed without further changes.

@TheBlueMatt
TheBlueMatt merged commit 2390dbc into lightningdevkit:mainDec 6, 2022
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.

Ensure UPDATE errors have an update

4 participants

@TheBlueMatt@valentinewallace@codecov-commenter@wpaulino
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Fix some onion errors and assert their length is correct - #1895

Merged
TheBlueMatt merged 12 commits into
lightningdevkit:mainfrom
TheBlueMatt:2022-12-fix-missing-data
Dec 6, 2022
Merged

Fix some onion errors and assert their length is correct#1895
TheBlueMatt merged 12 commits into
lightningdevkit:mainfrom
TheBlueMatt:2022-12-fix-missing-data

Conversation

@TheBlueMatt

Copy link
Copy Markdown
Collaborator

When we're constructing an HTLCFailReason, we should check that we
set the data to at least the correct length for the given failure
code, which we do here.

First we move HTLCFailReason into onion_utils and encapsulate it a bit better, making channelmanager just a bit smaller. Then we can assert the length, but only after fixing a few issues.

Fixes#1879 but I'm frankly a bit confused - I don't see the 14@valentinewallace claimed was being used incorrectly in phantom failures - maybe it was already fixed?

@TheBlueMattTheBlueMatt added this to the 0.0.113 milestone Dec 1, 2022
@TheBlueMatt
TheBlueMattforce-pushed the 2022-12-fix-missing-data branch from 7e29b27 to db345a5CompareDecember 1, 2022 21:54
@valentinewallace

Copy link
Copy Markdown
Contributor

I think this was it, so | 13: https://github.com/lightningdevkit/rust-lightning/blob/main/lightning/src/ln/channelmanager.rs#L2301. That scope will also set chan_update_opt to None, would have to check if any of the expiry checks below are reachable for phantom payments

@codecov-commenter

codecov-commenter commented Dec 1, 2022

Copy link
Copy Markdown

Codecov Report

Base: 90.69% // Head: 90.63% // Decreases project coverage by -0.05%⚠️

Coverage data is based on head (878a41f) compared to base (4dafa43).
Patch coverage: 92.69% of modified lines in pull request are covered.

❗ Current head 878a41f differs from pull request most recent head c9fe69f. Consider uploading reports for the commit c9fe69f to get more accurate results

Additional details and impacted files
@@ Coverage Diff @@## main #1895 +/- ##
==========================================
- Coverage 90.69% 90.63% -0.06% 
==========================================
Files 91 91 Lines 48404 51171 +2767 Branches 48404 51171 +2767 ==========================================
+ Hits 43898 46380 +2482 - Misses 4506 4791 +285 
Impacted FilesCoverage Δ
lightning/src/ln/channel.rs89.14% <ø> (+0.29%)⬆️
lightning/src/util/ser_macros.rs87.19% <0.00%> (ø)
lightning/src/ln/onion_utils.rs93.56% <86.58%> (-1.37%)⬇️
lightning/src/ln/channelmanager.rs87.15% <97.43%> (+0.88%)⬆️
lightning/src/ln/onion_route_tests.rs97.65% <100.00%> (+0.16%)⬆️
lightning/src/util/persist.rs94.44% <0.00%> (-0.80%)⬇️
lightning/src/util/events.rs24.56% <0.00%> (-0.44%)⬇️
lightning/src/ln/payment_tests.rs98.45% <0.00%> (-0.28%)⬇️
lightning/src/ln/functional_tests.rs96.96% <0.00%> (-0.12%)⬇️
... and 9 more

Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here.

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

@TheBlueMatt
TheBlueMattforce-pushed the 2022-12-fix-missing-data branch from db345a5 to 99c91bdCompareDecember 1, 2022 23:42
@TheBlueMatt

Copy link
Copy Markdown
CollaboratorAuthor

Ah, thanks, fixed.

@TheBlueMatt
TheBlueMattforce-pushed the 2022-12-fix-missing-data branch from 99c91bd to 22d94a8CompareDecember 2, 2022 01:23
Comment threadlightning/src/ln/channelmanager.rs Outdated
Comment on lines 51 to +52
use crate::ln::onion_utils;
use crate::ln::onion_utils::HTLCFailReason;

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.

nit:

Suggested change
usecrate::ln::onion_utils;
usecrate::ln::onion_utils::HTLCFailReason;
usecrate::ln::onion_utils::{self,HTLCFailReason};

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

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

I find the original more readable 🤷

Comment threadlightning/src/ln/onion_utils.rs Outdated
Comment threadlightning/src/ln/onion_utils.rs Outdated
Comment threadlightning/src/ln/channelmanager.rs
Comment threadlightning/src/ln/onion_utils.rs Outdated
Comment on lines +666 to +672
// we get a fail_malformed_htlc from the first hop
// TODO: We'd like to generate a NetworkUpdate for temporary
// failures here, but that would be insufficient as find_route
// generally ignores its view of our own channels as we provide them via
// ChannelDetails.
// TODO: For non-temporary failures, we really should be closing the
// channel here as we apparently can't relay through them anyway.

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.

Do these comments still make sense here, or should they stay in fail_backwards_internal?

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

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

The first TODO belongs here I think - it talks about building a NetworkUpdate which this fn is responsible for. The second we could debate but there's already a TODO that is equivalent at the callsite talking about if we blame our own channel.

@TheBlueMatt
TheBlueMattforce-pushed the 2022-12-fix-missing-data branch from 22d94a8 to af89d18CompareDecember 2, 2022 20:42
@valentinewallace

Copy link
Copy Markdown
Contributor

This test hits one of the new debug panics in HTLCFailReason::reason:

#[test]
fn test_phantom_failure_expires_too_soon() {
// Test that we fail back phantoms if the upstream node fiddled with the CLTV too much with the
// correct error code.
let chanmon_cfgs = create_chanmon_cfgs(2);
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
let channel = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
// Get the route.
let recv_value_msat = 10_000;
let (_, payment_hash, payment_secret) = get_payment_preimage_hash!(nodes[1], Some(recv_value_msat));
let (mut route, phantom_scid) = get_phantom_route!(nodes, recv_value_msat, channel);
// Route the HTLC through to the destination.
nodes[0].node.send_payment(&route, payment_hash, &Some(payment_secret), PaymentId(payment_hash.0)).unwrap();
check_added_monitors!(nodes[0], 1);
let update_0 = get_htlc_update_msgs!(nodes[0], nodes[1].node.get_our_node_id());
let mut update_add = update_0.update_add_htlcs[0].clone();
// Modify the route to have a too-low cltv.
// update_add.cltv_expiry += CLTV_FAR_FAR_AWAY;
connect_blocks(&nodes[1], 72);
nodes[1].node.handle_update_add_htlc(&nodes[0].node.get_our_node_id(), &update_add);
commitment_signed_dance!(nodes[1], nodes[0], &update_0.commitment_signed, false, true);
let update_1 = get_htlc_update_msgs!(nodes[1], nodes[0].node.get_our_node_id());
assert!(update_1.update_fail_htlcs.len() == 1);
let fail_msg = update_1.update_fail_htlcs[0].clone();
nodes[0].node.handle_update_fail_htlc(&nodes[1].node.get_our_node_id(), &fail_msg);
commitment_signed_dance!(nodes[0], nodes[1], update_1.commitment_signed, false);
// Ensure the payment fails with the expected error.
let mut fail_conditions = PaymentFailedConditions::new()
.blamed_scid(phantom_scid)
.expected_htlc_error_data(0x1000 | 14, &[]);
expect_payment_failed_conditions(&nodes[0], payment_hash, false, fail_conditions);
}

I think the other phantom 0x1000|14 error would hit the panic as well. I guess the lack of test coverage here is on me 😅

@valentinewallacevalentinewallace 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.

Really nice cleanup, basically LGTM

Comment threadlightning/src/ln/channelmanager.rs Outdated
Comment threadlightning/src/ln/onion_route_tests.rs Outdated
Comment threadlightning/src/ln/onion_utils.rs Outdated
// ChannelDetails.
if let &HTLCSource::OutboundRoute { ref path, .. } = htlc_source {
(None, Some(path.first().unwrap().short_channel_id), true, Some(*failure_code), Some(data.clone()))
} else { unreachable!(); }

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.

It'd remove some unreachables to make HTLCSource::OutboundRoute have an inner struct, but I think that'd be a future consideration

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

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

Yea, we should, agree it doesnt need to happen here.

@TheBlueMatt
TheBlueMattforce-pushed the 2022-12-fix-missing-data branch from a663ab2 to 35d8eb3CompareDecember 5, 2022 19:13
Comment threadlightning/src/ln/onion_utils.rs

@valentinewallacevalentinewallace 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 after squash

Now that it's entirely abstracted, there's no reason for
`HTLCFailReason` to be in `channelmanager`, it's really an
onion-level abstraction.
Now that `HTLCFailReason` is opaque and in `onion_utils`, we should
encapsulate it so that `ChannelManager` can no longer directly
access its inner fields.
This replaces `final_expiry_too_soon` with
`incorrect_or_unknown_payment` as was done in
lightning/bolts#608. Note that the
rationale for this (that it may expose whether you are the final
recipient for the payment or not) does not currently apply to us -
we don't apply different final CLTV values to different payments.
However, we might in the future, and this will make us slightly
more consistent with other nodes.
The spec mandates that we copy the `sha256_hash_of_onion` field
from the `UpdateFailMalformedHTLC` message into the error message
we send back to the sender, however we simply ignored it. Here we
copy it into the message correctly.
When we're constructing an HTLCFailReason, we should check that we
set the data to at least the correct length for the given failure
code, which we do here.
When we receive a phantom HTLC with a bogus/modified CLTV, we
should fail back with `incorrect_cltv_expiry`, but that requires a
`channel_update`, which we cannot generate for a phantom HTLC which
has no corresponding channel. Thus, instead, we have to fall back
to `incorrect_cltv_expiry`.
Fixeslightningdevkit#1879
This ensures we always hit our new debug assertions while building
failure packets in the immediately-fail pipeline while processing
an inbound HTLC.
If we try to send any onion error with the `UPDATE` flag in
response to a phantom receipt, we should always swap it for
something generic that doesn't require a `channel_update` in it.
Here we use `temporary_node_failure`.
Test provided by Valentine Wallace <vwallace@protonmail.com>
@TheBlueMatt
TheBlueMattforce-pushed the 2022-12-fix-missing-data branch from 878a41f to c9fe69fCompareDecember 6, 2022 20:00
@TheBlueMatt

Copy link
Copy Markdown
CollaboratorAuthor

Squashed without further changes.

@TheBlueMatt
TheBlueMatt merged commit 2390dbc into lightningdevkit:mainDec 6, 2022
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.

Ensure UPDATE errors have an update

4 participants

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

Fix some onion errors and assert their length is correct - #1895

Merged
TheBlueMatt merged 12 commits into
lightningdevkit:mainfrom
TheBlueMatt:2022-12-fix-missing-data
Dec 6, 2022
Merged

Fix some onion errors and assert their length is correct#1895
TheBlueMatt merged 12 commits into
lightningdevkit:mainfrom
TheBlueMatt:2022-12-fix-missing-data

Conversation

@TheBlueMatt

Copy link
Copy Markdown
Collaborator

When we're constructing an HTLCFailReason, we should check that we
set the data to at least the correct length for the given failure
code, which we do here.

First we move HTLCFailReason into onion_utils and encapsulate it a bit better, making channelmanager just a bit smaller. Then we can assert the length, but only after fixing a few issues.

Fixes#1879 but I'm frankly a bit confused - I don't see the 14@valentinewallace claimed was being used incorrectly in phantom failures - maybe it was already fixed?

@TheBlueMattTheBlueMatt added this to the 0.0.113 milestone Dec 1, 2022
@TheBlueMatt
TheBlueMattforce-pushed the 2022-12-fix-missing-data branch from 7e29b27 to db345a5CompareDecember 1, 2022 21:54
@valentinewallace

Copy link
Copy Markdown
Contributor

I think this was it, so | 13: https://github.com/lightningdevkit/rust-lightning/blob/main/lightning/src/ln/channelmanager.rs#L2301. That scope will also set chan_update_opt to None, would have to check if any of the expiry checks below are reachable for phantom payments

@codecov-commenter

codecov-commenter commented Dec 1, 2022

Copy link
Copy Markdown

Codecov Report

Base: 90.69% // Head: 90.63% // Decreases project coverage by -0.05%⚠️

Coverage data is based on head (878a41f) compared to base (4dafa43).
Patch coverage: 92.69% of modified lines in pull request are covered.

❗ Current head 878a41f differs from pull request most recent head c9fe69f. Consider uploading reports for the commit c9fe69f to get more accurate results

Additional details and impacted files
@@ Coverage Diff @@## main #1895 +/- ##
==========================================
- Coverage 90.69% 90.63% -0.06% 
==========================================
Files 91 91 Lines 48404 51171 +2767 Branches 48404 51171 +2767 ==========================================
+ Hits 43898 46380 +2482 - Misses 4506 4791 +285 
Impacted FilesCoverage Δ
lightning/src/ln/channel.rs89.14% <ø> (+0.29%)⬆️
lightning/src/util/ser_macros.rs87.19% <0.00%> (ø)
lightning/src/ln/onion_utils.rs93.56% <86.58%> (-1.37%)⬇️
lightning/src/ln/channelmanager.rs87.15% <97.43%> (+0.88%)⬆️
lightning/src/ln/onion_route_tests.rs97.65% <100.00%> (+0.16%)⬆️
lightning/src/util/persist.rs94.44% <0.00%> (-0.80%)⬇️
lightning/src/util/events.rs24.56% <0.00%> (-0.44%)⬇️
lightning/src/ln/payment_tests.rs98.45% <0.00%> (-0.28%)⬇️
lightning/src/ln/functional_tests.rs96.96% <0.00%> (-0.12%)⬇️
... and 9 more

Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here.

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

@TheBlueMatt
TheBlueMattforce-pushed the 2022-12-fix-missing-data branch from db345a5 to 99c91bdCompareDecember 1, 2022 23:42
@TheBlueMatt

Copy link
Copy Markdown
CollaboratorAuthor

Ah, thanks, fixed.

@TheBlueMatt
TheBlueMattforce-pushed the 2022-12-fix-missing-data branch from 99c91bd to 22d94a8CompareDecember 2, 2022 01:23
Comment threadlightning/src/ln/channelmanager.rs Outdated
Comment on lines 51 to +52
use crate::ln::onion_utils;
use crate::ln::onion_utils::HTLCFailReason;

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.

nit:

Suggested change
usecrate::ln::onion_utils;
usecrate::ln::onion_utils::HTLCFailReason;
usecrate::ln::onion_utils::{self,HTLCFailReason};

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

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

I find the original more readable 🤷

Comment threadlightning/src/ln/onion_utils.rs Outdated
Comment threadlightning/src/ln/onion_utils.rs Outdated
Comment threadlightning/src/ln/channelmanager.rs
Comment threadlightning/src/ln/onion_utils.rs Outdated
Comment on lines +666 to +672
// we get a fail_malformed_htlc from the first hop
// TODO: We'd like to generate a NetworkUpdate for temporary
// failures here, but that would be insufficient as find_route
// generally ignores its view of our own channels as we provide them via
// ChannelDetails.
// TODO: For non-temporary failures, we really should be closing the
// channel here as we apparently can't relay through them anyway.

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.

Do these comments still make sense here, or should they stay in fail_backwards_internal?

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

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

The first TODO belongs here I think - it talks about building a NetworkUpdate which this fn is responsible for. The second we could debate but there's already a TODO that is equivalent at the callsite talking about if we blame our own channel.

@TheBlueMatt
TheBlueMattforce-pushed the 2022-12-fix-missing-data branch from 22d94a8 to af89d18CompareDecember 2, 2022 20:42
@valentinewallace

Copy link
Copy Markdown
Contributor

This test hits one of the new debug panics in HTLCFailReason::reason:

#[test]
fn test_phantom_failure_expires_too_soon() {
// Test that we fail back phantoms if the upstream node fiddled with the CLTV too much with the
// correct error code.
let chanmon_cfgs = create_chanmon_cfgs(2);
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
let channel = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
// Get the route.
let recv_value_msat = 10_000;
let (_, payment_hash, payment_secret) = get_payment_preimage_hash!(nodes[1], Some(recv_value_msat));
let (mut route, phantom_scid) = get_phantom_route!(nodes, recv_value_msat, channel);
// Route the HTLC through to the destination.
nodes[0].node.send_payment(&route, payment_hash, &Some(payment_secret), PaymentId(payment_hash.0)).unwrap();
check_added_monitors!(nodes[0], 1);
let update_0 = get_htlc_update_msgs!(nodes[0], nodes[1].node.get_our_node_id());
let mut update_add = update_0.update_add_htlcs[0].clone();
// Modify the route to have a too-low cltv.
// update_add.cltv_expiry += CLTV_FAR_FAR_AWAY;
connect_blocks(&nodes[1], 72);
nodes[1].node.handle_update_add_htlc(&nodes[0].node.get_our_node_id(), &update_add);
commitment_signed_dance!(nodes[1], nodes[0], &update_0.commitment_signed, false, true);
let update_1 = get_htlc_update_msgs!(nodes[1], nodes[0].node.get_our_node_id());
assert!(update_1.update_fail_htlcs.len() == 1);
let fail_msg = update_1.update_fail_htlcs[0].clone();
nodes[0].node.handle_update_fail_htlc(&nodes[1].node.get_our_node_id(), &fail_msg);
commitment_signed_dance!(nodes[0], nodes[1], update_1.commitment_signed, false);
// Ensure the payment fails with the expected error.
let mut fail_conditions = PaymentFailedConditions::new()
.blamed_scid(phantom_scid)
.expected_htlc_error_data(0x1000 | 14, &[]);
expect_payment_failed_conditions(&nodes[0], payment_hash, false, fail_conditions);
}

I think the other phantom 0x1000|14 error would hit the panic as well. I guess the lack of test coverage here is on me 😅

@valentinewallacevalentinewallace 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.

Really nice cleanup, basically LGTM

Comment threadlightning/src/ln/channelmanager.rs Outdated
Comment threadlightning/src/ln/onion_route_tests.rs Outdated
Comment threadlightning/src/ln/onion_utils.rs Outdated
// ChannelDetails.
if let &HTLCSource::OutboundRoute { ref path, .. } = htlc_source {
(None, Some(path.first().unwrap().short_channel_id), true, Some(*failure_code), Some(data.clone()))
} else { unreachable!(); }

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.

It'd remove some unreachables to make HTLCSource::OutboundRoute have an inner struct, but I think that'd be a future consideration

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

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

Yea, we should, agree it doesnt need to happen here.

@TheBlueMatt
TheBlueMattforce-pushed the 2022-12-fix-missing-data branch from a663ab2 to 35d8eb3CompareDecember 5, 2022 19:13
Comment threadlightning/src/ln/onion_utils.rs

@valentinewallacevalentinewallace 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 after squash

Now that it's entirely abstracted, there's no reason for
`HTLCFailReason` to be in `channelmanager`, it's really an
onion-level abstraction.
Now that `HTLCFailReason` is opaque and in `onion_utils`, we should
encapsulate it so that `ChannelManager` can no longer directly
access its inner fields.
This replaces `final_expiry_too_soon` with
`incorrect_or_unknown_payment` as was done in
lightning/bolts#608. Note that the
rationale for this (that it may expose whether you are the final
recipient for the payment or not) does not currently apply to us -
we don't apply different final CLTV values to different payments.
However, we might in the future, and this will make us slightly
more consistent with other nodes.
The spec mandates that we copy the `sha256_hash_of_onion` field
from the `UpdateFailMalformedHTLC` message into the error message
we send back to the sender, however we simply ignored it. Here we
copy it into the message correctly.
When we're constructing an HTLCFailReason, we should check that we
set the data to at least the correct length for the given failure
code, which we do here.
When we receive a phantom HTLC with a bogus/modified CLTV, we
should fail back with `incorrect_cltv_expiry`, but that requires a
`channel_update`, which we cannot generate for a phantom HTLC which
has no corresponding channel. Thus, instead, we have to fall back
to `incorrect_cltv_expiry`.
Fixeslightningdevkit#1879
This ensures we always hit our new debug assertions while building
failure packets in the immediately-fail pipeline while processing
an inbound HTLC.
If we try to send any onion error with the `UPDATE` flag in
response to a phantom receipt, we should always swap it for
something generic that doesn't require a `channel_update` in it.
Here we use `temporary_node_failure`.
Test provided by Valentine Wallace <vwallace@protonmail.com>
@TheBlueMatt
TheBlueMattforce-pushed the 2022-12-fix-missing-data branch from 878a41f to c9fe69fCompareDecember 6, 2022 20:00
@TheBlueMatt

Copy link
Copy Markdown
CollaboratorAuthor

Squashed without further changes.

@TheBlueMatt
TheBlueMatt merged commit 2390dbc into lightningdevkit:mainDec 6, 2022
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.

Ensure UPDATE errors have an update

4 participants

@TheBlueMatt@valentinewallace@codecov-commenter@wpaulino