X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=src%2Fln%2Fchannel.rs;h=b9a81f6ebc0465cf34396eb44073b790fd7c3925;hb=224fb05cc53526e7b861e746183451d3d74ad549;hp=e0768e37cc1a67553ed94d3b3740dc42ab96e36a;hpb=78232f2aeded08b32fa4ebfeb0b77d80b337518d;p=rust-lightning diff --git a/src/ln/channel.rs b/src/ln/channel.rs index e0768e37..b9a81f6e 100644 --- a/src/ln/channel.rs +++ b/src/ln/channel.rs @@ -2071,6 +2071,9 @@ impl Channel { self.channel_state = ChannelState::ShutdownComplete as u32; return outbound_drops; } + // Upon reconnect we have to start the closing_signed dance over, but shutdown messages + // will be retransmitted. + self.last_sent_closing_fee = None; let mut inbound_drop_count = 0; self.pending_inbound_htlcs.retain(|htlc| { @@ -2258,7 +2261,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), 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 @@ -2274,9 +2277,16 @@ impl Channel { // remaining cases either succeed or ErrorMessage-fail). self.channel_state &= !(ChannelState::PeerDisconnected as u32); + let shutdown_msg = if self.channel_state & (ChannelState::LocalShutdownSent as u32) != 0 { + Some(msgs::Shutdown { + channel_id: self.channel_id, + scriptpubkey: self.get_closing_scriptpubkey(), + }) + } else { None }; + if self.channel_state & (ChannelState::FundingSent as u32 | ChannelState::OurFundingLocked as u32) == ChannelState::FundingSent as u32 { // Short circuit the whole handler as there is nothing we can resend them - return Ok((None, None, None, None, RAACommitmentOrder::CommitmentFirst)); + return Ok((None, None, None, None, RAACommitmentOrder::CommitmentFirst, shutdown_msg)); } if msg.next_local_commitment_number == 0 || msg.next_remote_commitment_number == 0 { @@ -2289,7 +2299,7 @@ impl Channel { return Ok((Some(msgs::FundingLocked { channel_id: self.channel_id(), next_per_commitment_point: next_per_commitment_point, - }), None, None, None, RAACommitmentOrder::CommitmentFirst)); + }), None, None, None, RAACommitmentOrder::CommitmentFirst, shutdown_msg)); } let required_revoke = if msg.next_remote_commitment_number == INITIAL_COMMITMENT_NUMBER - self.cur_local_commitment_transaction_number { @@ -2352,11 +2362,11 @@ impl Channel { panic!("Got non-channel-failing result from free_holding_cell_htlcs"); } }, - Ok(Some((commitment_update, channel_monitor))) => return Ok((resend_funding_locked, required_revoke, Some(commitment_update), Some(channel_monitor), order)), - Ok(None) => return Ok((resend_funding_locked, required_revoke, None, None, order)), + Ok(Some((commitment_update, channel_monitor))) => return Ok((resend_funding_locked, required_revoke, Some(commitment_update), Some(channel_monitor), order, shutdown_msg)), + Ok(None) => return Ok((resend_funding_locked, required_revoke, None, None, order, shutdown_msg)), } } else { - return Ok((resend_funding_locked, required_revoke, None, None, order)); + return Ok((resend_funding_locked, required_revoke, None, None, order, shutdown_msg)); } } else if msg.next_local_commitment_number == our_next_remote_commitment_number - 1 { if required_revoke.is_some() { @@ -2370,10 +2380,10 @@ impl Channel { if self.channel_state & (ChannelState::MonitorUpdateFailed as u32) != 0 { self.monitor_pending_commitment_signed = true; - return Ok((resend_funding_locked, None, None, None, order)); + return Ok((resend_funding_locked, None, None, None, order, shutdown_msg)); } - return Ok((resend_funding_locked, required_revoke, Some(self.get_last_commitment_update()), None, order)); + return Ok((resend_funding_locked, required_revoke, Some(self.get_last_commitment_update()), None, order, shutdown_msg)); } else { return Err(ChannelError::Close("Peer attempted to reestablish channel with a very old remote commitment transaction")); } @@ -2382,7 +2392,8 @@ impl Channel { fn maybe_propose_first_closing_signed(&mut self, fee_estimator: &FeeEstimator) -> Option { if !self.channel_outbound || !self.pending_inbound_htlcs.is_empty() || !self.pending_outbound_htlcs.is_empty() || self.channel_state & (BOTH_SIDES_SHUTDOWN_MASK | ChannelState::AwaitingRemoteRevoke as u32) != BOTH_SIDES_SHUTDOWN_MASK || - self.last_sent_closing_fee.is_some() { + self.last_sent_closing_fee.is_some() || + self.cur_remote_commitment_transaction_number != self.cur_local_commitment_transaction_number{ return None; } @@ -2420,9 +2431,6 @@ impl Channel { return Err(ChannelError::Close("Got shutdown with remote pending HTLCs")); } } - if (self.channel_state & ChannelState::RemoteShutdownSent as u32) == ChannelState::RemoteShutdownSent as u32 { - return Err(ChannelError::Ignore("Remote peer sent duplicate shutdown message")); - } assert_eq!(self.channel_state & ChannelState::ShutdownComplete as u32, 0); // BOLT 2 says we must only send a scriptpubkey of certain standard forms, which are up to @@ -2452,6 +2460,7 @@ impl Channel { // We can't send our shutdown until we've committed all of our pending HTLCs, but the // remote side is unlikely to accept any new HTLCs, so we go ahead and "free" any holding // cell HTLCs and return them to fail the payment. + self.holding_cell_update_fee = None; let mut dropped_outbound_htlcs = Vec::with_capacity(self.holding_cell_htlc_updates.len()); self.holding_cell_htlc_updates.retain(|htlc_update| { match htlc_update { @@ -3260,9 +3269,9 @@ impl Channel { } self.channel_update_count += 1; - // We can't send our shutdown until we've committed all of our pending HTLCs, but the - // remote side is unlikely to accept any new HTLCs, so we go ahead and "free" any holding - // cell HTLCs and return them to fail the payment. + // Go ahead and drop holding cell updates as we'd rather fail payments than wait to send + // our shutdown until we've committed all of the pending changes. + self.holding_cell_update_fee = None; let mut dropped_outbound_htlcs = Vec::with_capacity(self.holding_cell_htlc_updates.len()); self.holding_cell_htlc_updates.retain(|htlc_update| { match htlc_update {