Uh oh!
There was an error while loading. Please reload this page.
Avoid persisting a ChannelManager after each timer tick and send update_channel re-enable messages - #916
Conversation
1dabdc0 to
cad69f4CompareCodecov 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
9b69e1eCompare
valentinewallace
left a comment
There was a problem hiding this comment.
Cool! I like how it sets a foundation for removing other unnecessary persists in the future too
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
9b69e1e to
ba7a0c0CompareUh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
| 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.
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.
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.
Uh oh!
There was an error while loading. Please reload this page.
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
4edd86dCompareTheBlueMatt
commented
May 14, 2021
Pushed two different approaches to cleaning up the notifierguard, see the two fixup commits. |
jkczyz
commented
May 14, 2021
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
0a448b3CompareTheBlueMatt
commented
May 14, 2021
Ah! Indeed we could. |
0a448b3 to
0f24e79CompareUh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
| 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.
Would Self for the return type work for these?
There was a problem hiding this comment.
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
533eef8Compare533eef8 to
39bd883CompareTheBlueMatt
commented
May 14, 2021
Uh oh!
There was an error while loading. Please reload this page.
| 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.
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.
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
ee36d64CompareTheBlueMatt
commented
May 14, 2021
Fixed two minor typos, will merge after CI: |
Only somewhat-related commits here, but they touch the same code.