Skip to content

Use LocalHTLCFailureReason in Onion Processing #3744

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

carlaKC
Copy link
Contributor

@carlaKC carlaKC commented Apr 17, 2025

This PR contains some of the follow ups that didn't make it into #3601:

  • Implement Display for LocalHTLCFailureReason
  • Use LocalHTLCFailureReason in onion error processing, removing the last few places where we were using raw u16 values
  • Adds a very simple macro to de-dup use of u16 failure codes in failure_code and from<u16> to dedup codes

@ldk-reviews-bot
Copy link

ldk-reviews-bot commented Apr 17, 2025

👋 Thanks for assigning @joostjager as a reviewer!
I'll wait for their review and will help manage the review process.
Once they submit their review, I'll check if a second reviewer would be helpful.

@carlaKC
Copy link
Contributor Author

carlaKC commented Apr 21, 2025

@joostjager anything else that you'd like to add here?

carlaKC added 2 commits April 21, 2025 11:26
In some places where we have LocalHTLCFailureReason, the string we're
passing around is redundant.

This isn't the case in all uses of LocalHTLCFailureReason, for example
InboundHTLCError provides additional information about payload and
blinding related errors that isn't captured in LocalHTLCFailureReason.
In these cases we keep the error string, tolerating some duplication.
These error codes were removed from the specification seven years ago
to prevent probing, so we don't need to handle these cases anymore.
Copy link
Contributor

@joostjager joostjager left a comment

Choose a reason for hiding this comment

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

The only comment that I think may not be in this PR is #3601 (comment)

If that one still applies now of course.

@@ -601,19 +601,18 @@ where

pub(super) fn check_incoming_htlc_cltv(
cur_height: u32, outgoing_cltv_value: u32, cltv_expiry: u32
) -> Result<(), (&'static str, LocalHTLCFailureReason)> {
) -> Result<(), LocalHTLCFailureReason> {
Copy link
Contributor

Choose a reason for hiding this comment

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

In decode_incoming_update_add_htlc_onion, encode_malformed_error could have its message param dropped perhaps.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We lose some information from the encode_relay_error calls eg: "Underflow calculating outbound amount or cltv value for blinded forward" just turns into InvalidOnionBlinding.

Tension between internal/api struct shows up there.

Copy link
Contributor

Choose a reason for hiding this comment

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

Doesn't that indicate that another enum value is needed, that is mapped to InvalidOnionBlinding on the wire?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We could add that, but IMO it's not interesting to surface that on the API, and they all map to the same bolt04 code.

So we'd be adding a new enum variant just for the sake of getting rid of a string - not worth the change IMO.

Copy link
Contributor

@joostjager joostjager Apr 26, 2025

Choose a reason for hiding this comment

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

It isn't completely clear to me why something like Underflow calculating outbound amount or cltv value for blinded forward isn't interesting to surface on the API, while other internal reasons that are also not uniquely mapped to a bolt code are.

This particular string also occurs in the code base multiple times.

But fine to leave as is.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

To me, blinding errors are totally useless to a forwarding node because somebody else made a mistake.

Other non-bolt04 errors like liquidity errors (actionable) and private channel aliases (interesting, somebody is probing you) just seem much more obvious candidates to be surfaced.

That said, there's also things like ZeroAmount that we've surfaced which arguably aren't interesting either (buggy sender), but they happened to be co-located with other interesting errors - so acknowledge that there isn't one pure logical reason for this, some of it is just what was easy/reasonable to do.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Noted in #3753.

@carlaKC
Copy link
Contributor Author

carlaKC commented Apr 23, 2025

The only comment that I think may not be in this PR is #3601 (comment)

Addressed in 2cc8799

@carlaKC carlaKC marked this pull request as ready for review April 23, 2025 13:43
@carlaKC carlaKC requested a review from joostjager April 23, 2025 13:43
@@ -601,19 +601,18 @@ where

pub(super) fn check_incoming_htlc_cltv(
cur_height: u32, outgoing_cltv_value: u32, cltv_expiry: u32
) -> Result<(), (&'static str, LocalHTLCFailureReason)> {
) -> Result<(), LocalHTLCFailureReason> {
Copy link
Contributor

Choose a reason for hiding this comment

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

Doesn't that indicate that another enum value is needed, that is mapped to InvalidOnionBlinding on the wire?

@ldk-reviews-bot
Copy link

👋 The first review has been submitted!

Do you think this PR is ready for a second reviewer? If so, click here to assign a second reviewer.

joostjager
joostjager previously approved these changes Apr 26, 2025
@ldk-reviews-bot
Copy link

✅ Added second reviewer: @wpaulino

@wpaulino wpaulino requested review from valentinewallace and removed request for wpaulino April 28, 2025 16:25
carlaKC added 2 commits April 28, 2025 16:03
De-duplicate use of u16 failure codes by using a macro that will
match against each variant's failure_code instead.
@carlaKC
Copy link
Contributor Author

carlaKC commented Apr 28, 2025

@joostjager your approval came in before I could address last comment last comment - diff here 🙏

@@ -1651,14 +1652,42 @@ impl LocalHTLCFailureReason {
}
}

fn get_onion_debug_field(&self) -> (&'static str, usize) {
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: document return values

self.failure_code() == LocalHTLCFailureReason::IncorrectPaymentDetails.failure_code()
|| *self == LocalHTLCFailureReason::FinalIncorrectCLTVExpiry
|| *self == LocalHTLCFailureReason::FinalIncorrectHTLCAmount
|| *self == LocalHTLCFailureReason::MPPTimeout
Copy link
Contributor

Choose a reason for hiding this comment

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

I think this is intended to only apply to errors that directly map from onion codes, but we could also include InvalidKeysendPreimage and PaymentSecretRequired here if we expect this method to be used elsewhere in the future.

Comment on lines 1388 to +1392
error_code,
error_code.failure_code(),
debug_field,
log_bytes!(&err_packet.failuremsg[4..4 + debug_field_size]),
description
error_code
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: no need to log error_code twice, similar below

@@ -1713,6 +1713,86 @@ impl From<u16> for LocalHTLCFailureReason {
}
}

impl fmt::Display for LocalHTLCFailureReason {
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm a bit hesitant on adding this, mainly because I'm not sure it adds much since the enum variant names are already nicely descriptive and can be easily cross-referenced to the LDK docs if more detail is desired. I also think one of the reasons we had strings to begin with was due to the lack of a nice enum, which we now have. We'll also need to remember to update these strings if any docs on the enum change, potentially. Don't feel tooo strongly about it though.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants