X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;ds=sidebyside;f=lightning%2Fsrc%2Futil%2Fevents.rs;h=1319f7d2101cc1c5b861acc5c3c86e78dd72277b;hb=34dd7c5cbbfe04a91edacfc995499a40f22e9d7c;hp=ca4e96d60f73e4f44d0c5ce01a82d80671d4943a;hpb=e64467f512bf15f2ac0a3f8c54512f4445ab6adf;p=rust-lightning diff --git a/lightning/src/util/events.rs b/lightning/src/util/events.rs index ca4e96d6..1319f7d2 100644 --- a/lightning/src/util/events.rs +++ b/lightning/src/util/events.rs @@ -19,7 +19,8 @@ use ln::msgs; use ln::msgs::DecodeError; use ln::{PaymentPreimage, PaymentHash, PaymentSecret}; use routing::network_graph::NetworkUpdate; -use util::ser::{Writeable, Writer, MaybeReadable, Readable, VecReadWrapper, VecWriteWrapper}; +use util::ser::{BigSize, FixedLengthReader, Writeable, Writer, MaybeReadable, Readable, VecReadWrapper, VecWriteWrapper}; +use routing::router::RouteHop; use bitcoin::blockdata::script::Script; @@ -170,8 +171,8 @@ pub enum Event { /// Indicates an outbound payment we made succeeded (i.e. it made it all the way to its target /// and we got back the payment preimage for it). /// - /// Note for MPP payments: in rare cases, this event may be preceded by a `PaymentFailed` event. - /// In this situation, you SHOULD treat this payment as having succeeded. + /// Note for MPP payments: in rare cases, this event may be preceded by a `PaymentPathFailed` + /// event. In this situation, you SHOULD treat this payment as having succeeded. PaymentSent { /// The preimage to the hash given to ChannelManager::send_payment. /// Note that this serves as a payment receipt, if you wish to have such a thing, you must @@ -180,7 +181,7 @@ pub enum Event { }, /// Indicates an outbound payment we made failed. Probably some intermediary node dropped /// something. You may wish to retry with a different route. - PaymentFailed { + PaymentPathFailed { /// The hash which was given to ChannelManager::send_payment. payment_hash: PaymentHash, /// Indicates the payment was rejected for some reason by the recipient. This implies that @@ -200,6 +201,8 @@ pub enum Event { /// failed. This will be set to false if (1) this is an MPP payment and (2) other parts of the /// larger MPP payment were still in flight when this event was generated. all_paths_failed: bool, + /// The payment path that failed. + path: Vec, #[cfg(test)] error_code: Option, #[cfg(test)] @@ -291,7 +294,8 @@ impl Writeable for Event { (0, payment_preimage, required), }); }, - &Event::PaymentFailed { ref payment_hash, ref rejected_by_dest, ref network_update, ref all_paths_failed, + &Event::PaymentPathFailed { ref payment_hash, ref rejected_by_dest, ref network_update, + ref all_paths_failed, ref path, #[cfg(test)] ref error_code, #[cfg(test)] @@ -307,6 +311,7 @@ impl Writeable for Event { (1, network_update, option), (2, rejected_by_dest, required), (3, all_paths_failed, required), + (5, path, vec_type), }); }, &Event::PendingHTLCsForwardable { time_forwardable: _ } => { @@ -335,6 +340,9 @@ impl Writeable for Event { (2, reason, required) }); }, + // Note that, going forward, all new events must only write data inside of + // `write_tlv_fields`. Versions 0.0.101+ will ignore odd-numbered events that write + // data via `write_tlv_fields`. } Ok(()) } @@ -342,6 +350,8 @@ impl Writeable for Event { impl MaybeReadable for Event { fn read(reader: &mut R) -> Result, msgs::DecodeError> { match Readable::read(reader)? { + // Note that we do not write a length-prefixed TLV for FundingGenerationReady events, + // unlike all other events, thus we return immediately here. 0u8 => Ok(None), 1u8 => { let f = || { @@ -398,17 +408,20 @@ impl MaybeReadable for Event { let mut rejected_by_dest = false; let mut network_update = None; let mut all_paths_failed = Some(true); + let mut path: Option> = Some(vec![]); read_tlv_fields!(reader, { (0, payment_hash, required), (1, network_update, ignorable), (2, rejected_by_dest, required), (3, all_paths_failed, option), + (5, path, vec_type), }); - Ok(Some(Event::PaymentFailed { + Ok(Some(Event::PaymentPathFailed { payment_hash, rejected_by_dest, network_update, all_paths_failed: all_paths_failed.unwrap(), + path: path.unwrap(), #[cfg(test)] error_code, #[cfg(test)] @@ -459,7 +472,19 @@ impl MaybeReadable for Event { Ok(Some(Event::ChannelClosed { channel_id, reason: reason.unwrap() })) }, // Versions prior to 0.0.100 did not ignore odd types, instead returning InvalidValue. - x if x % 2 == 1 => Ok(None), + // Version 0.0.100 failed to properly ignore odd types, possibly resulting in corrupt + // reads. + x if x % 2 == 1 => { + // If the event is of unknown type, assume it was written with `write_tlv_fields`, + // which prefixes the whole thing with a length BigSize. Because the event is + // odd-type unknown, we should treat it as `Ok(None)` even if it has some TLV + // fields that are even. Thus, we avoid using `read_tlv_fields` and simply read + // exactly the number of bytes specified, ignoring them entirely. + let tlv_len: BigSize = Readable::read(reader)?; + FixedLengthReader::new(reader, tlv_len.0) + .eat_remaining().map_err(|_| msgs::DecodeError::ShortRead)?; + Ok(None) + }, _ => Err(msgs::DecodeError::InvalidValue) } }