mirror of
https://github.com/lightningdevkit/rust-lightning.git
synced 2025-01-19 05:43:55 +01:00
Move a handful of channel messages to notify-without-persist
Many channel related messages don't actually change the channel state in a way that changes the persisted channel. For example, an `update_add_htlc` or `update_fail_htlc` message simply adds the change to a queue, changing the channel state when we receive a `commitment_signed` message. In these cases there's really no reason to wake the background processor at all - there's no response message and there's no state update. However, note that if we close the channel we should persist the `ChannelManager`. If we send an error message without closing the channel, we should wake the background processor without persisting. Here we move to the appropriate `NotifyOption` on some of the simpler channel message handlers.
This commit is contained in:
parent
305df1d7da
commit
71bafecafc
@ -494,6 +494,10 @@ impl MsgHandleErrInternal {
|
||||
channel_capacity: None,
|
||||
}
|
||||
}
|
||||
|
||||
fn closes_channel(&self) -> bool {
|
||||
self.chan_id.is_some()
|
||||
}
|
||||
}
|
||||
|
||||
/// We hold back HTLCs we intend to relay for a random interval greater than this (see
|
||||
@ -1238,6 +1242,12 @@ struct PersistenceNotifierGuard<'a, F: Fn() -> NotifyOption> {
|
||||
}
|
||||
|
||||
impl<'a> PersistenceNotifierGuard<'a, fn() -> NotifyOption> { // We don't care what the concrete F is here, it's unused
|
||||
/// Notifies any waiters and indicates that we need to persist, in addition to possibly having
|
||||
/// events to handle.
|
||||
///
|
||||
/// This must always be called if the changes included a `ChannelMonitorUpdate`, as well as in
|
||||
/// other cases where losing the changes on restart may result in a force-close or otherwise
|
||||
/// isn't ideal.
|
||||
fn notify_on_drop<C: AChannelManager>(cm: &'a C) -> PersistenceNotifierGuard<'a, impl Fn() -> NotifyOption> {
|
||||
Self::optionally_notify(cm, || -> NotifyOption { NotifyOption::DoPersist })
|
||||
}
|
||||
@ -2152,9 +2162,14 @@ macro_rules! process_events_body {
|
||||
processed_all_events = false;
|
||||
}
|
||||
|
||||
if result == NotifyOption::DoPersist {
|
||||
$self.needs_persist_flag.store(true, Ordering::Release);
|
||||
$self.event_persist_notifier.notify();
|
||||
match result {
|
||||
NotifyOption::DoPersist => {
|
||||
$self.needs_persist_flag.store(true, Ordering::Release);
|
||||
$self.event_persist_notifier.notify();
|
||||
},
|
||||
NotifyOption::SkipPersistHandleEvents =>
|
||||
$self.event_persist_notifier.notify(),
|
||||
NotifyOption::SkipPersistNoEvents => {},
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -5560,6 +5575,8 @@ where
|
||||
}
|
||||
|
||||
fn internal_open_channel(&self, counterparty_node_id: &PublicKey, msg: &msgs::OpenChannel) -> Result<(), MsgHandleErrInternal> {
|
||||
// Note that the ChannelManager is NOT re-persisted on disk after this, so any changes are
|
||||
// likely to be lost on restart!
|
||||
if msg.chain_hash != self.genesis_hash {
|
||||
return Err(MsgHandleErrInternal::send_err_msg_no_close("Unknown genesis block hash".to_owned(), msg.temporary_channel_id.clone()));
|
||||
}
|
||||
@ -5659,6 +5676,8 @@ where
|
||||
}
|
||||
|
||||
fn internal_accept_channel(&self, counterparty_node_id: &PublicKey, msg: &msgs::AcceptChannel) -> Result<(), MsgHandleErrInternal> {
|
||||
// Note that the ChannelManager is NOT re-persisted on disk after this, so any changes are
|
||||
// likely to be lost on restart!
|
||||
let (value, output_script, user_id) = {
|
||||
let per_peer_state = self.per_peer_state.read().unwrap();
|
||||
let peer_state_mutex = per_peer_state.get(counterparty_node_id)
|
||||
@ -5819,6 +5838,8 @@ where
|
||||
}
|
||||
|
||||
fn internal_channel_ready(&self, counterparty_node_id: &PublicKey, msg: &msgs::ChannelReady) -> Result<(), MsgHandleErrInternal> {
|
||||
// Note that the ChannelManager is NOT re-persisted on disk after this (unless we error
|
||||
// closing a channel), so any changes are likely to be lost on restart!
|
||||
let per_peer_state = self.per_peer_state.read().unwrap();
|
||||
let peer_state_mutex = per_peer_state.get(counterparty_node_id)
|
||||
.ok_or_else(|| {
|
||||
@ -5997,6 +6018,9 @@ where
|
||||
//encrypted with the same key. It's not immediately obvious how to usefully exploit that,
|
||||
//but we should prevent it anyway.
|
||||
|
||||
// Note that the ChannelManager is NOT re-persisted on disk after this (unless we error
|
||||
// closing a channel), so any changes are likely to be lost on restart!
|
||||
|
||||
let decoded_hop_res = self.decode_update_add_htlc_onion(msg);
|
||||
let per_peer_state = self.per_peer_state.read().unwrap();
|
||||
let peer_state_mutex = per_peer_state.get(counterparty_node_id)
|
||||
@ -6078,6 +6102,8 @@ where
|
||||
}
|
||||
|
||||
fn internal_update_fail_htlc(&self, counterparty_node_id: &PublicKey, msg: &msgs::UpdateFailHTLC) -> Result<(), MsgHandleErrInternal> {
|
||||
// Note that the ChannelManager is NOT re-persisted on disk after this (unless we error
|
||||
// closing a channel), so any changes are likely to be lost on restart!
|
||||
let per_peer_state = self.per_peer_state.read().unwrap();
|
||||
let peer_state_mutex = per_peer_state.get(counterparty_node_id)
|
||||
.ok_or_else(|| {
|
||||
@ -6101,6 +6127,8 @@ where
|
||||
}
|
||||
|
||||
fn internal_update_fail_malformed_htlc(&self, counterparty_node_id: &PublicKey, msg: &msgs::UpdateFailMalformedHTLC) -> Result<(), MsgHandleErrInternal> {
|
||||
// Note that the ChannelManager is NOT re-persisted on disk after this (unless we error
|
||||
// closing a channel), so any changes are likely to be lost on restart!
|
||||
let per_peer_state = self.per_peer_state.read().unwrap();
|
||||
let peer_state_mutex = per_peer_state.get(counterparty_node_id)
|
||||
.ok_or_else(|| {
|
||||
@ -7476,8 +7504,21 @@ where
|
||||
L::Target: Logger,
|
||||
{
|
||||
fn handle_open_channel(&self, counterparty_node_id: &PublicKey, msg: &msgs::OpenChannel) {
|
||||
let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(self);
|
||||
let _ = handle_error!(self, self.internal_open_channel(counterparty_node_id, msg), *counterparty_node_id);
|
||||
// Note that we never need to persist the updated ChannelManager for an inbound
|
||||
// open_channel message - pre-funded channels are never written so there should be no
|
||||
// change to the contents.
|
||||
let _persistence_guard = PersistenceNotifierGuard::optionally_notify(self, || {
|
||||
let res = self.internal_open_channel(counterparty_node_id, msg);
|
||||
let persist = match &res {
|
||||
Err(e) if e.closes_channel() => {
|
||||
debug_assert!(false, "We shouldn't close a new channel");
|
||||
NotifyOption::DoPersist
|
||||
},
|
||||
_ => NotifyOption::SkipPersistHandleEvents,
|
||||
};
|
||||
let _ = handle_error!(self, res, *counterparty_node_id);
|
||||
persist
|
||||
});
|
||||
}
|
||||
|
||||
fn handle_open_channel_v2(&self, counterparty_node_id: &PublicKey, msg: &msgs::OpenChannelV2) {
|
||||
@ -7487,8 +7528,13 @@ where
|
||||
}
|
||||
|
||||
fn handle_accept_channel(&self, counterparty_node_id: &PublicKey, msg: &msgs::AcceptChannel) {
|
||||
let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(self);
|
||||
let _ = handle_error!(self, self.internal_accept_channel(counterparty_node_id, msg), *counterparty_node_id);
|
||||
// Note that we never need to persist the updated ChannelManager for an inbound
|
||||
// accept_channel message - pre-funded channels are never written so there should be no
|
||||
// change to the contents.
|
||||
let _persistence_guard = PersistenceNotifierGuard::optionally_notify(self, || {
|
||||
let _ = handle_error!(self, self.internal_accept_channel(counterparty_node_id, msg), *counterparty_node_id);
|
||||
NotifyOption::SkipPersistHandleEvents
|
||||
});
|
||||
}
|
||||
|
||||
fn handle_accept_channel_v2(&self, counterparty_node_id: &PublicKey, msg: &msgs::AcceptChannelV2) {
|
||||
@ -7508,8 +7554,19 @@ where
|
||||
}
|
||||
|
||||
fn handle_channel_ready(&self, counterparty_node_id: &PublicKey, msg: &msgs::ChannelReady) {
|
||||
let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(self);
|
||||
let _ = handle_error!(self, self.internal_channel_ready(counterparty_node_id, msg), *counterparty_node_id);
|
||||
// Note that we never need to persist the updated ChannelManager for an inbound
|
||||
// channel_ready message - while the channel's state will change, any channel_ready message
|
||||
// will ultimately be re-sent on startup and the `ChannelMonitor` won't be updated so we
|
||||
// will not force-close the channel on startup.
|
||||
let _persistence_guard = PersistenceNotifierGuard::optionally_notify(self, || {
|
||||
let res = self.internal_channel_ready(counterparty_node_id, msg);
|
||||
let persist = match &res {
|
||||
Err(e) if e.closes_channel() => NotifyOption::DoPersist,
|
||||
_ => NotifyOption::SkipPersistHandleEvents,
|
||||
};
|
||||
let _ = handle_error!(self, res, *counterparty_node_id);
|
||||
persist
|
||||
});
|
||||
}
|
||||
|
||||
fn handle_shutdown(&self, counterparty_node_id: &PublicKey, msg: &msgs::Shutdown) {
|
||||
@ -7523,8 +7580,19 @@ where
|
||||
}
|
||||
|
||||
fn handle_update_add_htlc(&self, counterparty_node_id: &PublicKey, msg: &msgs::UpdateAddHTLC) {
|
||||
let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(self);
|
||||
let _ = handle_error!(self, self.internal_update_add_htlc(counterparty_node_id, msg), *counterparty_node_id);
|
||||
// Note that we never need to persist the updated ChannelManager for an inbound
|
||||
// update_add_htlc message - the message itself doesn't change our channel state only the
|
||||
// `commitment_signed` message afterwards will.
|
||||
let _persistence_guard = PersistenceNotifierGuard::optionally_notify(self, || {
|
||||
let res = self.internal_update_add_htlc(counterparty_node_id, msg);
|
||||
let persist = match &res {
|
||||
Err(e) if e.closes_channel() => NotifyOption::DoPersist,
|
||||
Err(_) => NotifyOption::SkipPersistHandleEvents,
|
||||
Ok(()) => NotifyOption::SkipPersistNoEvents,
|
||||
};
|
||||
let _ = handle_error!(self, res, *counterparty_node_id);
|
||||
persist
|
||||
});
|
||||
}
|
||||
|
||||
fn handle_update_fulfill_htlc(&self, counterparty_node_id: &PublicKey, msg: &msgs::UpdateFulfillHTLC) {
|
||||
@ -7533,13 +7601,35 @@ where
|
||||
}
|
||||
|
||||
fn handle_update_fail_htlc(&self, counterparty_node_id: &PublicKey, msg: &msgs::UpdateFailHTLC) {
|
||||
let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(self);
|
||||
let _ = handle_error!(self, self.internal_update_fail_htlc(counterparty_node_id, msg), *counterparty_node_id);
|
||||
// Note that we never need to persist the updated ChannelManager for an inbound
|
||||
// update_fail_htlc message - the message itself doesn't change our channel state only the
|
||||
// `commitment_signed` message afterwards will.
|
||||
let _persistence_guard = PersistenceNotifierGuard::optionally_notify(self, || {
|
||||
let res = self.internal_update_fail_htlc(counterparty_node_id, msg);
|
||||
let persist = match &res {
|
||||
Err(e) if e.closes_channel() => NotifyOption::DoPersist,
|
||||
Err(_) => NotifyOption::SkipPersistHandleEvents,
|
||||
Ok(()) => NotifyOption::SkipPersistNoEvents,
|
||||
};
|
||||
let _ = handle_error!(self, res, *counterparty_node_id);
|
||||
persist
|
||||
});
|
||||
}
|
||||
|
||||
fn handle_update_fail_malformed_htlc(&self, counterparty_node_id: &PublicKey, msg: &msgs::UpdateFailMalformedHTLC) {
|
||||
let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(self);
|
||||
let _ = handle_error!(self, self.internal_update_fail_malformed_htlc(counterparty_node_id, msg), *counterparty_node_id);
|
||||
// Note that we never need to persist the updated ChannelManager for an inbound
|
||||
// update_fail_malformed_htlc message - the message itself doesn't change our channel state
|
||||
// only the `commitment_signed` message afterwards will.
|
||||
let _persistence_guard = PersistenceNotifierGuard::optionally_notify(self, || {
|
||||
let res = self.internal_update_fail_malformed_htlc(counterparty_node_id, msg);
|
||||
let persist = match &res {
|
||||
Err(e) if e.closes_channel() => NotifyOption::DoPersist,
|
||||
Err(_) => NotifyOption::SkipPersistHandleEvents,
|
||||
Ok(()) => NotifyOption::SkipPersistNoEvents,
|
||||
};
|
||||
let _ = handle_error!(self, res, *counterparty_node_id);
|
||||
persist
|
||||
});
|
||||
}
|
||||
|
||||
fn handle_commitment_signed(&self, counterparty_node_id: &PublicKey, msg: &msgs::CommitmentSigned) {
|
||||
@ -7553,8 +7643,19 @@ where
|
||||
}
|
||||
|
||||
fn handle_update_fee(&self, counterparty_node_id: &PublicKey, msg: &msgs::UpdateFee) {
|
||||
let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(self);
|
||||
let _ = handle_error!(self, self.internal_update_fee(counterparty_node_id, msg), *counterparty_node_id);
|
||||
// Note that we never need to persist the updated ChannelManager for an inbound
|
||||
// update_fee message - the message itself doesn't change our channel state only the
|
||||
// `commitment_signed` message afterwards will.
|
||||
let _persistence_guard = PersistenceNotifierGuard::optionally_notify(self, || {
|
||||
let res = self.internal_update_fee(counterparty_node_id, msg);
|
||||
let persist = match &res {
|
||||
Err(e) if e.closes_channel() => NotifyOption::DoPersist,
|
||||
Err(_) => NotifyOption::SkipPersistHandleEvents,
|
||||
Ok(()) => NotifyOption::SkipPersistNoEvents,
|
||||
};
|
||||
let _ = handle_error!(self, res, *counterparty_node_id);
|
||||
persist
|
||||
});
|
||||
}
|
||||
|
||||
fn handle_announcement_signatures(&self, counterparty_node_id: &PublicKey, msg: &msgs::AnnouncementSignatures) {
|
||||
|
Loading…
Reference in New Issue
Block a user