-
Notifications
You must be signed in to change notification settings - Fork 419
LSPS5 implementation #3662
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
LSPS5 implementation #3662
Conversation
👋 Thanks for assigning @TheBlueMatt as a reviewer! |
This is a huge PR, but it wasn’t obvious to me how to split it in a way that would still make sense (I did split it into small commits to make it easier to review.). I’m open to suggestions if you have ideas on how this could be structured differently. |
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #3662 +/- ##
==========================================
- Coverage 88.95% 88.92% -0.04%
==========================================
Files 168 173 +5
Lines 121974 123393 +1419
Branches 121974 123393 +1419
==========================================
+ Hits 108502 109723 +1221
- Misses 11072 11216 +144
- Partials 2400 2454 +54
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
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.
Wow, thank you for looking into this! I did a first pass, and it looks pretty amazing already!
Before going too much into further details, here are a few general comments upfront:
-
I'm generally no fan of introducing additional dependencies here, an in particular not
reqwest
andtokio
. I think following the pattern so farBroadcastNotifications
could be a request that the user handles with any HTTP client they want and then could call back intoLSPS5ServiceHandler
. Alternatively, we could also use a trait similar to the currentHTTPClient
, but I don't think we want to keep the default implementation. Note that the blockingreqwest
variant wraps atokio
runtime internally, and therefore should never (1, 2, ...) be used together. I guess technically we could consider a defaultasync
version of the trait that usesasync
reqwest
, but I would prefer to simply have well-documented trait on our end that the user can implement however they choose to. Also note that stackingtokio
runtimes is heavily discouraged in general, so assuming our users would themselves use atokio
runtime, we shouldn't wrap one inLSPS5ServiceHandler
. -
Note that
lightning-liquidity
is optionally no-std
compliant, so please don't rely onstd
wherever possible, often it's just a matter of usingcore
instead and importing the respective types fromcrate::prelude
. If you really find yourselves needing to usestd
, make sure it's feature gated behindfeature = "std"
and we provide an alternative for users that don't support it. -
Minor: Regarding formatting we're using tabs, not spaces. Feel free to run
./contrib/run-rustfmt.sh
after each commit to run our formatting scripts. -
This PR in its current scope is great, just want to note that eventually we need to add persistence for the state. As we haven't fully fleshed out the persistence strategy for
lightning-liquidity
in general yet, it's actually preferred to defer this to a follow-up, but just wanted to mention it. Also note that some changes toMessageQueue
/EventQueue
will happen in #3509, but will ping you to rebase once that has been merged. (just sidenotes here).
I hope these initial points make sense, let me know if you have any questions, or once you made corresponding changes and think this is ready for the next round of review!
👋 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. |
Thanks for asking! I'm totally fine to keep this (with its current scope) in a single PR, as long as we keep the commit history pretty clean to allow continuing review to happen commit-by-commit. To this end, please make sure add any fixup commits clearly marked (e.g. via a |
Btw, I'm not sure if you're familiar with the previous attempt of implementing LSPS5: #3499 Given this is a clean slate, not sure how much there is to learn, but still might be worth a look. Also not sure if @johncantrell97 would be interested in reviewing this PR, too, as he's familiar with the codebase and LSPS5. |
1d4b47c
to
edf5346
Compare
@tnull, ready for the next review round!
CI is failing because of the usage of the |
9809682
to
af5929e
Compare
🔔 1st Reminder Hey @tnull @valentinewallace! This PR has been waiting for your review. |
1 similar comment
🔔 1st Reminder Hey @tnull @valentinewallace! This PR has been waiting for your review. |
@TheBlueMatt just pushed a few commits addressing your comments. let me know what you think |
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.
One last improvement suggestion on the fixups (add a link), otherwise fixups are fine by me and would be good for squashing.
lightning/src/sign/mod.rs
Outdated
/// Sign an arbitrary message with the node's secret key. | ||
/// | ||
/// Creates a digital signature of a message given the node's secret. The message is prefixed | ||
/// with "Lightning Signed Message:" before signing. |
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.
FWIW, we could link to Rusty's spec-in-a-tweet here: https://web.archive.org/web/20191010011846/https://twitter.com/rusty_twit/status/1182102005914800128
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.
looks good 2cb5743
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 think I'm happy with this as it is, needs squash, though (I think the need for rebase will go away after squash, but maybe not).
This will be used to allow disabling time-dependent functionality. 'time' is included in the features default.
Introduce new_from_duration_since_epoch constructor from Duration. Also add abs_diff function to use on client / service. Also do feature='time' instead of feature='std' on time related functionality
…5/service when signing notifications
Allows validating webhook URLs without depending on the external url crate.
Define LSPSMessage request, response and error types. Also introduce LSPS5AppName, LSPS5WebhookUrl, WebhookNotification types
Introduce SendWebhookNotification event for LSPS5/service, and also WebhookRegistered, WebhookRegistrationFailed, WebhooksListed, WebhookRemoved and WebhookRemovalFailed events for LSPS5/client.
Implements the LSPS5 webhook registration service that allows LSPs to notify clients of important events via webhooks. This service handles webhook registration, listing, removal, and notification delivery according to the LSPS5 specification.
Implements the client-side functionality for LSPS5 webhook registration, allowing clients to register, list, and remove webhooks with LSPs.
…ions from an LSP. As context, this utility started as part of the client, but was extracted in favor of having it separated, so it's clear that this functions should not be used by the client, but by the proxy server that has to forward the notifications
Fully integrates the LSPS5 webhook components into the lightning-liquidity framework, enabling usage through the LiquidityManager.
conflicts fixed and fixups squashed! |
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.
Alright, since Matt said he's happy I'm gonna land this to reduce the risk of the branch getting stale yet again. We have quite a few follow-ups planned anyways, so can always still iterate on it if we found we missed something.
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.
Did another brief skim through and found a few more things its probably worth following up on.
"Received unexpected request message from {}", | ||
counterparty_node_id | ||
), | ||
action: ErrorAction::IgnoreAndLog(Level::Info), |
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.
Oops, we shouldn't log at INFO a peer (any peer, might not be "our LSP") sending us garbage.
}; | ||
let mut result: Result<(), LightningError> = Err(LightningError { | ||
err: format!("Received LSPS5 response from unknown peer: {}", counterparty_node_id), | ||
action: ErrorAction::IgnoreAndLog(Level::Error), |
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.
Same here, we shouldn't be logging at ERROR
a peer sending us garbage.
} else { | ||
result = Err(LightningError { | ||
err: format!("Received response for unknown request ID: {}", request_id.0), | ||
action: ErrorAction::IgnoreAndLog(Level::Info), |
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.
Same here.
pub struct LSPS5ServiceConfig { | ||
/// Maximum number of webhooks allowed per client. | ||
pub max_webhooks_per_client: u32, | ||
/// Minimum time between sending the same notification type in hours (default: 24) |
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.
Shouldn't this be, like, 30 seconds, not a full day? If a user receives two payments over the course of an hour we definitely want to send two notifications, not eat the second.
lsps5_client_handler.handle_message(msg, sender_node_id)?; | ||
}, | ||
None => { | ||
return Err(LightningError { err: format!("Received LSPS5 response message without LSPS5 client handler configured. From node = {:?}", sender_node_id), action: ErrorAction::IgnoreAndLog(Level::Info)}); |
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.
Here and in the logs above we also shouldn't be logging this at INFO level.
A complete implementation for LSPS5 (spec defined here lightning/blips#55)
Reviewing commit by commit is recommended (~40% of the added lines are tests)
Notes:
- Will rebase fromDONElightning-liquidity
: IntroduceEventQueue
notifier and wake BP for message processing #3509 once that PR is merged