Parse keysend TLV field in onion.
[rust-lightning] / lightning / src / ln / msgs.rs
index eec1a053802fd7476ce1b43f0518b4ef339c1dfb..85672f4cd978dbd521b01b4fe5493b7a9f8d438a 100644 (file)
@@ -38,6 +38,7 @@ use core::fmt::Debug;
 use std::io::Read;
 
 use util::events::MessageSendEventsProvider;
+use util::logger;
 use util::ser::{Readable, Writeable, Writer, FixedLengthReader, HighZeroBytesDroppedVarInt};
 
 use ln::{PaymentPreimage, PaymentHash, PaymentSecret};
@@ -46,7 +47,7 @@ use ln::{PaymentPreimage, PaymentHash, PaymentSecret};
 pub(crate) const MAX_VALUE_MSAT: u64 = 21_000_000_0000_0000_000;
 
 /// An error in decoding a message or struct.
-#[derive(Clone, Debug)]
+#[derive(Clone, Debug, PartialEq)]
 pub enum DecodeError {
        /// A version byte specified something we don't know how to handle.
        /// Includes unknown realm byte in an OnionHopData packet
@@ -688,7 +689,11 @@ pub enum ErrorAction {
                msg: Option<ErrorMessage>
        },
        /// The peer did something harmless that we weren't able to process, just log and ignore
+       // New code should *not* use this. New code must use IgnoreAndLog, below!
        IgnoreError,
+       /// The peer did something harmless that we weren't able to meaningfully process.
+       /// If the error is logged, log it at the given level.
+       IgnoreAndLog(logger::Level),
        /// The peer did something incorrect. Tell them.
        SendErrorMessage {
                /// The message to send.
@@ -880,7 +885,7 @@ pub trait RoutingMessageHandler : MessageSendEventsProvider {
 
 mod fuzzy_internal_msgs {
        use prelude::*;
-       use ln::PaymentSecret;
+       use ln::{PaymentPreimage, PaymentSecret};
 
        // These types aren't intended to be pub, but are exposed for direct fuzzing (as we deserialize
        // them from untrusted input):
@@ -901,6 +906,7 @@ mod fuzzy_internal_msgs {
                },
                FinalNode {
                        payment_data: Option<FinalOnionHopData>,
+                       keysend_preimage: Option<PaymentPreimage>,
                },
        }
 
@@ -1295,20 +1301,20 @@ impl Writeable for OnionHopData {
                        },
                        OnionHopDataFormat::NonFinalNode { short_channel_id } => {
                                encode_varint_length_prefixed_tlv!(w, {
-                                       (2, HighZeroBytesDroppedVarInt(self.amt_to_forward)),
-                                       (4, HighZeroBytesDroppedVarInt(self.outgoing_cltv_value)),
-                                       (6, short_channel_id)
-                               }, { });
+                                       (2, HighZeroBytesDroppedVarInt(self.amt_to_forward), required),
+                                       (4, HighZeroBytesDroppedVarInt(self.outgoing_cltv_value), required),
+                                       (6, short_channel_id, required)
+                               });
                        },
-                       OnionHopDataFormat::FinalNode { ref payment_data } => {
+                       OnionHopDataFormat::FinalNode { ref payment_data, ref keysend_preimage } => {
                                if let Some(final_data) = payment_data {
                                        if final_data.total_msat > MAX_VALUE_MSAT { panic!("We should never be sending infinite/overflow onion payments"); }
                                }
                                encode_varint_length_prefixed_tlv!(w, {
-                                       (2, HighZeroBytesDroppedVarInt(self.amt_to_forward)),
-                                       (4, HighZeroBytesDroppedVarInt(self.outgoing_cltv_value))
-                               }, {
-                                       (8, payment_data)
+                                       (2, HighZeroBytesDroppedVarInt(self.amt_to_forward), required),
+                                       (4, HighZeroBytesDroppedVarInt(self.outgoing_cltv_value), required),
+                                       (8, payment_data, option),
+                                       (5482373484, keysend_preimage, option)
                                });
                        },
                }
@@ -1331,12 +1337,14 @@ impl Readable for OnionHopData {
                        let mut cltv_value = HighZeroBytesDroppedVarInt(0u32);
                        let mut short_id: Option<u64> = None;
                        let mut payment_data: Option<FinalOnionHopData> = None;
-                       decode_tlv!(&mut rd, {
-                               (2, amt),
-                               (4, cltv_value)
-                       }, {
-                               (6, short_id),
-                               (8, payment_data)
+                       let mut keysend_preimage: Option<PaymentPreimage> = None;
+                       // The TLV type is chosen to be compatible with lnd and c-lightning.
+                       decode_tlv_stream!(&mut rd, {
+                               (2, amt, required),
+                               (4, cltv_value, required),
+                               (6, short_id, option),
+                               (8, payment_data, option),
+                               (5482373484, keysend_preimage, option)
                        });
                        rd.eat_remaining().map_err(|_| DecodeError::ShortRead)?;
                        let format = if let Some(short_channel_id) = short_id {
@@ -1351,7 +1359,8 @@ impl Readable for OnionHopData {
                                        }
                                }
                                OnionHopDataFormat::FinalNode {
-                                       payment_data
+                                       payment_data,
+                                       keysend_preimage,
                                }
                        };
                        (format, amt.0, cltv_value.0)
@@ -2531,6 +2540,7 @@ mod tests {
                let mut msg = msgs::OnionHopData {
                        format: OnionHopDataFormat::FinalNode {
                                payment_data: None,
+                               keysend_preimage: None,
                        },
                        amt_to_forward: 0x0badf00d01020304,
                        outgoing_cltv_value: 0xffffffff,
@@ -2539,7 +2549,7 @@ mod tests {
                let target_value = hex::decode("1002080badf00d010203040404ffffffff").unwrap();
                assert_eq!(encoded_value, target_value);
                msg = Readable::read(&mut Cursor::new(&target_value[..])).unwrap();
-               if let OnionHopDataFormat::FinalNode { payment_data: None } = msg.format { } else { panic!(); }
+               if let OnionHopDataFormat::FinalNode { payment_data: None, .. } = msg.format { } else { panic!(); }
                assert_eq!(msg.amt_to_forward, 0x0badf00d01020304);
                assert_eq!(msg.outgoing_cltv_value, 0xffffffff);
        }
@@ -2553,6 +2563,7 @@ mod tests {
                                        payment_secret: expected_payment_secret,
                                        total_msat: 0x1badca1f
                                }),
+                               keysend_preimage: None,
                        },
                        amt_to_forward: 0x0badf00d01020304,
                        outgoing_cltv_value: 0xffffffff,
@@ -2565,7 +2576,8 @@ mod tests {
                        payment_data: Some(FinalOnionHopData {
                                payment_secret,
                                total_msat: 0x1badca1f
-                       })
+                       }),
+                       keysend_preimage: None,
                } = msg.format {
                        assert_eq!(payment_secret, expected_payment_secret);
                } else { panic!(); }