X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=src%2Fln%2Fchannel.rs;h=19c80f81e4d4494f98d2d79a4f20b7922e154c4e;hb=84953fc68fd9b119f85f947909cd91b72db079c7;hp=762ecab5b20614e11b67e4aa3b318f81d7840916;hpb=662485a4ddb63058a967fd3fb81efc9faf924466;p=rust-lightning diff --git a/src/ln/channel.rs b/src/ln/channel.rs index 762ecab5..19c80f81 100644 --- a/src/ln/channel.rs +++ b/src/ln/channel.rs @@ -1508,38 +1508,38 @@ impl Channel { /// Removes an outbound HTLC which has been commitment_signed by the remote end #[inline] - fn mark_outbound_htlc_removed(&mut self, htlc_id: u64, check_preimage: Option<[u8; 32]>, fail_reason: Option) -> Result<&HTLCSource, HandleError> { + fn mark_outbound_htlc_removed(&mut self, htlc_id: u64, check_preimage: Option<[u8; 32]>, fail_reason: Option) -> Result<&HTLCSource, ChannelError> { for htlc in self.pending_outbound_htlcs.iter_mut() { if htlc.htlc_id == htlc_id { match check_preimage { None => {}, Some(payment_hash) => if payment_hash != htlc.payment_hash { - return Err(HandleError{err: "Remote tried to fulfill HTLC with an incorrect preimage", action: None}); + return Err(ChannelError::Close("Remote tried to fulfill HTLC with an incorrect preimage")); } }; match htlc.state { OutboundHTLCState::LocalAnnounced => - return Err(HandleError{err: "Remote tried to fulfill HTLC before it had been committed", action: None}), + return Err(ChannelError::Close("Remote tried to fulfill HTLC before it had been committed")), OutboundHTLCState::Committed => { htlc.state = OutboundHTLCState::RemoteRemoved; htlc.fail_reason = fail_reason; }, OutboundHTLCState::AwaitingRemoteRevokeToRemove | OutboundHTLCState::AwaitingRemovedRemoteRevoke | OutboundHTLCState::RemoteRemoved => - return Err(HandleError{err: "Remote tried to fulfill HTLC that they'd already fulfilled", action: None}), + return Err(ChannelError::Close("Remote tried to fulfill HTLC that they'd already fulfilled")), } return Ok(&htlc.source); } } - Err(HandleError{err: "Remote tried to fulfill/fail an HTLC we couldn't find", action: None}) + 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<&HTLCSource, HandleError> { + pub fn update_fulfill_htlc(&mut self, msg: &msgs::UpdateFulfillHTLC) -> Result<&HTLCSource, ChannelError> { if (self.channel_state & (ChannelState::ChannelFunded as u32)) != (ChannelState::ChannelFunded as u32) { - return Err(HandleError{err: "Got add HTLC message when channel was not in an operational state", action: None}); + return Err(ChannelError::Close("Got fulfill HTLC message when channel was not in an operational state")); } if self.channel_state & (ChannelState::PeerDisconnected as u32) == ChannelState::PeerDisconnected as u32 { - return Err(HandleError{err: "Peer sent update_fulfill_htlc when we needed a channel_reestablish", action: Some(msgs::ErrorAction::SendErrorMessage{msg: msgs::ErrorMessage{data: "Peer sent update_fulfill_htlc when we needed a channel_reestablish".to_string(), channel_id: msg.channel_id}})}); + return Err(ChannelError::Close("Peer sent update_fulfill_htlc when we needed a channel_reestablish")); } let mut sha = Sha256::new(); @@ -1550,23 +1550,23 @@ impl Channel { self.mark_outbound_htlc_removed(msg.htlc_id, Some(payment_hash), None) } - pub fn update_fail_htlc(&mut self, msg: &msgs::UpdateFailHTLC, fail_reason: HTLCFailReason) -> Result<&HTLCSource, HandleError> { + pub fn update_fail_htlc(&mut self, msg: &msgs::UpdateFailHTLC, fail_reason: HTLCFailReason) -> Result<&HTLCSource, ChannelError> { if (self.channel_state & (ChannelState::ChannelFunded as u32)) != (ChannelState::ChannelFunded as u32) { - return Err(HandleError{err: "Got add HTLC message when channel was not in an operational state", action: None}); + return Err(ChannelError::Close("Got fail HTLC message when channel was not in an operational state")); } if self.channel_state & (ChannelState::PeerDisconnected as u32) == ChannelState::PeerDisconnected as u32 { - return Err(HandleError{err: "Peer sent update_fail_htlc when we needed a channel_reestablish", action: Some(msgs::ErrorAction::SendErrorMessage{msg: msgs::ErrorMessage{data: "Peer sent update_fail_htlc when we needed a channel_reestablish".to_string(), channel_id: msg.channel_id}})}); + return Err(ChannelError::Close("Peer sent update_fail_htlc when we needed a channel_reestablish")); } self.mark_outbound_htlc_removed(msg.htlc_id, None, Some(fail_reason)) } - pub fn update_fail_malformed_htlc<'a>(&mut self, msg: &msgs::UpdateFailMalformedHTLC, fail_reason: HTLCFailReason) -> Result<&HTLCSource, HandleError> { + pub fn update_fail_malformed_htlc<'a>(&mut self, msg: &msgs::UpdateFailMalformedHTLC, fail_reason: HTLCFailReason) -> Result<&HTLCSource, ChannelError> { if (self.channel_state & (ChannelState::ChannelFunded as u32)) != (ChannelState::ChannelFunded as u32) { - return Err(HandleError{err: "Got add HTLC message when channel was not in an operational state", action: None}); + return Err(ChannelError::Close("Got fail malformed HTLC message when channel was not in an operational state")); } if self.channel_state & (ChannelState::PeerDisconnected as u32) == ChannelState::PeerDisconnected as u32 { - return Err(HandleError{err: "Peer sent update_fail_malformed_htlc when we needed a channel_reestablish", action: Some(msgs::ErrorAction::SendErrorMessage{msg: msgs::ErrorMessage{data: "Peer sent update_fail_malformed_htlc when we needed a channel_reestablish".to_string(), channel_id: msg.channel_id}})}); + return Err(ChannelError::Close("Peer sent update_fail_malformed_htlc when we needed a channel_reestablish")); } self.mark_outbound_htlc_removed(msg.htlc_id, None, Some(fail_reason)) @@ -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()[..];