Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

missioncontrol: add invalid onion blinding handling for blinded paths #8095

Merged
merged 7 commits into from
Jan 3, 2024

Conversation

carlaKC
Copy link
Collaborator

@carlaKC carlaKC commented Oct 13, 2023

This PR updates mission control to handle InvalidOnionBlinding errors, fixes #7882.

Key ideas in this PR (h/t @bitromortac for digging into edge cases):

  • Blinded errors should only every originate from an introduction node.
  • We should not penalize the introduction node, as it is responsible for reporting on behalf of the blinded route.
  • We should minimize the number of ephemeral blinded keys that we store in mission control, as they're single use (also the case with bolt 11 hop hints).

Key for images:

  • Yellow = node sending InvalidOnionBlinding
  • Pink = node penalized
  • Green = node success

❗ Handling has been updated to also reward the incoming link to the introduction node after discussion on the PR, images are slightly outdated ❗

Regular Blinded Paths

Screenshot 2023-10-31 at 9 57 28 AM

Misuse of Error Code

Screenshot 2023-10-31 at 9 57 34 AM

Final Hop

Final Hop Case:
Screenshot 2023-10-31 at 9 57 40 AM

@carlaKC carlaKC force-pushed the 7882-mcblinding branch 2 times, most recently from 152ca56 to dd01d71 Compare October 13, 2023 19:31
@Roasbeef Roasbeef added this to the v0.18.0 milestone Oct 13, 2023
@Roasbeef Roasbeef requested a review from bitromortac October 13, 2023 19:31
Copy link
Collaborator

@bitromortac bitromortac left a comment

Choose a reason for hiding this comment

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

Nice 👍, I provided some initial feedback, hope my understanding is correct there.

