-
Notifications
You must be signed in to change notification settings - Fork 367
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
Expose API to update a channel's ChannelConfig #1527
Expose API to update a channel's ChannelConfig #1527
Conversation
206a98b
to
7394b93
Compare
Needs rebase after #1529 landed. |
7394b93
to
cadf33a
Compare
Codecov Report
@@ Coverage Diff @@
## main #1527 +/- ##
==========================================
+ Coverage 90.92% 91.85% +0.93%
==========================================
Files 80 80
Lines 43533 47946 +4413
Branches 43533 47946 +4413
==========================================
+ Hits 39582 44041 +4459
+ Misses 3951 3905 -46
Continue to review full report at Codecov.
|
Its probably worth supporting forwarding with the previous config for a minute or so after the update, no need to bother serializing that part out, just keep an |
cadf33a
to
4d0bb1b
Compare
Pushed a new version implementing this. |
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! Few nits, two questions.
lightning/src/ln/channelmanager.rs
Outdated
// We attempt to forward the HTLC with the current policy, or the previous | ||
// for a short period of time. | ||
if let Some(prev_config) = chan.get_prev_config() { | ||
if chan.get_update_time_counter() > prev_config.1 + 1 { |
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.
Mh, I see that using the update time counter is the most straight forward here, but it's probably not that well correlated with real time? Since the propagation delay of channel updates are in real time, I wonder if the grace period should be based on that rather than the counter, e.g., by clearing the prev config when a (time-delayed) event fires?
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.
+1, relatedly, lets try to keep this kinda logic in channel.rs and have as little channel logic in channelmanager.rs as possible. This may also be an opportunity to move the "what is the fee I'm currently applying for a payment of value X" logic into channel.rs and also just ask for the current cltv-delta from the Channel vs doing the previous-update logic here.
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.
Mh, I see that using the update time counter is the most straight forward here, but it's probably not that well correlated with real time? Since the propagation delay of channel updates are in real time, I wonder if the grace period should be based on that rather than the counter, e.g., by clearing the prev config when a (time-delayed) event fires?
The expiration of the previous config now relies on ChannelManager::timer_tick_occured
. See the rationale behind how many ticks need to happen within the commit, but TLDR, it's based on the average convergence delay of updates across the network as seen in https://arxiv.org/pdf/2205.12737.pdf. We could be a bit more forgiving and bump it so that we can account for 95% of all nodes or even 100%.
This may also be an opportunity to move the "what is the fee I'm currently applying for a payment of value X" logic into channel.rs and also just ask for the current cltv-delta from the Channel vs doing the previous-update logic here.
Slightly refactored to help achieve this. I would've liked to just expose a single fee and CLTV delta from Channel
, but I found it a bit awkward now that we have two possible values.
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.
Note: As of yesterday's meeting, the spec seems to lean towards a 10 minute grace period.
4d0bb1b
to
00ebbbb
Compare
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, mod two comments and the failing benchmark. Nice solution using timer_tick_occured
!
I also wonder if we need to be opinionated here and enforce a certain rate limiting on channel updates, or if we should allow the user to spam BroadcastChannelUpdate
via update_channel_config()
.
00ebbbb
to
fae37b9
Compare
Could be worthy of a follow-up. We'd likely want to implement a block-based rate limit as it seems we'll be moving forward with that anyway in a future gossip upgrade. |
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.
LGTM, only one small nit.
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.
Basically looks good. Haven't reviewed the test changes in detail yet.
@@ -345,6 +345,14 @@ impl Default for ChannelConfig { | |||
} | |||
} | |||
|
|||
impl_writeable_tlv_based!(ChannelConfig, { |
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.
Ugh, yuck, so now between 108 and 109 we'll keep the ChannelConfig
serialization but it'll be different but silent. Can we move the 8 on force_close_avoidance_max_fee_satoshis
to 10 (and make all the fields required, not default_value) so that we'll explicitly fail to read a ChannelConfig
(and old versions will fail to read new ones)?
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.
Yeah I wasn't happy about this either, thanks for the pointer. I dug into this a bit deeper and noticed that ChannelDetails
is serialized within PhantomRouteHints
, which impls the writeable macro but doesn't seem to be used anywhere through the codebase. I assume this is intended as noted in #1294? Otherwise it would've been nice to remove all of this serialization. Another approach would be to reduce ChannelDetails
to a new struct only containing the fields necessary for phantom invoices.
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.
Yea, we expect users to de/serialize ChannelDetails
objects, so I think we need this, but we definitely dont expect users to serialize ChannelConfig
objects manually. Maybe we should have some non-public internal serialization trait, I dunno, but for now this seems fine and we can mention it in the release notes.
|
||
if (msg.cltv_expiry as u64) < (*outgoing_cltv_value) as u64 + forwardee_cltv_expiry_delta as u64 { // incorrect_cltv_expiry |
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.
We should keep checking this for phantom forwards, which is why it was outside the if let Some(..) = forwarding_id_opt
block. We can always just re-add this check using MIN_CLTV_EXPIRY_DELTA
explicitly.
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.
Added. Any reason to not check the fee here as well? We could use the default config and call the new htlc_satisfies_config
method.
6943c8c
to
a70d922
Compare
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.
LGTM
Feel free to squash. |
As we prepare to expose an API to update a channel's ChannelConfig, we'll also want to expose this struct to consumers such that they have insights into the current ChannelConfig applied for each channel.
A new `update_channel_config` method is exposed on the `ChannelManger` to update the `ChannelConfig` for a set of channels atomically. New `ChannelUpdate` events are generated for each eligible channel. Note that as currently implemented, a buggy and/or auto-policy-management client could spam the network with updates as there is no rate-limiting in place. This could already be done with `broadcast_node_announcement`, though users are less inclined to update that as frequently as its data is mostly static.
We do this to prevent payment failures while the `ChannelUpdate` for the new `ChannelConfig` still propagates throughout the network. In a follow up commit, we'll honor forwarding HTLCs that were constructed based on either the previous or current `ChannelConfig`. To handle expiration (when we should stop allowing the previous config), we rely on the ChannelManager's `timer_tick_occurred` method. After enough ticks, the previous config is cleared from memory, and only the current config applies moving forward.
This is mostly motivated by the fact that payments may happen while the latest `ChannelUpdate` indicating our new `ChannelConfig` is still propagating throughout the network. By temporarily allowing the previous config, we can help reduce payment failures across the network.
a70d922
to
0f30d76
Compare
A new
update_channel_config
method is exposed on theChannelManger
to update the ChannelConfig for a set of channels atomically. New ChannelUpdate events are generated for each eligible channel.Note that as currently implemented, a buggy and/or auto-policy-management client could spam the network with updates as there is no rate-limiting in place. This could already be done with
broadcast_node_announcement
, though users are less inclined to update that as frequently as its data is mostly static.Fixes #216.