X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Fln%2Fchannelmanager.rs;h=a4684bfe6cc2960438bfdc9e2e575ed2b7aa2f79;hb=0273ac52db6df30b798b1815b093d9ef065c8c17;hp=ebffe5c0af988a6b180d5909f90d256bdad37aac;hpb=6ce7f3e1cecb2b9393d89cac495776f82e975a36;p=rust-lightning diff --git a/lightning/src/ln/channelmanager.rs b/lightning/src/ln/channelmanager.rs index ebffe5c0..a4684bfe 100644 --- a/lightning/src/ln/channelmanager.rs +++ b/lightning/src/ln/channelmanager.rs @@ -54,7 +54,7 @@ use chain::keysinterface::{Sign, KeysInterface, KeysManager, InMemorySigner}; use util::config::UserConfig; use util::events::{EventHandler, EventsProvider, MessageSendEvent, MessageSendEventsProvider, ClosureReason}; use util::{byte_utils, events}; -use util::ser::{Readable, ReadableArgs, MaybeReadable, Writeable, Writer}; +use util::ser::{BigSize, FixedLengthReader, Readable, ReadableArgs, MaybeReadable, Writeable, Writer}; use util::chacha20::{ChaCha20, ChaChaReader}; use util::logger::{Logger, Level}; use util::errors::APIError; @@ -489,7 +489,7 @@ pub struct ChannelManager ChannelMana self.fail_htlc_backwards_internal(channel_state, htlc_src, &payment_hash, HTLCFailReason::Reason { failure_code, data: onion_failure_data}); }, - HTLCSource::OutboundRoute { session_priv, mpp_id, .. } => { + HTLCSource::OutboundRoute { session_priv, mpp_id, path, .. } => { let mut session_priv_bytes = [0; 32]; session_priv_bytes.copy_from_slice(&session_priv[..]); let mut outbounds = self.pending_outbound_payments.lock().unwrap(); if let hash_map::Entry::Occupied(mut sessions) = outbounds.entry(mpp_id) { if sessions.get_mut().remove(&session_priv_bytes) { self.pending_events.lock().unwrap().push( - events::Event::PaymentFailed { + events::Event::PaymentPathFailed { payment_hash, rejected_by_dest: false, network_update: None, all_paths_failed: sessions.get().len() == 0, + path: path.clone(), #[cfg(test)] error_code: None, #[cfg(test)] @@ -2950,11 +2952,12 @@ impl ChannelMana // process_onion_failure we should close that channel as it implies our // next-hop is needlessly blaming us! self.pending_events.lock().unwrap().push( - events::Event::PaymentFailed { + events::Event::PaymentPathFailed { payment_hash: payment_hash.clone(), rejected_by_dest: !payment_retryable, network_update, all_paths_failed, + path: path.clone(), #[cfg(test)] error_code: onion_error_code, #[cfg(test)] @@ -2976,11 +2979,12 @@ impl ChannelMana // TODO: For non-temporary failures, we really should be closing the // channel here as we apparently can't relay through them anyway. self.pending_events.lock().unwrap().push( - events::Event::PaymentFailed { + events::Event::PaymentPathFailed { payment_hash: payment_hash.clone(), rejected_by_dest: path.len() == 1, network_update: None, all_paths_failed, + path: path.clone(), #[cfg(test)] error_code: Some(*failure_code), #[cfg(test)] @@ -4929,10 +4933,74 @@ impl_writeable_tlv_based!(PendingHTLCInfo, { (8, outgoing_cltv_value, required) }); -impl_writeable_tlv_based_enum!(HTLCFailureMsg, ; - (0, Relay), - (1, Malformed), -); + +impl Writeable for HTLCFailureMsg { + fn write(&self, writer: &mut W) -> Result<(), io::Error> { + match self { + HTLCFailureMsg::Relay(msgs::UpdateFailHTLC { channel_id, htlc_id, reason }) => { + 0u8.write(writer)?; + channel_id.write(writer)?; + htlc_id.write(writer)?; + reason.write(writer)?; + }, + HTLCFailureMsg::Malformed(msgs::UpdateFailMalformedHTLC { + channel_id, htlc_id, sha256_of_onion, failure_code + }) => { + 1u8.write(writer)?; + channel_id.write(writer)?; + htlc_id.write(writer)?; + sha256_of_onion.write(writer)?; + failure_code.write(writer)?; + }, + } + Ok(()) + } +} + +impl Readable for HTLCFailureMsg { + fn read(reader: &mut R) -> Result { + let id: u8 = Readable::read(reader)?; + match id { + 0 => { + Ok(HTLCFailureMsg::Relay(msgs::UpdateFailHTLC { + channel_id: Readable::read(reader)?, + htlc_id: Readable::read(reader)?, + reason: Readable::read(reader)?, + })) + }, + 1 => { + Ok(HTLCFailureMsg::Malformed(msgs::UpdateFailMalformedHTLC { + channel_id: Readable::read(reader)?, + htlc_id: Readable::read(reader)?, + sha256_of_onion: Readable::read(reader)?, + failure_code: Readable::read(reader)?, + })) + }, + // In versions prior to 0.0.101, HTLCFailureMsg objects were written with type 0 or 1 but + // weren't length-prefixed and thus didn't support reading the TLV stream suffix of the network + // messages contained in the variants. + // In version 0.0.101, support for reading the variants with these types was added, and + // we should migrate to writing these variants when UpdateFailHTLC or + // UpdateFailMalformedHTLC get TLV fields. + 2 => { + let length: BigSize = Readable::read(reader)?; + let mut s = FixedLengthReader::new(reader, length.0); + let res = Readable::read(&mut s)?; + s.eat_remaining()?; // Return ShortRead if there's actually not enough bytes + Ok(HTLCFailureMsg::Relay(res)) + }, + 3 => { + let length: BigSize = Readable::read(reader)?; + let mut s = FixedLengthReader::new(reader, length.0); + let res = Readable::read(&mut s)?; + s.eat_remaining()?; // Return ShortRead if there's actually not enough bytes + Ok(HTLCFailureMsg::Malformed(res)) + }, + _ => Err(DecodeError::UnknownRequiredFeature), + } + } +} + impl_writeable_tlv_based_enum!(PendingHTLCStatus, ; (0, Forward), (1, Fail),