lnwire/onion_error.go Outdated Show resolved Hide resolved
// Everything up until the error source forwarded the payment
// correctly.
i.successPairRange(route, 0, errorSourceIdx-1)
i.failPairRange(
Copy link
Collaborator

Choose a reason for hiding this comment

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

With failPairRange this fails pairs after errorSourceIdx completely, which means that all hops afterwards are discarded for any amount in future attempts, because the failure amount is set to zero (additionally pairs are failed backwards and forwards, which may be unneccesary). I feel like we should use failPairBalance only for the last hop, as this will already invalidate the blinded part of the route for the amount that was tried, but it leaves some room for the splitting algo to retry the blinded path in case of multiple blinded paths? The other benefit of this would be to not pollute mission control with many ephemeral keys (payment successes could be handled similarly).

I think we ideally don't want any ephemeral outgoing pairs associated with the introduction node to be reported failed (as it currently is) nor succeeded. Node reputation is computed on all outgoing results of a node, which is why this would add/remove node penalization (hope my analysis is correct, see https://github.com/lightningnetwork/lnd/blob/master/routing/missioncontrol.go#L335 and https://github.com/lightningnetwork/lnd/blob/master/routing/probability_apriori.go#L180). Otherwise this may be gameable by providing faulty invoices that would worsen/improve introduction nodes' routing reputation.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I feel like we should use failPairBalance only for the last hop, as this will already invalidate the blinded part of the route for the amount that was tried

Oh yeah, this is much nicer. WDYT we should do in the case of a single hop blinded route (Introduction -> Blinded Recipient), because failPairBalance is only effective on intermediate nodes rn? afaik we don't have a way to penalize the blinded recipient without penalizing the intro node, so just set a final failure so that we give up?

Otherwise this may be gameable by providing faulty invoices that would worsen/improve introduction nodes' routing reputation.

I do wonder how much we actually need to worry about this? To "poison" an introduction node, the malicious receiver needs to get the sender to pay that invoice. Which would only happen if the sender wants to make that payment (buy something / send money etc), and then surely the receiver is more incentivized to "shut up and take my money"? Not disagreeing with leaving the intro node untouched (makes sense for node score), just not sure how much of a threat it would be.

Thanks for taking a look!

Copy link
Collaborator

Choose a reason for hiding this comment

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

Oh yeah, this is much nicer. WDYT we should do in the case of a single hop blinded route (Introduction -> Blinded Recipient), because failPairBalance is only effective on intermediate nodes rn? afaik we don't have a way to penalize the blinded recipient without penalizing the intro node, so just set a final failure so that we give up?

Yes, that one is tricky, but it seems reasonable to fail the payment, since the receiver should have added a route hint that has liquidity. Another case which is not handled right now is the case where we see FailInvalidBlinding from a node after the introduction point (spec violated twice?). In that case we probably would like to punish the introduction node for not letting the error originate from it (thereby also invalidating the blinded route). Since all of this is really complicated I tried check any edge cases as well (https://github.com/bitromortac/lnd/tree/re-8095-231018-11-blinded-error).

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yes, that one is tricky, but it seems reasonable to fail the payment, since the receiver should have added a route hint that has liquidity.

I think this might get a little tricky with multi-blinded path support, but I think this is a good start for the single-path case.

Thanks for going through all the edge cases! Updated code to account for single hop case + errors after the introduction node. Also updated PR description with overview of each case - lmk if anything is missing / different to your interpretation.

Copy link
Collaborator

@bitromortac bitromortac left a comment

Choose a reason for hiding this comment

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

Nice updates, great code documentation! I think there are two issues left, one is to mark the hop before the intro node successful in some cases and to check error conversion for all error types if it's a blinded route.

routing/result_interpretation.go Outdated Show resolved Hide resolved
routing/result_interpretation_test.go Outdated Show resolved Hide resolved
routing/result_interpretation.go Outdated Show resolved Hide resolved
@carlaKC
Copy link
Collaborator Author

carlaKC commented Nov 6, 2023

Updated handling of blinded errors after the introduction node to a higher level in the decision tree (before we decide to handle intermediate / final). I think that this makes sense because it's a new "class" or error type we need to handle, but also happy to move it into the individual process functions if that's more readable.

@bitromortac bitromortac self-requested a review November 7, 2023 10:49
Copy link
Collaborator

@bitromortac bitromortac left a comment

Choose a reason for hiding this comment

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

LGTM 🎉

@saubyk saubyk requested a review from ziggie1984 November 9, 2023 19:46
@lightninglabs-deploy
Copy link

@ziggie1984: review reminder

@carlaKC
Copy link
Collaborator Author

carlaKC commented Dec 12, 2023

Latest push just a rebase!

Copy link
Collaborator

@ziggie1984 ziggie1984 left a comment

Choose a reason for hiding this comment

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

Very difficult topic and rock solid PR 💪

Had only some nits.

routing/result_interpretation.go Show resolved Hide resolved
routing/result_interpretation.go Outdated Show resolved Hide resolved
routing/result_interpretation_test.go Outdated Show resolved Hide resolved
routing/result_interpretation_test.go Outdated Show resolved Hide resolved
routing/result_interpretation_test.go Outdated Show resolved Hide resolved
routing/result_interpretation_test.go Show resolved Hide resolved
routing/result_interpretation.go Show resolved Hide resolved
routing/result_interpretation.go Show resolved Hide resolved
routing/result_interpretation_test.go Outdated Show resolved Hide resolved
@carlaKC carlaKC force-pushed the 7882-mcblinding branch 2 times, most recently from 5a3a4ab to 0075a8e Compare December 18, 2023 17:05
This commit adds handling for errors that originate after the
introduction node when making payment to a blinded route. This
indicates that the introduction node is not obeying the spec, so
it is punished for the violation.
This commit adds handling for route blinding errors that are reported
by the introduction node in a multi-hop blinded route. As the
introduction node is always responsible for handling blinded errors,
it is not penalized - only the final hop is penalized to discourage the
blinded route without filling up mission control with ephemeral
results.

If this error code is reported by a node that is not an introduction
node, we penalize the node because it is returning an error code that
it should not be using.
Note: this refactor updates the inequality used from >= 2 to > 1 to
align with the rest of this file so that we express this concept
consistently throughout the code.
We do not expect blinding errors from the final node:
1. If the introduction is the recipient, they should use regular errors.
2. Otherwise, nodes have no business sending this error when they are
   not part of a blinded route.
Copy link
Collaborator

@ziggie1984 ziggie1984 left a comment

Choose a reason for hiding this comment

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

LGTM ⭐️

EDIT: Maybe it makes sense to create an issue that specifies that the error handling will need to get updated when we are capable of forwarding/failing blinded path payments ?

@Roasbeef
Copy link
Member

Roasbeef commented Jan 3, 2024

EDIT: Maybe it makes sense to create an issue that specifies that the error handling will need to get updated when we are capable of forwarding/failing blinded path payments ?

Def, can you create this (given current context) @carlaKC?

@Roasbeef Roasbeef merged commit ffd330a into lightningnetwork:master Jan 3, 2024
23 of 25 checks passed
@carlaKC
Copy link
Collaborator Author

carlaKC commented Jan 9, 2024

Opened #8363 with write up, @ziggie1984 / @bitromortac please give it a peep to make sure I've covered everything properly!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

[Followup]: Update Mission Control to Handle invalid_onion_blinding
5 participants