-
Notifications
You must be signed in to change notification settings - Fork 401
(3/3) Add Failure Reason to HTLCHandlingFailed #3700
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
base: main
Are you sure you want to change the base?
Conversation
👋 I see @wpaulino was un-assigned. |
d049301
to
6138779
Compare
6138779
to
2d39ef8
Compare
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #3700 +/- ##
==========================================
- Coverage 89.12% 89.09% -0.04%
==========================================
Files 156 156
Lines 123514 123670 +156
Branches 123514 123670 +156
==========================================
+ Hits 110086 110186 +100
- Misses 10749 10799 +50
- Partials 2679 2685 +6 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
2d39ef8
to
b48c6ce
Compare
Needs rebase 🥳 |
HTLCDestination currently contains a combination of information about the type of HTLC we handled to fail (a payment, a forward etc) and error information for a select set of cases (unknown next peer, for example). In preparation for a refactor that will split the failure reason out into its own enum, this commit renames HTLCDestination to HTLCHandlingType.
Rename variant to be more specific to the current context - a FailedPayment could be a payment that we failed to dispatch or one that we rejected on receive.
Standardize naming within the HTLCHandlingType struct to present more consistent API terminology.
This variant of HTLCHandlingType contains infromation about the failure cause along with its type - as an UnknownNextPeer is just an InvalidForward that has the failure type UnknownNextPeer. This commit deprecates the variant's use, while still writing it to disk to allow the option to downgrade.
This struct doesn't just contain a failure reason, it has all the data that's used to construct our failure.
b48c6ce
to
cda8de5
Compare
@@ -502,7 +502,7 @@ pub enum HTLCHandlingType { | |||
/// * The counterparty node modified the HTLC in transit, | |||
/// * A probing attack where an intermediary node is trying to detect if we are the ultimate | |||
/// recipient for a payment. | |||
FailedPayment { | |||
ReceiveFailed { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the context of HTLCHandlingType, this would communicate that receiving the htlc failed. Previously a reference to payment was in the name, but I think that was a layering violation?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This represents all HTLCs that were intended for our node as the final node, but were rejected.
I think that Payment
is a bad name here because PaymentFailed
could refer to a payment you sent or one you received (it was unclear to me when I first encountered this struct). Receive
is less ambiguous.
@@ -471,7 +471,7 @@ impl_writeable_tlv_based_enum_upgradable!(ClosureReason, | |||
pub enum HTLCHandlingType { | |||
/// We tried forwarding to a channel but failed to do so. An example of such an instance is when | |||
/// there is insufficient capacity in our outbound channel. | |||
NextHopChannel { | |||
ForwardFailed { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed, it shouldn't be underestimated how much naming helps with understanding code.
@@ -525,6 +525,31 @@ impl_writeable_tlv_based_enum_upgradable!(HTLCHandlingType, | |||
}, | |||
); | |||
|
|||
/// The reason for HTLC failures in [`Event::HTLCHandlingFailed`]. | |||
#[derive(Clone, Debug, PartialEq, Eq)] | |||
pub enum HTLCHandlingFailureReason { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This one does remind me of HTLCFailReasonRepr
. Isn't there more in that struct that might be useful to expose here such as the failure data or the hold time?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Definitely, this is essentially an external facing version of HTLCFailReasonRepr
.
I don't think that we'll ever want to surface the encrypted data blob on the API, which is my main reason for not surfacing HTLCFailReasonRepr
.
We're also not going to have tons and tons of fields that we need to translate from one to the other so I think it's nice to have a clean/readable api-facing struct.
@@ -466,9 +466,9 @@ impl_writeable_tlv_based_enum_upgradable!(ClosureReason, | |||
}, | |||
); | |||
|
|||
/// Intended destination of a failed HTLC as indicated in [`Event::HTLCHandlingFailed`]. | |||
/// The type of HTLC that is being handled in [`Event::HTLCHandlingFailed`]. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"the type of htlc that is being handled", but isn't it more the outcome of the htlc forward, not saying much about the htlc itself? In particular ForwardFailed
doesn't have much to do with the htlc?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"the type of htlc that is being handled", but isn't it more the outcome of the htlc forward, not saying much about the htlc itself?
Would "the handling action taken" be better? Aiming to represent what we were supposed to do to the HTLC we were handed (forward it/ receive it / we don't know because it's invalid).
Open to better naming/wording if you have it, but I do think that outcome
is more associated with settle/fail so not a good fit here.
ForwardFailed doesn't have much to do with the htlc?
Do you mean InvalidForward
?
@@ -480,12 +480,16 @@ pub enum HTLCHandlingType { | |||
channel_id: ChannelId, | |||
}, | |||
/// Scenario where we are unsure of the next node to forward the HTLC to. | |||
/// |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typo in commit msg 'infromation'
let downgradable_type = match (handling_type, handling_failure) { | ||
(HTLCHandlingType::InvalidForward { requested_forward_scid }, | ||
Some(HTLCHandlingFailureReason::Local { reason })) | ||
if *reason == LocalHTLCFailureReason::UnknownNextPeer => |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe you can get rid of the inner if
let downgradable_type = match (handling_type, handling_failure) {
(
HTLCHandlingType::InvalidForward { requested_forward_scid },
Some(HTLCHandlingFailureReason::Local {
reason: LocalHTLCFailureReason::UnknownNextPeer,
}),
) => HTLCHandlingType::UnknownNextHop {
requested_forward_scid: *requested_forward_scid,
},
_ => handling_type.clone(),
};
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice 🧹
// where we have a legacy event | ||
match event { | ||
Event::HTLCHandlingFailed { ref handling_type, .. } => { | ||
if let HTLCHandlingType::UnknownNextHop { requested_forward_scid } = handling_type { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similar alternative:
match event {
Event::HTLCHandlingFailed { handling_type: HTLCHandlingType::UnknownNextHop { requested_forward_scid }, .. } => {
event = Event::HTLCHandlingFailed {
prev_channel_id,
handling_type: HTLCHandlingType::InvalidForward {
requested_forward_scid: requested_forward_scid,
},
handling_failure: Some(LocalHTLCFailureReason::UnknownNextPeer.into()),
};
}
_ => panic!("HTLCHandlingFailed wrong type"),
}
@@ -480,12 +480,16 @@ pub enum HTLCHandlingType { | |||
channel_id: ChannelId, | |||
}, | |||
/// Scenario where we are unsure of the next node to forward the HTLC to. | |||
/// | |||
/// Deprecated: will only be used in versions before LDK v0.2.0. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I still see one occurrence of HTLCHandlingType::UnknownNextHop in a macro in process_pending_htlc_forwards
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
#[derive(Clone)] // See Channel::revoke_and_ack for why, tl;dr: Rust bug | ||
#[cfg_attr(test, derive(PartialEq))] | ||
pub(super) struct HTLCFailReason(HTLCFailReasonRepr); | ||
pub(super) struct HTLCFailurePayload(HTLCFailReasonRepr); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Embedded inside there is still a reason? Payload with a reason repr 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rename the internal struct as well?
Open to other naming suggestions here, aim is to differentiate this from the HTLCHandlingFailureReason
a bit.
This PR surfaces a failure reason in
HTLCHandlingFailed
events. Opening up early to add some context to the prefactor PR #3601.The heart of the PR is in d35d35f, and it could probably be reduced to just this commit. I've made some quite opinionated renaming / deprecation decisions in the other commits which aren't required for this change, but I think make for a more readable API overall - happy to drop them if it ain't broke, don't fix it applies.
Fixes: #3561
Fixes: #3541