X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=src%2Fln%2Fchannel.rs;h=0a923dc7eedc904da44f31d6ed9f6c74c422b6a3;hb=a82a5f71dac03181145e78c90145e8a036fac2c5;hp=906d1ffff0e36f09caccd5009966cc19000c1620;hpb=ad77f72ff3ede5b9d6c5f9c91075e712f4e8b6c6;p=rust-lightning diff --git a/src/ln/channel.rs b/src/ln/channel.rs index 906d1fff..0a923dc7 100644 --- a/src/ln/channel.rs +++ b/src/ln/channel.rs @@ -2014,14 +2014,17 @@ 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), HandleError> { + pub fn channel_reestablish(&mut self, msg: &msgs::ChannelReestablish) -> Result<(Option, Option, Option, Option), ChannelError> { if self.channel_state & (ChannelState::PeerDisconnected as u32) == 0 { - return Err(HandleError{err: "Peer sent a loose channel_reestablish not after reconnect", action: Some(msgs::ErrorAction::SendErrorMessage{msg: msgs::ErrorMessage{data: "Peer sent a loose channel_reestablish not after reconnect".to_string(), channel_id: msg.channel_id}})}); + // 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 + // just close here instead of trying to recover. + return Err(ChannelError::Close("Peer sent a loose channel_reestablish not after reconnect")); } if msg.next_local_commitment_number == 0 || msg.next_local_commitment_number >= INITIAL_COMMITMENT_NUMBER || msg.next_remote_commitment_number == 0 || msg.next_remote_commitment_number >= INITIAL_COMMITMENT_NUMBER { - return Err(HandleError{err: "Peer send garbage channel_reestablish", action: Some(msgs::ErrorAction::SendErrorMessage{msg: msgs::ErrorMessage{data: "Peer send garbage channel_reestablish".to_string(), channel_id: msg.channel_id}})}); + return Err(ChannelError::Close("Peer send garbage channel_reestablish")); } // Go ahead and unmark PeerDisconnected as various calls we may make check for it (and all @@ -2041,7 +2044,7 @@ impl Channel { next_per_commitment_point, }); } else { - return Err(HandleError{err: "Peer attempted to reestablish channel with a very old local commitment transaction", action: Some(msgs::ErrorAction::SendErrorMessage{msg: msgs::ErrorMessage{data: "Peer attempted to reestablish channel with a very old remote commitment transaction".to_string(), channel_id: msg.channel_id}})}); + return Err(ChannelError::Close("Peer attempted to reestablish channel with a very old local commitment transaction")); } if msg.next_local_commitment_number == INITIAL_COMMITMENT_NUMBER - self.cur_remote_commitment_transaction_number { @@ -2065,11 +2068,12 @@ impl Channel { match self.free_holding_cell_htlcs() { Err(e) => { if let &Some(msgs::ErrorAction::DisconnectPeer{msg: Some(_)}) = &e.action { + return Err(ChannelError::Close(e.err)); } else if let &Some(msgs::ErrorAction::SendErrorMessage{msg: _}) = &e.action { + return Err(ChannelError::Close(e.err)); } else { panic!("Got non-channel-failing result from free_holding_cell_htlcs"); } - return Err(e); }, Ok(Some((commitment_update, channel_monitor))) => return Ok((None, required_revoke, Some(commitment_update), Some(channel_monitor))), Ok(None) => return Ok((None, required_revoke, None, None)), @@ -2088,7 +2092,7 @@ impl Channel { commitment_signed: self.send_commitment_no_state_update().expect("It looks like we failed to re-generate a commitment_signed we had previously sent?").0, }), None)); } else { - return Err(HandleError{err: "Peer attempted to reestablish channel with a very old remote commitment transaction", action: Some(msgs::ErrorAction::SendErrorMessage{msg: msgs::ErrorMessage{data: "Peer attempted to reestablish channel with a very old remote commitment transaction".to_string(), channel_id: msg.channel_id}})}); + return Err(ChannelError::Close("Peer attempted to reestablish channel with a very old remote commitment transaction")); } } @@ -2644,15 +2648,15 @@ 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), HandleError> { + pub fn get_channel_announcement(&self, our_node_id: PublicKey, chain_hash: Sha256dHash) -> Result<(msgs::UnsignedChannelAnnouncement, Signature), ChannelError> { if !self.announce_publicly { - return Err(HandleError{err: "Channel is not available for public announcements", action: Some(msgs::ErrorAction::IgnoreError)}); + return Err(ChannelError::Ignore("Channel is not available for public announcements")); } if self.channel_state & (ChannelState::ChannelFunded as u32) == 0 { - return Err(HandleError{err: "Cannot get a ChannelAnnouncement until the channel funding has been locked", action: Some(msgs::ErrorAction::IgnoreError)}); + return Err(ChannelError::Ignore("Cannot get a ChannelAnnouncement until the channel funding has been locked")); } if (self.channel_state & (ChannelState::LocalShutdownSent as u32 | ChannelState::ShutdownComplete as u32)) != 0 { - return Err(HandleError{err: "Cannot get a ChannelAnnouncement once the channel is closing", action: Some(msgs::ErrorAction::IgnoreError)}); + return Err(ChannelError::Ignore("Cannot get a ChannelAnnouncement once the channel is closing")); } let were_node_one = our_node_id.serialize()[..] < self.their_node_id.serialize()[..]; @@ -2875,18 +2879,23 @@ impl Channel { /// Begins the shutdown process, getting a message for the remote peer and returning all /// holding cell HTLCs for payment failure. - pub fn get_shutdown(&mut self) -> Result<(msgs::Shutdown, Vec<(HTLCSource, [u8; 32])>), HandleError> { + pub fn get_shutdown(&mut self) -> Result<(msgs::Shutdown, Vec<(HTLCSource, [u8; 32])>), APIError> { for htlc in self.pending_outbound_htlcs.iter() { if htlc.state == OutboundHTLCState::LocalAnnounced { - return Err(HandleError{err: "Cannot begin shutdown with pending HTLCs, call send_commitment first", action: None}); + return Err(APIError::APIMisuseError{err: "Cannot begin shutdown with pending HTLCs. Process pending events first"}); } } if self.channel_state & BOTH_SIDES_SHUTDOWN_MASK != 0 { - return Err(HandleError{err: "Shutdown already in progress", action: None}); + if (self.channel_state & ChannelState::LocalShutdownSent as u32) == ChannelState::LocalShutdownSent as u32 { + return Err(APIError::APIMisuseError{err: "Shutdown already in progress"}); + } + else if (self.channel_state & ChannelState::RemoteShutdownSent as u32) == ChannelState::RemoteShutdownSent as u32 { + return Err(APIError::ChannelUnavailable{err: "Shutdown already in progress by remote"}); + } } assert_eq!(self.channel_state & ChannelState::ShutdownComplete as u32, 0); if self.channel_state & (ChannelState::PeerDisconnected as u32) == ChannelState::PeerDisconnected as u32 { - return Err(HandleError{err: "Cannot begin shutdown while peer is disconnected, maybe force-close instead?", action: None}); + return Err(APIError::ChannelUnavailable{err: "Cannot begin shutdown while peer is disconnected, maybe force-close instead?"}); } let our_closing_script = self.get_closing_scriptpubkey();