From f930fc1886dbfdc388be79579ef02e788e2478f5 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Sat, 8 Feb 2020 17:22:58 -0500 Subject: [PATCH] Use ChannelMonitorUpdate in fallen-behind handling during reestablish This is a rather huge diff, almost entirely due to removing the type parameter from ChannelError which was added in c20e930b31e973e0fb290322c9ac425002e3b672 due to holding the ChannelKeys in ChannelMonitors. --- lightning/src/ln/channel.rs | 86 +++++++++++++++++------------- lightning/src/ln/channelmanager.rs | 30 +++++------ lightning/src/ln/channelmonitor.rs | 22 +++++++- 3 files changed, 82 insertions(+), 56 deletions(-) diff --git a/lightning/src/ln/channel.rs b/lightning/src/ln/channel.rs index 9866dcf5e..3cc845362 100644 --- a/lightning/src/ln/channel.rs +++ b/lightning/src/ln/channel.rs @@ -383,16 +383,16 @@ pub const MAX_FUNDING_SATOSHIS: u64 = (1 << 24); /// Used to return a simple Error back to ChannelManager. Will get converted to a /// msgs::ErrorAction::SendErrorMessage or msgs::ErrorAction::IgnoreError as appropriate with our /// channel_id in ChannelManager. -pub(super) enum ChannelError { +pub(super) enum ChannelError { Ignore(&'static str), Close(&'static str), CloseDelayBroadcast { msg: &'static str, - update: Option>, + update: ChannelMonitorUpdate, }, } -impl fmt::Debug for ChannelError { +impl fmt::Debug for ChannelError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { &ChannelError::Ignore(e) => write!(f, "Ignore : {}", e), @@ -539,7 +539,7 @@ impl Channel { }) } - fn check_remote_fee(fee_estimator: &FeeEstimator, feerate_per_kw: u32) -> Result<(), ChannelError> { + fn check_remote_fee(fee_estimator: &FeeEstimator, feerate_per_kw: u32) -> Result<(), ChannelError> { if (feerate_per_kw as u64) < fee_estimator.get_est_sat_per_1000_weight(ConfirmationTarget::Background) { return Err(ChannelError::Close("Peer's feerate much too low")); } @@ -551,7 +551,7 @@ impl Channel { /// Creates a new channel from a remote sides' request for one. /// Assumes chain_hash has already been checked and corresponds with what we expect! - pub fn new_from_req(fee_estimator: &FeeEstimator, keys_provider: &Arc>, their_node_id: PublicKey, their_features: InitFeatures, msg: &msgs::OpenChannel, user_id: u64, logger: Arc, config: &UserConfig) -> Result, ChannelError> { + pub fn new_from_req(fee_estimator: &FeeEstimator, keys_provider: &Arc>, their_node_id: PublicKey, their_features: InitFeatures, msg: &msgs::OpenChannel, user_id: u64, logger: Arc, config: &UserConfig) -> Result, ChannelError> { let mut chan_keys = keys_provider.get_channel_keys(true, msg.funding_satoshis); let their_pubkeys = ChannelPublicKeys { funding_pubkey: msg.funding_pubkey, @@ -1098,7 +1098,7 @@ impl Channel { /// our counterparty!) /// The result is a transaction which we can revoke ownership of (ie a "local" transaction) /// TODO Some magic rust shit to compile-time check this? - fn build_local_transaction_keys(&self, commitment_number: u64) -> Result> { + fn build_local_transaction_keys(&self, commitment_number: u64) -> Result { let per_commitment_point = PublicKey::from_secret_key(&self.secp_ctx, &self.build_local_commitment_secret(commitment_number)); let delayed_payment_base = PublicKey::from_secret_key(&self.secp_ctx, self.local_keys.delayed_payment_base_key()); let htlc_basepoint = PublicKey::from_secret_key(&self.secp_ctx, self.local_keys.htlc_base_key()); @@ -1111,7 +1111,7 @@ impl Channel { /// Creates a set of keys for build_commitment_transaction to generate a transaction which we /// will sign and send to our counterparty. /// If an Err is returned, it is a ChannelError::Close (for get_outbound_funding_created) - fn build_remote_transaction_keys(&self) -> Result> { + fn build_remote_transaction_keys(&self) -> Result { //TODO: Ensure that the payment_key derived here ends up in the library users' wallet as we //may see payments to it! let payment_basepoint = PublicKey::from_secret_key(&self.secp_ctx, self.local_keys.payment_base_key()); @@ -1140,7 +1140,7 @@ impl Channel { /// Per HTLC, only one get_update_fail_htlc or get_update_fulfill_htlc call may be made. /// In such cases we debug_assert!(false) and return an IgnoreError. Thus, will always return /// Ok(_) if debug assertions are turned on and preconditions are met. - fn get_update_fulfill_htlc(&mut self, htlc_id_arg: u64, payment_preimage_arg: PaymentPreimage) -> Result<(Option, Option), ChannelError> { + fn get_update_fulfill_htlc(&mut self, htlc_id_arg: u64, payment_preimage_arg: PaymentPreimage) -> Result<(Option, Option), ChannelError> { // Either ChannelFunded got set (which means it won't be unset) or there is no way any // caller thought we could have something claimed (cause we wouldn't have accepted in an // incoming HTLC anyway). If we got to ShutdownComplete, callers aren't allowed to call us, @@ -1239,7 +1239,7 @@ impl Channel { }), Some(monitor_update))) } - pub fn get_update_fulfill_htlc_and_commit(&mut self, htlc_id: u64, payment_preimage: PaymentPreimage) -> Result<(Option<(msgs::UpdateFulfillHTLC, msgs::CommitmentSigned)>, Option), ChannelError> { + pub fn get_update_fulfill_htlc_and_commit(&mut self, htlc_id: u64, payment_preimage: PaymentPreimage) -> Result<(Option<(msgs::UpdateFulfillHTLC, msgs::CommitmentSigned)>, Option), ChannelError> { match self.get_update_fulfill_htlc(htlc_id, payment_preimage)? { (Some(update_fulfill_htlc), Some(mut monitor_update)) => { let (commitment, mut additional_update) = self.send_commitment_no_status_check()?; @@ -1261,7 +1261,7 @@ impl Channel { /// Per HTLC, only one get_update_fail_htlc or get_update_fulfill_htlc call may be made. /// In such cases we debug_assert!(false) and return an IgnoreError. Thus, will always return /// Ok(_) if debug assertions are turned on and preconditions are met. - pub fn get_update_fail_htlc(&mut self, htlc_id_arg: u64, err_packet: msgs::OnionErrorPacket) -> Result, ChannelError> { + pub fn get_update_fail_htlc(&mut self, htlc_id_arg: u64, err_packet: msgs::OnionErrorPacket) -> Result, ChannelError> { if (self.channel_state & (ChannelState::ChannelFunded as u32)) != (ChannelState::ChannelFunded as u32) { panic!("Was asked to fail an HTLC when channel was not in an operational state"); } @@ -1329,7 +1329,7 @@ impl Channel { // Message handlers: - pub fn accept_channel(&mut self, msg: &msgs::AcceptChannel, config: &UserConfig, their_features: InitFeatures) -> Result<(), ChannelError> { + pub fn accept_channel(&mut self, msg: &msgs::AcceptChannel, config: &UserConfig, their_features: InitFeatures) -> Result<(), ChannelError> { // Check sanity of message fields: if !self.channel_outbound { return Err(ChannelError::Close("Got an accept_channel message from an inbound peer")); @@ -1436,7 +1436,7 @@ impl Channel { Ok(()) } - fn funding_created_signature(&mut self, sig: &Signature) -> Result<(Transaction, LocalCommitmentTransaction, Signature, TxCreationKeys), ChannelError> { + fn funding_created_signature(&mut self, sig: &Signature) -> Result<(Transaction, LocalCommitmentTransaction, Signature, TxCreationKeys), ChannelError> { let funding_script = self.get_funding_redeemscript(); let local_keys = self.build_local_transaction_keys(self.cur_local_commitment_transaction_number)?; @@ -1461,7 +1461,7 @@ impl Channel { &self.their_pubkeys.as_ref().expect("their_funding_pubkey() only allowed after accept_channel").funding_pubkey } - pub fn funding_created(&mut self, msg: &msgs::FundingCreated) -> Result<(msgs::FundingSigned, ChannelMonitor), ChannelError> { + pub fn funding_created(&mut self, msg: &msgs::FundingCreated) -> Result<(msgs::FundingSigned, ChannelMonitor), ChannelError> { if self.channel_outbound { return Err(ChannelError::Close("Received funding_created for an outbound channel?")); } @@ -1512,7 +1512,7 @@ impl Channel { /// Handles a funding_signed message from the remote end. /// If this call is successful, broadcast the funding transaction (and not before!) - pub fn funding_signed(&mut self, msg: &msgs::FundingSigned) -> Result, ChannelError)> { + pub fn funding_signed(&mut self, msg: &msgs::FundingSigned) -> Result, ChannelError)> { if !self.channel_outbound { return Err((None, ChannelError::Close("Received funding_signed for an inbound channel?"))); } @@ -1558,7 +1558,7 @@ impl Channel { } } - pub fn funding_locked(&mut self, msg: &msgs::FundingLocked) -> Result<(), ChannelError> { + pub fn funding_locked(&mut self, msg: &msgs::FundingLocked) -> Result<(), ChannelError> { if self.channel_state & (ChannelState::PeerDisconnected as u32) == ChannelState::PeerDisconnected as u32 { return Err(ChannelError::Close("Peer sent funding_locked when we needed a channel_reestablish")); } @@ -1629,7 +1629,7 @@ impl Channel { cmp::min(self.value_to_self_msat as i64 - self.get_outbound_pending_htlc_stats().1 as i64, 0) as u64) } - pub fn update_add_htlc(&mut self, msg: &msgs::UpdateAddHTLC, pending_forward_state: PendingHTLCStatus) -> Result<(), ChannelError> { + pub fn update_add_htlc(&mut self, msg: &msgs::UpdateAddHTLC, pending_forward_state: PendingHTLCStatus) -> Result<(), ChannelError> { if (self.channel_state & (ChannelState::ChannelFunded as u32 | ChannelState::RemoteShutdownSent as u32)) != (ChannelState::ChannelFunded as u32) { return Err(ChannelError::Close("Got add HTLC message when channel was not in an operational state")); } @@ -1703,7 +1703,7 @@ impl Channel { /// Marks an outbound HTLC which we have received update_fail/fulfill/malformed #[inline] - fn mark_outbound_htlc_removed(&mut self, htlc_id: u64, check_preimage: Option, fail_reason: Option) -> Result<&HTLCSource, ChannelError> { + fn mark_outbound_htlc_removed(&mut self, htlc_id: u64, check_preimage: Option, fail_reason: Option) -> Result<&HTLCSource, ChannelError> { for htlc in self.pending_outbound_htlcs.iter_mut() { if htlc.htlc_id == htlc_id { match check_preimage { @@ -1728,7 +1728,7 @@ impl Channel { Err(ChannelError::Close("Remote tried to fulfill/fail an HTLC we couldn't find")) } - pub fn update_fulfill_htlc(&mut self, msg: &msgs::UpdateFulfillHTLC) -> Result> { + pub fn update_fulfill_htlc(&mut self, msg: &msgs::UpdateFulfillHTLC) -> Result { if (self.channel_state & (ChannelState::ChannelFunded as u32)) != (ChannelState::ChannelFunded as u32) { return Err(ChannelError::Close("Got fulfill HTLC message when channel was not in an operational state")); } @@ -1740,7 +1740,7 @@ impl Channel { self.mark_outbound_htlc_removed(msg.htlc_id, Some(payment_hash), None).map(|source| source.clone()) } - pub fn update_fail_htlc(&mut self, msg: &msgs::UpdateFailHTLC, fail_reason: HTLCFailReason) -> Result<(), ChannelError> { + pub fn update_fail_htlc(&mut self, msg: &msgs::UpdateFailHTLC, fail_reason: HTLCFailReason) -> Result<(), ChannelError> { if (self.channel_state & (ChannelState::ChannelFunded as u32)) != (ChannelState::ChannelFunded as u32) { return Err(ChannelError::Close("Got fail HTLC message when channel was not in an operational state")); } @@ -1752,7 +1752,7 @@ impl Channel { Ok(()) } - pub fn update_fail_malformed_htlc<'a>(&mut self, msg: &msgs::UpdateFailMalformedHTLC, fail_reason: HTLCFailReason) -> Result<(), ChannelError> { + pub fn update_fail_malformed_htlc<'a>(&mut self, msg: &msgs::UpdateFailMalformedHTLC, fail_reason: HTLCFailReason) -> Result<(), ChannelError> { if (self.channel_state & (ChannelState::ChannelFunded as u32)) != (ChannelState::ChannelFunded as u32) { return Err(ChannelError::Close("Got fail malformed HTLC message when channel was not in an operational state")); } @@ -1764,7 +1764,7 @@ impl Channel { Ok(()) } - pub fn commitment_signed(&mut self, msg: &msgs::CommitmentSigned, fee_estimator: &FeeEstimator) -> Result<(msgs::RevokeAndACK, Option, Option, ChannelMonitorUpdate), (Option, ChannelError)> { + pub fn commitment_signed(&mut self, msg: &msgs::CommitmentSigned, fee_estimator: &FeeEstimator) -> Result<(msgs::RevokeAndACK, Option, Option, ChannelMonitorUpdate), (Option, ChannelError)> { if (self.channel_state & (ChannelState::ChannelFunded as u32)) != (ChannelState::ChannelFunded as u32) { return Err((None, ChannelError::Close("Got commitment signed message when channel was not in an operational state"))); } @@ -1925,7 +1925,7 @@ impl Channel { /// Used to fulfill holding_cell_htlcs when we get a remote ack (or implicitly get it by them /// fulfilling or failing the last pending HTLC) - fn free_holding_cell_htlcs(&mut self) -> Result, ChannelError> { + fn free_holding_cell_htlcs(&mut self) -> Result, ChannelError> { assert_eq!(self.channel_state & ChannelState::MonitorUpdateFailed as u32, 0); if self.holding_cell_htlc_updates.len() != 0 || self.holding_cell_update_fee.is_some() { log_trace!(self, "Freeing holding cell with {} HTLC updates{}", self.holding_cell_htlc_updates.len(), if self.holding_cell_update_fee.is_some() { " and a fee update" } else { "" }); @@ -2052,7 +2052,7 @@ impl Channel { /// waiting on this revoke_and_ack. The generation of this new commitment_signed may also fail, /// generating an appropriate error *after* the channel state has been updated based on the /// revoke_and_ack message. - pub fn revoke_and_ack(&mut self, msg: &msgs::RevokeAndACK, fee_estimator: &FeeEstimator) -> Result<(Option, Vec<(PendingHTLCInfo, u64)>, Vec<(HTLCSource, PaymentHash, HTLCFailReason)>, Option, ChannelMonitorUpdate), ChannelError> { + pub fn revoke_and_ack(&mut self, msg: &msgs::RevokeAndACK, fee_estimator: &FeeEstimator) -> Result<(Option, Vec<(PendingHTLCInfo, u64)>, Vec<(HTLCSource, PaymentHash, HTLCFailReason)>, Option, ChannelMonitorUpdate), ChannelError> { if (self.channel_state & (ChannelState::ChannelFunded as u32)) != (ChannelState::ChannelFunded as u32) { return Err(ChannelError::Close("Got revoke/ACK message when channel was not in an operational state")); } @@ -2299,7 +2299,7 @@ impl Channel { }) } - pub fn send_update_fee_and_commit(&mut self, feerate_per_kw: u64) -> Result, ChannelError> { + pub fn send_update_fee_and_commit(&mut self, feerate_per_kw: u64) -> Result, ChannelError> { match self.send_update_fee(feerate_per_kw) { Some(update_fee) => { let (commitment_signed, monitor_update) = self.send_commitment_no_status_check()?; @@ -2450,7 +2450,7 @@ impl Channel { (raa, commitment_update, order, forwards, failures, needs_broadcast_safe, funding_locked) } - pub fn update_fee(&mut self, fee_estimator: &FeeEstimator, msg: &msgs::UpdateFee) -> Result<(), ChannelError> { + pub fn update_fee(&mut self, fee_estimator: &FeeEstimator, msg: &msgs::UpdateFee) -> Result<(), ChannelError> { if self.channel_outbound { return Err(ChannelError::Close("Non-funding remote tried to update channel fee")); } @@ -2532,7 +2532,7 @@ impl Channel { /// May panic if some calls other than message-handling calls (which will all Err immediately) /// have been called between remove_uncommitted_htlcs_and_mark_paused and this call. - pub fn channel_reestablish(&mut self, msg: &msgs::ChannelReestablish) -> Result<(Option, Option, Option, Option, RAACommitmentOrder, Option), ChannelError> { + pub fn channel_reestablish(&mut self, msg: &msgs::ChannelReestablish) -> Result<(Option, Option, Option, Option, RAACommitmentOrder, Option), ChannelError> { if self.channel_state & (ChannelState::PeerDisconnected as u32) == 0 { // While BOLT 2 doesn't indicate explicitly we should error this channel here, it // almost certainly indicates we are going to end up out-of-sync in some way, so we @@ -2552,8 +2552,18 @@ impl Channel { return Err(ChannelError::Close("Peer sent a garbage channel_reestablish with secret key not matching the commitment height provided")); } if msg.next_remote_commitment_number > INITIAL_COMMITMENT_NUMBER - self.cur_local_commitment_transaction_number { - self.channel_monitor.provide_rescue_remote_commitment_tx_info(data_loss.my_current_per_commitment_point); - return Err(ChannelError::CloseDelayBroadcast { msg: "We have fallen behind - we have received proof that if we broadcast remote is going to claim our funds - we can't do any automated broadcasting", update: Some(self.channel_monitor.clone())}); + self.latest_monitor_update_id += 1; + let monitor_update = ChannelMonitorUpdate { + update_id: self.latest_monitor_update_id, + updates: vec![ChannelMonitorUpdateStep::RescueRemoteCommitmentTXInfo { + their_current_per_commitment_point: data_loss.my_current_per_commitment_point + }] + }; + self.channel_monitor.update_monitor_ooo(monitor_update.clone()).unwrap(); + return Err(ChannelError::CloseDelayBroadcast { + msg: "We have fallen behind - we have received proof that if we broadcast remote is going to claim our funds - we can't do any automated broadcasting", + update: monitor_update + }); } }, OptionalField::Absent => {} @@ -2689,7 +2699,7 @@ impl Channel { }) } - pub fn shutdown(&mut self, fee_estimator: &FeeEstimator, msg: &msgs::Shutdown) -> Result<(Option, Option, Vec<(HTLCSource, PaymentHash)>), ChannelError> { + pub fn shutdown(&mut self, fee_estimator: &FeeEstimator, msg: &msgs::Shutdown) -> Result<(Option, Option, Vec<(HTLCSource, PaymentHash)>), ChannelError> { if self.channel_state & (ChannelState::PeerDisconnected as u32) == ChannelState::PeerDisconnected as u32 { return Err(ChannelError::Close("Peer sent shutdown when we needed a channel_reestablish")); } @@ -2785,7 +2795,7 @@ impl Channel { tx.input[0].witness.push(self.get_funding_redeemscript().into_bytes()); } - pub fn closing_signed(&mut self, fee_estimator: &FeeEstimator, msg: &msgs::ClosingSigned) -> Result<(Option, Option), ChannelError> { + pub fn closing_signed(&mut self, fee_estimator: &FeeEstimator, msg: &msgs::ClosingSigned) -> Result<(Option, Option), ChannelError> { if self.channel_state & BOTH_SIDES_SHUTDOWN_MASK != BOTH_SIDES_SHUTDOWN_MASK { return Err(ChannelError::Close("Remote end sent us a closing_signed before both sides provided a shutdown")); } @@ -3273,7 +3283,7 @@ impl Channel { } /// If an Err is returned, it is a ChannelError::Close (for get_outbound_funding_created) - fn get_outbound_funding_created_signature(&mut self) -> Result<(Signature, Transaction), ChannelError> { + fn get_outbound_funding_created_signature(&mut self) -> Result<(Signature, Transaction), ChannelError> { let remote_keys = self.build_remote_transaction_keys()?; let remote_initial_commitment_tx = self.build_commitment_transaction(self.cur_remote_commitment_transaction_number, &remote_keys, false, false, self.feerate_per_kw).0; Ok((self.local_keys.sign_remote_commitment(self.feerate_per_kw, &remote_initial_commitment_tx, &remote_keys, &Vec::new(), self.our_to_self_delay, &self.secp_ctx) @@ -3287,7 +3297,7 @@ impl Channel { /// Note that channel_id changes during this call! /// Do NOT broadcast the funding transaction until after a successful funding_signed call! /// If an Err is returned, it is a ChannelError::Close. - pub fn get_outbound_funding_created(&mut self, funding_txo: OutPoint) -> Result<(msgs::FundingCreated, ChannelMonitor), ChannelError> { + pub fn get_outbound_funding_created(&mut self, funding_txo: OutPoint) -> Result<(msgs::FundingCreated, ChannelMonitor), ChannelError> { if !self.channel_outbound { panic!("Tried to create outbound funding_created message on an inbound channel!"); } @@ -3340,7 +3350,7 @@ impl Channel { /// closing). /// Note that the "channel must be funded" requirement is stricter than BOLT 7 requires - see /// https://github.com/lightningnetwork/lightning-rfc/issues/468 - pub fn get_channel_announcement(&self, our_node_id: PublicKey, chain_hash: Sha256dHash) -> Result<(msgs::UnsignedChannelAnnouncement, Signature), ChannelError> { + pub fn get_channel_announcement(&self, our_node_id: PublicKey, chain_hash: Sha256dHash) -> Result<(msgs::UnsignedChannelAnnouncement, Signature), ChannelError> { if !self.config.announced_channel { return Err(ChannelError::Ignore("Channel is not available for public announcements")); } @@ -3424,7 +3434,7 @@ impl Channel { /// HTLCs on the wire or we wouldn't be able to determine what they actually ACK'ed. /// You MUST call send_commitment prior to any other calls on this Channel /// If an Err is returned, it's a ChannelError::Ignore! - pub fn send_htlc(&mut self, amount_msat: u64, payment_hash: PaymentHash, cltv_expiry: u32, source: HTLCSource, onion_routing_packet: msgs::OnionPacket) -> Result, ChannelError> { + pub fn send_htlc(&mut self, amount_msat: u64, payment_hash: PaymentHash, cltv_expiry: u32, source: HTLCSource, onion_routing_packet: msgs::OnionPacket) -> Result, ChannelError> { if (self.channel_state & (ChannelState::ChannelFunded as u32 | BOTH_SIDES_SHUTDOWN_MASK)) != (ChannelState::ChannelFunded as u32) { return Err(ChannelError::Ignore("Cannot send HTLC until channel is fully established and we haven't started shutting down")); } @@ -3501,7 +3511,7 @@ impl Channel { /// Always returns a ChannelError::Close if an immediately-preceding (read: the /// last call to this Channel) send_htlc returned Ok(Some(_)) and there is an Err. /// May panic if called except immediately after a successful, Ok(Some(_))-returning send_htlc. - pub fn send_commitment(&mut self) -> Result<(msgs::CommitmentSigned, ChannelMonitorUpdate), ChannelError> { + pub fn send_commitment(&mut self) -> Result<(msgs::CommitmentSigned, ChannelMonitorUpdate), ChannelError> { if (self.channel_state & (ChannelState::ChannelFunded as u32)) != (ChannelState::ChannelFunded as u32) { panic!("Cannot create commitment tx until channel is fully established"); } @@ -3533,7 +3543,7 @@ impl Channel { self.send_commitment_no_status_check() } /// Only fails in case of bad keys - fn send_commitment_no_status_check(&mut self) -> Result<(msgs::CommitmentSigned, ChannelMonitorUpdate), ChannelError> { + fn send_commitment_no_status_check(&mut self) -> Result<(msgs::CommitmentSigned, ChannelMonitorUpdate), ChannelError> { // We can upgrade the status of some HTLCs that are waiting on a commitment, even if we // fail to generate this, we still are at least at a position where upgrading their status // is acceptable. @@ -3581,7 +3591,7 @@ impl Channel { /// Only fails in case of bad keys. Used for channel_reestablish commitment_signed generation /// when we shouldn't change HTLC/channel state. - fn send_commitment_no_state_update(&self) -> Result<(msgs::CommitmentSigned, (Transaction, Vec<(HTLCOutputInCommitment, Option<&HTLCSource>)>)), ChannelError> { + fn send_commitment_no_state_update(&self) -> Result<(msgs::CommitmentSigned, (Transaction, Vec<(HTLCOutputInCommitment, Option<&HTLCSource>)>)), ChannelError> { let mut feerate_per_kw = self.feerate_per_kw; if let Some(feerate) = self.pending_update_fee { if self.channel_outbound { @@ -3629,7 +3639,7 @@ impl Channel { /// to send to the remote peer in one go. /// Shorthand for calling send_htlc() followed by send_commitment(), see docs on those for /// more info. - pub fn send_htlc_and_commit(&mut self, amount_msat: u64, payment_hash: PaymentHash, cltv_expiry: u32, source: HTLCSource, onion_routing_packet: msgs::OnionPacket) -> Result, ChannelError> { + pub fn send_htlc_and_commit(&mut self, amount_msat: u64, payment_hash: PaymentHash, cltv_expiry: u32, source: HTLCSource, onion_routing_packet: msgs::OnionPacket) -> Result, ChannelError> { match self.send_htlc(amount_msat, payment_hash, cltv_expiry, source, onion_routing_packet)? { Some(update_add_htlc) => { let (commitment_signed, monitor_update) = self.send_commitment_no_status_check()?; diff --git a/lightning/src/ln/channelmanager.rs b/lightning/src/ln/channelmanager.rs index b489305c9..f7aa487ce 100644 --- a/lightning/src/ln/channelmanager.rs +++ b/lightning/src/ln/channelmanager.rs @@ -210,7 +210,7 @@ impl MsgHandleErrInternal { } } #[inline] - fn from_chan_no_close(err: ChannelError, channel_id: [u8; 32]) -> Self { + fn from_chan_no_close(err: ChannelError, channel_id: [u8; 32]) -> Self { Self { err: match err { ChannelError::Ignore(msg) => LightningError { @@ -484,7 +484,7 @@ macro_rules! break_chan_entry { match $res { Ok(res) => res, Err(ChannelError::Ignore(msg)) => { - break Err(MsgHandleErrInternal::from_chan_no_close::(ChannelError::Ignore(msg), $entry.key().clone())) + break Err(MsgHandleErrInternal::from_chan_no_close(ChannelError::Ignore(msg), $entry.key().clone())) }, Err(ChannelError::Close(msg)) => { log_trace!($self, "Closing channel {} due to Close-required error: {}", log_bytes!($entry.key()[..]), msg); @@ -504,7 +504,7 @@ macro_rules! try_chan_entry { match $res { Ok(res) => res, Err(ChannelError::Ignore(msg)) => { - return Err(MsgHandleErrInternal::from_chan_no_close::(ChannelError::Ignore(msg), $entry.key().clone())) + return Err(MsgHandleErrInternal::from_chan_no_close(ChannelError::Ignore(msg), $entry.key().clone())) }, Err(ChannelError::Close(msg)) => { log_trace!($self, "Closing channel {} due to Close-required error: {}", log_bytes!($entry.key()[..]), msg); @@ -520,16 +520,14 @@ macro_rules! try_chan_entry { if let Some(short_id) = chan.get_short_channel_id() { $channel_state.short_to_id.remove(&short_id); } - if let Some(update) = update { - if let Err(e) = $self.monitor.add_update_monitor(update.get_funding_txo().unwrap(), update.clone()) { - match e { - // Upstream channel is dead, but we want at least to fail backward HTLCs to save - // downstream channels. In case of PermanentFailure, we are not going to be able - // to claim back to_remote output on remote commitment transaction. Doesn't - // make a difference here, we are concern about HTLCs circuit, not onchain funds. - ChannelMonitorUpdateErr::PermanentFailure => {}, - ChannelMonitorUpdateErr::TemporaryFailure => {}, - } + if let Err(e) = $self.monitor.update_monitor(chan.get_funding_txo().unwrap(), update) { + match e { + // Upstream channel is dead, but we want at least to fail backward HTLCs to save + // downstream channels. In case of PermanentFailure, we are not going to be able + // to claim back to_remote output on remote commitment transaction. Doesn't + // make a difference here, we are concern about HTLCs circuit, not onchain funds. + ChannelMonitorUpdateErr::PermanentFailure => {}, + ChannelMonitorUpdateErr::TemporaryFailure => {}, } } let mut shutdown_res = chan.force_shutdown(); @@ -587,7 +585,7 @@ macro_rules! handle_monitor_err { debug_assert!($action_type == RAACommitmentOrder::CommitmentFirst || !$resend_commitment); } $entry.get_mut().monitor_update_failed($resend_raa, $resend_commitment, $failed_forwards, $failed_fails); - Err(MsgHandleErrInternal::from_chan_no_close::(ChannelError::Ignore("Failed to update ChannelMonitor"), *$entry.key())) + Err(MsgHandleErrInternal::from_chan_no_close(ChannelError::Ignore("Failed to update ChannelMonitor"), *$entry.key())) }, } } @@ -2354,7 +2352,7 @@ impl ChannelManager = ChannelError::Close("Got update_fail_malformed_htlc with BADONION not set"); + let chan_err: ChannelError = ChannelError::Close("Got update_fail_malformed_htlc with BADONION not set"); try_chan_entry!(self, Err(chan_err), channel_state, chan); } try_chan_entry!(self, chan.get_mut().update_fail_malformed_htlc(&msg, HTLCFailReason::Reason { failure_code: msg.failure_code, data: Vec::new() }), channel_state, chan); @@ -2529,7 +2527,7 @@ impl ChannelManager = ChannelError::Close("Bad announcement_signatures node_signature"); + let chan_err: ChannelError = ChannelError::Close("Bad announcement_signatures node_signature"); try_chan_entry!(self, Err(chan_err), channel_state, chan); } diff --git a/lightning/src/ln/channelmonitor.rs b/lightning/src/ln/channelmonitor.rs index 39467f6cc..373f811e9 100644 --- a/lightning/src/ln/channelmonitor.rs +++ b/lightning/src/ln/channelmonitor.rs @@ -673,6 +673,11 @@ pub(super) enum ChannelMonitorUpdateStep { idx: u64, secret: [u8; 32], }, + /// Indicates our channel is likely a stale version, we're closing, but this update should + /// allow us to spend what is ours if our counterparty broadcasts their latest state. + RescueRemoteCommitmentTXInfo { + their_current_per_commitment_point: PublicKey, + }, } impl Writeable for ChannelMonitorUpdateStep { @@ -716,6 +721,10 @@ impl Writeable for ChannelMonitorUpdateStep { idx.write(w)?; secret.write(w)?; }, + &ChannelMonitorUpdateStep::RescueRemoteCommitmentTXInfo { ref their_current_per_commitment_point } => { + 4u8.write(w)?; + their_current_per_commitment_point.write(w)?; + }, } Ok(()) } @@ -764,6 +773,11 @@ impl Readable for ChannelMonitorUpdateStep { secret: Readable::read(r)?, }) }, + 4u8 => { + Ok(ChannelMonitorUpdateStep::RescueRemoteCommitmentTXInfo { + their_current_per_commitment_point: Readable::read(r)?, + }) + }, _ => Err(DecodeError::InvalidValue), } } @@ -1448,7 +1462,9 @@ impl ChannelMonitor { ChannelMonitorUpdateStep::PaymentPreimage { payment_preimage } => self.provide_payment_preimage(&PaymentHash(Sha256::hash(&payment_preimage.0[..]).into_inner()), &payment_preimage), ChannelMonitorUpdateStep::CommitmentSecret { idx, secret } => - self.provide_secret(idx, secret)? + self.provide_secret(idx, secret)?, + ChannelMonitorUpdateStep::RescueRemoteCommitmentTXInfo { their_current_per_commitment_point } => + self.provide_rescue_remote_commitment_tx_info(their_current_per_commitment_point), } } self.latest_update_id = updates.update_id; @@ -1472,7 +1488,9 @@ impl ChannelMonitor { ChannelMonitorUpdateStep::PaymentPreimage { payment_preimage } => self.provide_payment_preimage(&PaymentHash(Sha256::hash(&payment_preimage.0[..]).into_inner()), &payment_preimage), ChannelMonitorUpdateStep::CommitmentSecret { idx, secret } => - self.provide_secret(idx, secret)? + self.provide_secret(idx, secret)?, + ChannelMonitorUpdateStep::RescueRemoteCommitmentTXInfo { their_current_per_commitment_point } => + self.provide_rescue_remote_commitment_tx_info(their_current_per_commitment_point), } } self.latest_update_id = updates.update_id; -- 2.39.5