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

Make onion fields optional on lsp client hook handler #544

Merged
merged 4 commits into from
Nov 25, 2024

Conversation

nepet
Copy link
Collaborator

@nepet nepet commented Nov 21, 2024

This PR makes all of the onion payload fields for the lsp clients htlc_accepted hook handler optional. We can not assume that all fields are set and we need to act to what we get. If the handler processes an onion payload that is missing essential fields it will stop executing and return the continue signal to core-lightning to pass the htlc to the next processor/handler in line.

Resolves #541

@nepet nepet requested a review from cdecker November 21, 2024 14:21
@nepet nepet changed the title Make onion fields optional Make onion fields optional on lsp client hook handler Nov 21, 2024
#[serde(deserialize_with = "from_hex_opt")]
shared_secret: Option<Vec<u8>>,
#[serde(deserialize_with = "from_hex_opt")]
next_onion: Option<Vec<u8>>,
Copy link
Collaborator

Choose a reason for hiding this comment

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

Copy link
Collaborator

@cdecker cdecker left a comment

Choose a reason for hiding this comment

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

All good changes, let's just reflect the shared_secret and next_onion having the correct optionality (they're not optional), and the other things are suggestions, so feel free to drop them.

// An onion payload without an `amt_to_forward` is unorthodox and
// can not be processed by this plugin. Skip it.
log::debug!(
"lsp-plugin: got an onion payload={} without an amt forward_msat.",
Copy link
Collaborator

Choose a reason for hiding this comment

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

Add the outcome continuing so we don't spook people reading the logs, thinking that it is not being handled.

@@ -22,8 +22,7 @@ def test_node_start(scheduler, clients):


def test_node_connect(scheduler, clients, bitcoind):
"""Register and schedule a node, then connect to it.
Copy link
Collaborator

Choose a reason for hiding this comment

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

Feels like the changes here should have been a separate format commit. Are there any logic changes in here?

/// signal to core-lightning. This is to be used when we don't know how to
/// handle a given payload or as a shortcut in case we could identify that the
/// incoming htlc is not part of a LSP jit channel opening.
macro_rules! unwrap_or_continue {
Copy link
Collaborator

Choose a reason for hiding this comment

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

I wonder if this couldn't have been a trait on the Result type instead? That would retain the operation.unwrap_or_continue() order and allow better chaining, rather than having to wrap like this unwrap_or_continue!(operation).

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This is what i considered to do first, but I fail to see how this is possible. How can we return an outer function from an inner function without calling panic (like unwrap does)? I also explored the possibility of using a ControlFlow or a custom implementation of the Try trait, using the ?-operator, but that also seemed a bit overly complicated given that we only use this in one place for now (the try trait is experimental as well).
I would suggest to leave it as is for now and If we feel that we could profit from this pattern at other places as well, we can move it upstream to the cln-plugin repo and may come up with a solution that is a bit more aligned with the chaining approach that rust follows.

As reported by JssDWt in #541,
the fields of the onion passed to the  htlc_accepted_hook might not be
set. To avoid any unnecessary panics we make them optional and handle an
unset field in the lsp plugin.

Signed-off-by: Peter Neuroth <[email protected]>
Adds a check that we return "continue" on the htlc_accepted_hook if we
don't understand an onion payload in the lsp client plugin because of
missing fields.

Signed-off-by: Peter Neuroth <[email protected]>
Adds a macro that allows us to replace `unwrap`s in order to prevent
panics. The macro shortcuts further execution and returns from the
htlc_accepted_hook.

Signed-off-by: Peter Neuroth <[email protected]>
Remove clippy errors on lsp.rs:
`the borrowed expression implements the required traits`

Signed-off-by: Peter Neuroth <[email protected]>
@nepet nepet force-pushed the 2447-make-onion-fields-optional branch from 74b1a0e to be47278 Compare November 25, 2024 13:02
@nepet
Copy link
Collaborator Author

nepet commented Nov 25, 2024

Made shared_secret and next_onion optional and rebased on main.

@cdecker cdecker dismissed their stale review November 25, 2024 13:39

Feedback had been addressed.

@cdecker cdecker merged commit 17c71aa into main Nov 25, 2024
12 checks passed
@cdecker cdecker deleted the 2447-make-onion-fields-optional branch November 25, 2024 13:39
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.

panic potential: htlc_accepted hook may have some fields not set
2 participants