-
Notifications
You must be signed in to change notification settings - Fork 407
Avoid persisting a ChannelManager after each timer tick and send update_channel re-enable messages #916
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
Avoid persisting a ChannelManager after each timer tick and send update_channel re-enable messages #916
Conversation
1dabdc0
to
cad69f4
Compare
Codecov Report
@@ Coverage Diff @@
## main #916 +/- ##
==========================================
+ Coverage 90.46% 90.55% +0.08%
==========================================
Files 59 59
Lines 29788 29911 +123
==========================================
+ Hits 26948 27086 +138
+ Misses 2840 2825 -15
Continue to review full report at Codecov.
|
8d7a09f
to
9b69e1e
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.
Cool! I like how it sets a foundation for removing other unnecessary persists in the future too
9b69e1e
to
ba7a0c0
Compare
lightning/src/ln/functional_tests.rs
Outdated
let short_id = msg.contents.short_channel_id; | ||
// Check generated channel_update match list in PendingChannelUpdate | ||
if short_id != short_id_1 && short_id != short_id_2 && short_id != short_id_3 { | ||
panic!("Generated ChannelUpdate for wrong chan!"); | ||
} |
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.
Not sure I understand the value of this check. There aren't any other channels to update and it doesn't guarantee all channels are covered. Would the test suffice using one channel instead?
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.
Hmm, possibly? From a black-box point-of-view, its somewhat nice to ensure that it works in any direction - inbound or outbound and across multiple channels, though given the implementation I agree it'd be hard to screw that up. I went ahead and simplified this check, though.
Currently, we only send an update_channel message after disconnecting a peer and waiting some time. We do not send a followup when the peer has been reconnected for some time. This changes that behavior to make the disconnect and reconnect channel updates symmetric, and also simplifies the state machine somewhat to make it more clear. Finally, it serializes the current announcement state so that we usually know when we need to send a new update_channel.
e981c57
to
4edd86d
Compare
Pushed two different approaches to cleaning up the notifierguard, see the two fixup commits. |
I was hoping with the closure-based approach, the guarded code could go into the closure. But I guess that gets messy if you also need to return a value. Seems ok as is then. For naming, I'd say the methods and enums are about notifying persisters rather than persisting itself, so should be named in such a manner (e.g., |
4edd86d
to
0a448b3
Compare
Ah! Indeed we could. |
0a448b3
to
0f24e79
Compare
lightning/src/ln/channelmanager.rs
Outdated
fn notify_on_drop(lock: &'a RwLock<()>, notifier: &'a PersistenceNotifier) -> PersistenceNotifierGuard<'a, impl Fn() -> PersistenceGuardOption> { | ||
PersistenceNotifierGuard::optionally_notify(lock, notifier, || -> PersistenceGuardOption { PersistenceGuardOption::DoPersist }) | ||
} | ||
|
||
fn optionally_notify<F: Fn() -> PersistenceGuardOption>(lock: &'a RwLock<()>, notifier: &'a PersistenceNotifier, persist_check: F) -> PersistenceNotifierGuard<'a, F> { |
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.
Would Self
for the return type work for these?
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.
No, we could move it into its own impl block and use Self
, but notify_on_drop
always has to be in a concrete impl block and return something else. I figured it was easier to just put them both in a concrete impl block (with concrete types that we don't care about) and then make the return types explicit.
0f24e79
to
533eef8
Compare
533eef8
to
39bd883
Compare
lightning/src/ln/channelmanager.rs
Outdated
// We hold onto this result so the lock doesn't get released immediately. | ||
_read_guard: RwLockReadGuard<'a, ()>, | ||
} | ||
|
||
impl<'a> PersistenceNotifierGuard<'a> { | ||
fn new(lock: &'a RwLock<()>, notifier: &'a PersistenceNotifier) -> Self { | ||
impl<'a> PersistenceNotifierGuard<'a, fn() -> NotifyOption> { // We don't care what the concrete F is here, its unused |
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.
nit: it's
Also a bit confused by this comment because it is used here, isn't it?
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.
No, the concrete type here is a function pointer (ie fn() -> NotifyOption
), but we don't actually ever use a PersistenceNotifierGuard
with a function pointer, only closures.
Currently, when a user calls `ChannelManager::timer_tick_occurred` we always set the persister's update flag to true. This results in a ChannelManager persistence after each timer tick, even when nothing happened. Instead, we add a new flag to `PersistenceNotifierGuard` to indicate if we should skip setting the update flag.
When we had a event which caused us to set the persist flag in a PersistenceNotifier in between wait calls, we will still wait, potentially not persisting a ChannelManager when we should. Worse, for wait_timeout, this caused us to always wait up to the timeout, but then always return true that a persistence is needed. Instead, we simply check the persist flag before waiting, returning immediately if it is set.
39bd883
to
ee36d64
Compare
Fixed two minor typos, will merge after CI:
|
Only somewhat-related commits here, but they touch the same code.