first_hop_htlc_msat: htlc_msat,
}, onion_packet), channel_state, chan)
} {
- Some((update_add, commitment_signed, chan_monitor)) => {
- if let Err(e) = self.monitor.add_update_monitor(chan_monitor.get_funding_txo().unwrap(), chan_monitor) {
+ Some((update_add, commitment_signed, monitor_update)) => {
+ if let Err(e) = self.monitor.update_monitor(chan.get().get_funding_txo().unwrap(), monitor_update) {
maybe_break_monitor_err!(self, e, channel_state, chan, RAACommitmentOrder::CommitmentFirst, false, true);
// Note that MonitorUpdateFailed here indicates (per function docs)
// that we will resent the commitment update once we unfree monitor
}
if !add_htlc_msgs.is_empty() || !fail_htlc_msgs.is_empty() {
- let (commitment_msg, monitor) = match chan.get_mut().send_commitment() {
+ let (commitment_msg, monitor_update) = match chan.get_mut().send_commitment() {
Ok(res) => res,
Err(e) => {
// We surely failed send_commitment due to bad keys, in that case
}
}
};
- if let Err(e) = self.monitor.add_update_monitor(monitor.get_funding_txo().unwrap(), monitor) {
+ if let Err(e) = self.monitor.update_monitor(chan.get().get_funding_txo().unwrap(), monitor_update) {
handle_errors.push((chan.get().get_their_node_id(), handle_monitor_err!(self, e, channel_state, chan, RAACommitmentOrder::CommitmentFirst, false, true)));
continue;
}
let was_frozen_for_monitor = chan.get().is_awaiting_monitor_update();
match chan.get_mut().get_update_fulfill_htlc_and_commit(htlc_id, payment_preimage) {
Ok((msgs, monitor_option)) => {
- if let Some(chan_monitor) = monitor_option {
- if let Err(e) = self.monitor.add_update_monitor(chan_monitor.get_funding_txo().unwrap(), chan_monitor) {
+ if let Some(monitor_update) = monitor_option {
+ if let Err(e) = self.monitor.update_monitor(chan.get().get_funding_txo().unwrap(), monitor_update) {
if was_frozen_for_monitor {
assert!(msgs.is_none());
} else {
PublicKey::from_secret_key(&self.secp_ctx, &self.our_network_key)
}
+ /// Restores a single, given channel to normal operation after a
+ /// ChannelMonitorUpdateErr::TemporaryFailure was returned from a channel monitor update
+ /// operation.
+ ///
+ /// All ChannelMonitor updates up to and including highest_applied_update_id must have been
+ /// fully committed in every copy of the given channels' ChannelMonitors.
+ ///
+ /// Note that there is no effect to calling with a highest_applied_update_id other than the
+ /// current latest ChannelMonitorUpdate and one call to this function after multiple
+ /// ChannelMonitorUpdateErr::TemporaryFailures is fine. The highest_applied_update_id field
+ /// exists largely only to prevent races between this and concurrent update_monitor calls.
+ ///
+ /// Thus, the anticipated use is, at a high level:
+ /// 1) You register a ManyChannelMonitor with this ChannelManager,
+ /// 2) it stores each update to disk, and begins updating any remote (eg watchtower) copies of
+ /// said ChannelMonitors as it can, returning ChannelMonitorUpdateErr::TemporaryFailures
+ /// any time it cannot do so instantly,
+ /// 3) update(s) are applied to each remote copy of a ChannelMonitor,
+ /// 4) once all remote copies are updated, you call this function with the update_id that
+ /// completed, and once it is the latest the Channel will be re-enabled.
+ pub fn channel_monitor_updated(&self, funding_txo: &OutPoint, highest_applied_update_id: u64) {
+ let _ = self.total_consistency_lock.read().unwrap();
+
+ let mut close_results = Vec::new();
+ let mut htlc_forwards = Vec::new();
+ let mut htlc_failures = Vec::new();
+ let mut pending_events = Vec::new();
+
+ {
+ let mut channel_lock = self.channel_state.lock().unwrap();
+ let channel_state = &mut *channel_lock;
+ let short_to_id = &mut channel_state.short_to_id;
+ let pending_msg_events = &mut channel_state.pending_msg_events;
+ let channel = match channel_state.by_id.get_mut(&funding_txo.to_channel_id()) {
+ Some(chan) => chan,
+ None => return,
+ };
+ if !channel.is_awaiting_monitor_update() || channel.get_latest_monitor_update_id() != highest_applied_update_id {
+ return;
+ }
+
+ let (raa, commitment_update, order, pending_forwards, mut pending_failures, needs_broadcast_safe, funding_locked) = channel.monitor_updating_restored();
+ if !pending_forwards.is_empty() {
+ htlc_forwards.push((channel.get_short_channel_id().expect("We can't have pending forwards before funding confirmation"), pending_forwards));
+ }
+ htlc_failures.append(&mut pending_failures);
+
+ macro_rules! handle_cs { () => {
+ if let Some(update) = commitment_update {
+ pending_msg_events.push(events::MessageSendEvent::UpdateHTLCs {
+ node_id: channel.get_their_node_id(),
+ updates: update,
+ });
+ }
+ } }
+ macro_rules! handle_raa { () => {
+ if let Some(revoke_and_ack) = raa {
+ pending_msg_events.push(events::MessageSendEvent::SendRevokeAndACK {
+ node_id: channel.get_their_node_id(),
+ msg: revoke_and_ack,
+ });
+ }
+ } }
+ match order {
+ RAACommitmentOrder::CommitmentFirst => {
+ handle_cs!();
+ handle_raa!();
+ },
+ RAACommitmentOrder::RevokeAndACKFirst => {
+ handle_raa!();
+ handle_cs!();
+ },
+ }
+ if needs_broadcast_safe {
+ pending_events.push(events::Event::FundingBroadcastSafe {
+ funding_txo: channel.get_funding_txo().unwrap(),
+ user_channel_id: channel.get_user_id(),
+ });
+ }
+ if let Some(msg) = funding_locked {
+ pending_msg_events.push(events::MessageSendEvent::SendFundingLocked {
+ node_id: channel.get_their_node_id(),
+ msg,
+ });
+ if let Some(announcement_sigs) = self.get_announcement_sigs(channel) {
+ pending_msg_events.push(events::MessageSendEvent::SendAnnouncementSignatures {
+ node_id: channel.get_their_node_id(),
+ msg: announcement_sigs,
+ });
+ }
+ short_to_id.insert(channel.get_short_channel_id().unwrap(), channel.channel_id());
+ }
+ }
+
+ self.pending_events.lock().unwrap().append(&mut pending_events);
+
+ for failure in htlc_failures.drain(..) {
+ self.fail_htlc_backwards_internal(self.channel_state.lock().unwrap(), failure.0, &failure.1, failure.2);
+ }
+ self.forward_htlcs(&mut htlc_forwards[..]);
+
+ for res in close_results.drain(..) {
+ self.finish_force_close_channel(res);
+ }
+ }
+
/// Used to restore channels to normal operation after a
/// ChannelMonitorUpdateErr::TemporaryFailure was returned from a channel monitor update
/// operation.
if chan.get().get_their_node_id() != *their_node_id {
return Err(MsgHandleErrInternal::send_err_msg_no_close("Got a message for a channel from the wrong node!", msg.channel_id));
}
- let chan_monitor = try_chan_entry!(self, chan.get_mut().funding_signed(&msg), channel_state, chan);
- if let Err(e) = self.monitor.add_update_monitor(chan_monitor.get_funding_txo().unwrap(), chan_monitor) {
+ let monitor_update = match chan.get_mut().funding_signed(&msg) {
+ Err((None, e)) => try_chan_entry!(self, Err(e), channel_state, chan),
+ Err((Some(monitor_update), e)) => {
+ assert!(chan.get().is_awaiting_monitor_update());
+ let _ = self.monitor.update_monitor(chan.get().get_funding_txo().unwrap(), monitor_update);
+ try_chan_entry!(self, Err(e), channel_state, chan);
+ unreachable!();
+ },
+ Ok(update) => update,
+ };
+ if let Err(e) = self.monitor.update_monitor(chan.get().get_funding_txo().unwrap(), monitor_update) {
return_monitor_err!(self, e, channel_state, chan, RAACommitmentOrder::RevokeAndACKFirst, false, false);
}
(chan.get().get_funding_txo().unwrap(), chan.get().get_user_id())
if chan.get().get_their_node_id() != *their_node_id {
return Err(MsgHandleErrInternal::send_err_msg_no_close("Got a message for a channel from the wrong node!", msg.channel_id));
}
- let (revoke_and_ack, commitment_signed, closing_signed, chan_monitor) =
- try_chan_entry!(self, chan.get_mut().commitment_signed(&msg, &*self.fee_estimator), channel_state, chan);
- if let Err(e) = self.monitor.add_update_monitor(chan_monitor.get_funding_txo().unwrap(), chan_monitor) {
+ let (revoke_and_ack, commitment_signed, closing_signed, monitor_update) =
+ match chan.get_mut().commitment_signed(&msg, &*self.fee_estimator) {
+ Err((None, e)) => try_chan_entry!(self, Err(e), channel_state, chan),
+ Err((Some(update), e)) => {
+ assert!(chan.get().is_awaiting_monitor_update());
+ let _ = self.monitor.update_monitor(chan.get().get_funding_txo().unwrap(), update);
+ try_chan_entry!(self, Err(e), channel_state, chan);
+ unreachable!();
+ },
+ Ok(res) => res
+ };
+ if let Err(e) = self.monitor.update_monitor(chan.get().get_funding_txo().unwrap(), monitor_update) {
return_monitor_err!(self, e, channel_state, chan, RAACommitmentOrder::RevokeAndACKFirst, true, commitment_signed.is_some());
//TODO: Rebroadcast closing_signed if present on monitor update restoration
}
return Err(MsgHandleErrInternal::send_err_msg_no_close("Got a message for a channel from the wrong node!", msg.channel_id));
}
let was_frozen_for_monitor = chan.get().is_awaiting_monitor_update();
- let (commitment_update, pending_forwards, pending_failures, closing_signed, chan_monitor) =
+ let (commitment_update, pending_forwards, pending_failures, closing_signed, monitor_update) =
try_chan_entry!(self, chan.get_mut().revoke_and_ack(&msg, &*self.fee_estimator), channel_state, chan);
- if let Err(e) = self.monitor.add_update_monitor(chan_monitor.get_funding_txo().unwrap(), chan_monitor) {
+ if let Err(e) = self.monitor.update_monitor(chan.get().get_funding_txo().unwrap(), monitor_update) {
if was_frozen_for_monitor {
assert!(commitment_update.is_none() && closing_signed.is_none() && pending_forwards.is_empty() && pending_failures.is_empty());
return Err(MsgHandleErrInternal::ignore_no_close("Previous monitor update failure prevented responses to RAA"));
if chan.get().get_their_node_id() != *their_node_id {
return Err(MsgHandleErrInternal::send_err_msg_no_close("Got a message for a channel from the wrong node!", msg.channel_id));
}
- let (funding_locked, revoke_and_ack, commitment_update, channel_monitor, mut order, shutdown) =
+ let (funding_locked, revoke_and_ack, commitment_update, monitor_update_opt, mut order, shutdown) =
try_chan_entry!(self, chan.get_mut().channel_reestablish(msg), channel_state, chan);
- if let Some(monitor) = channel_monitor {
- if let Err(e) = self.monitor.add_update_monitor(monitor.get_funding_txo().unwrap(), monitor) {
+ if let Some(monitor_update) = monitor_update_opt {
+ if let Err(e) = self.monitor.update_monitor(chan.get().get_funding_txo().unwrap(), monitor_update) {
// channel_reestablish doesn't guarantee the order it returns is sensical
// for the messages it returns, but if we're setting what messages to
// re-transmit on monitor update success, we need to make sure it is sane.
return Err(APIError::ChannelUnavailable{err: "Channel is either not yet fully established or peer is currently disconnected"});
}
their_node_id = chan.get().get_their_node_id();
- if let Some((update_fee, commitment_signed, chan_monitor)) =
+ if let Some((update_fee, commitment_signed, monitor_update)) =
break_chan_entry!(self, chan.get_mut().send_update_fee_and_commit(feerate_per_kw), channel_state, chan)
{
- if let Err(_e) = self.monitor.add_update_monitor(chan_monitor.get_funding_txo().unwrap(), chan_monitor) {
+ if let Err(_e) = self.monitor.update_monitor(chan.get().get_funding_txo().unwrap(), monitor_update) {
unimplemented!();
}
channel_state.pending_msg_events.push(events::MessageSendEvent::UpdateHTLCs {
if let Some(ref mut monitor) = args.channel_monitors.get_mut(&funding_txo) {
if channel.get_cur_local_commitment_transaction_number() != monitor.get_cur_local_commitment_number() ||
channel.get_revoked_remote_commitment_transaction_number() != monitor.get_min_seen_secret() ||
- channel.get_cur_remote_commitment_transaction_number() != monitor.get_cur_remote_commitment_number() {
+ channel.get_cur_remote_commitment_transaction_number() != monitor.get_cur_remote_commitment_number() ||
+ channel.get_latest_monitor_update_id() != monitor.get_latest_update_id() {
let mut force_close_res = channel.force_shutdown();
force_close_res.0 = monitor.get_latest_local_commitment_txn();
closed_channels.push(force_close_res);