Support parsing blinded non-intro onion receive payloads.
[rust-lightning] / lightning / src / ln / msgs.rs
index 2d871b354a26d5643bece3211ddaa9986978bebd..db7579039cce848aafdeb90941a12d29d37a6222 100644 (file)
@@ -52,7 +52,7 @@ use core::fmt::Display;
 use crate::io::{self, Cursor, Read};
 use crate::io_extras::read_to_end;
 
-use crate::events::MessageSendEventsProvider;
+use crate::events::{EventsProvider, MessageSendEventsProvider};
 use crate::util::chacha20poly1305rfc::ChaChaPolyReadAdapter;
 use crate::util::logger;
 use crate::util::ser::{LengthReadable, LengthReadableArgs, Readable, ReadableArgs, Writeable, Writer, WithoutLength, FixedLengthReader, HighZeroBytesDroppedBigSize, Hostname, TransactionU16LenLimited, BigSize};
@@ -1631,7 +1631,7 @@ pub trait RoutingMessageHandler : MessageSendEventsProvider {
 }
 
 /// A handler for received [`OnionMessage`]s and for providing generated ones to send.
-pub trait OnionMessageHandler {
+pub trait OnionMessageHandler: EventsProvider {
        /// Handle an incoming `onion_message` message from the given peer.
        fn handle_onion_message(&self, peer_node_id: &PublicKey, msg: &OnionMessage);
 
@@ -1650,6 +1650,10 @@ pub trait OnionMessageHandler {
        /// drop and refuse to forward onion messages to this peer.
        fn peer_disconnected(&self, their_node_id: &PublicKey);
 
+       /// Performs actions that should happen roughly every ten seconds after startup. Allows handlers
+       /// to drop any buffered onion messages intended for prospective peers.
+       fn timer_tick_occurred(&self);
+
        // Handler information:
        /// Gets the node feature flags which this handler itself supports. All available handlers are
        /// queried similarly and their feature flags are OR'd together to form the [`NodeFeatures`]
@@ -1709,7 +1713,7 @@ mod fuzzy_internal_msgs {
                        outgoing_cltv_value: u32,
                        payment_secret: PaymentSecret,
                        payment_constraints: PaymentConstraints,
-                       intro_node_blinding_point: PublicKey,
+                       intro_node_blinding_point: Option<PublicKey>,
                }
        }
 
@@ -2315,8 +2319,10 @@ impl Writeable for OutboundOnionPayload {
        }
 }
 
-impl<NS: Deref> ReadableArgs<&NS> for InboundOnionPayload where NS::Target: NodeSigner {
-       fn read<R: Read>(r: &mut R, node_signer: &NS) -> Result<Self, DecodeError> {
+impl<NS: Deref> ReadableArgs<(Option<PublicKey>, &NS)> for InboundOnionPayload where NS::Target: NodeSigner {
+       fn read<R: Read>(r: &mut R, args: (Option<PublicKey>, &NS)) -> Result<Self, DecodeError> {
+               let (update_add_blinding_point, node_signer) = args;
+
                let mut amt = None;
                let mut cltv_value = None;
                let mut short_id: Option<u64> = None;
@@ -2350,8 +2356,11 @@ impl<NS: Deref> ReadableArgs<&NS> for InboundOnionPayload where NS::Target: Node
                });
 
                if amt.unwrap_or(0) > MAX_VALUE_MSAT { return Err(DecodeError::InvalidValue) }
+               if intro_node_blinding_point.is_some() && update_add_blinding_point.is_some() {
+                       return Err(DecodeError::InvalidValue)
+               }
 
-               if let Some(blinding_point) = intro_node_blinding_point {
+               if let Some(blinding_point) = intro_node_blinding_point.or(update_add_blinding_point) {
                        if short_id.is_some() || payment_data.is_some() || payment_metadata.is_some() {
                                return Err(DecodeError::InvalidValue)
                        }
@@ -2373,7 +2382,7 @@ impl<NS: Deref> ReadableArgs<&NS> for InboundOnionPayload where NS::Target: Node
                                                payment_relay,
                                                payment_constraints,
                                                features,
-                                               intro_node_blinding_point: blinding_point,
+                                               intro_node_blinding_point: intro_node_blinding_point.ok_or(DecodeError::InvalidValue)?,
                                        })
                                },
                                ChaChaPolyReadAdapter { readable: BlindedPaymentTlvs::Receive(ReceiveTlvs {
@@ -2386,7 +2395,7 @@ impl<NS: Deref> ReadableArgs<&NS> for InboundOnionPayload where NS::Target: Node
                                                outgoing_cltv_value: cltv_value.ok_or(DecodeError::InvalidValue)?,
                                                payment_secret,
                                                payment_constraints,
-                                               intro_node_blinding_point: blinding_point,
+                                               intro_node_blinding_point,
                                        })
                                },
                        }
@@ -3983,7 +3992,7 @@ mod tests {
                assert_eq!(encoded_value, target_value);
 
                let node_signer = test_utils::TestKeysInterface::new(&[42; 32], Network::Testnet);
-               let inbound_msg = ReadableArgs::read(&mut Cursor::new(&target_value[..]), &&node_signer).unwrap();
+               let inbound_msg = ReadableArgs::read(&mut Cursor::new(&target_value[..]), (None, &&node_signer)).unwrap();
                if let msgs::InboundOnionPayload::Forward {
                        short_channel_id, amt_to_forward, outgoing_cltv_value
                } = inbound_msg {
@@ -4008,7 +4017,7 @@ mod tests {
                assert_eq!(encoded_value, target_value);
 
                let node_signer = test_utils::TestKeysInterface::new(&[42; 32], Network::Testnet);
-               let inbound_msg = ReadableArgs::read(&mut Cursor::new(&target_value[..]), &&node_signer).unwrap();
+               let inbound_msg = ReadableArgs::read(&mut Cursor::new(&target_value[..]), (None, &&node_signer)).unwrap();
                if let msgs::InboundOnionPayload::Receive {
                        payment_data: None, amt_msat, outgoing_cltv_value, ..
                } = inbound_msg {
@@ -4036,7 +4045,7 @@ mod tests {
                assert_eq!(encoded_value, target_value);
 
                let node_signer = test_utils::TestKeysInterface::new(&[42; 32], Network::Testnet);
-               let inbound_msg = ReadableArgs::read(&mut Cursor::new(&target_value[..]), &&node_signer).unwrap();
+               let inbound_msg = ReadableArgs::read(&mut Cursor::new(&target_value[..]), (None, &&node_signer)).unwrap();
                if let msgs::InboundOnionPayload::Receive {
                        payment_data: Some(FinalOnionHopData {
                                payment_secret,
@@ -4072,7 +4081,7 @@ mod tests {
                };
                let encoded_value = msg.encode();
                let node_signer = test_utils::TestKeysInterface::new(&[42; 32], Network::Testnet);
-               assert!(msgs::InboundOnionPayload::read(&mut Cursor::new(&encoded_value[..]), &&node_signer).is_err());
+               assert!(msgs::InboundOnionPayload::read(&mut Cursor::new(&encoded_value[..]), (None, &&node_signer)).is_err());
                let good_type_range_tlvs = vec![
                        ((1 << 16) - 3, vec![42]),
                        ((1 << 16) - 1, vec![42; 32]),
@@ -4081,7 +4090,7 @@ mod tests {
                        *custom_tlvs = good_type_range_tlvs.clone();
                }
                let encoded_value = msg.encode();
-               let inbound_msg = ReadableArgs::read(&mut Cursor::new(&encoded_value[..]), &&node_signer).unwrap();
+               let inbound_msg = ReadableArgs::read(&mut Cursor::new(&encoded_value[..]), (None, &&node_signer)).unwrap();
                match inbound_msg {
                        msgs::InboundOnionPayload::Receive { custom_tlvs, .. } => assert!(custom_tlvs.is_empty()),
                        _ => panic!(),
@@ -4106,7 +4115,7 @@ mod tests {
                let target_value = <Vec<u8>>::from_hex("2e02080badf00d010203040404ffffffffff0000000146c6616b021234ff0000000146c6616f084242424242424242").unwrap();
                assert_eq!(encoded_value, target_value);
                let node_signer = test_utils::TestKeysInterface::new(&[42; 32], Network::Testnet);
-               let inbound_msg: msgs::InboundOnionPayload = ReadableArgs::read(&mut Cursor::new(&target_value[..]), &&node_signer).unwrap();
+               let inbound_msg: msgs::InboundOnionPayload = ReadableArgs::read(&mut Cursor::new(&target_value[..]), (None, &&node_signer)).unwrap();
                if let msgs::InboundOnionPayload::Receive {
                        payment_data: None,
                        payment_metadata: None,
@@ -4271,8 +4280,8 @@ mod tests {
                let mut rd = Cursor::new(&big_payload[..]);
 
                let node_signer = test_utils::TestKeysInterface::new(&[42; 32], Network::Testnet);
-               <msgs::InboundOnionPayload as ReadableArgs<&&test_utils::TestKeysInterface>>
-                       ::read(&mut rd, &&node_signer).unwrap();
+               <msgs::InboundOnionPayload as ReadableArgs<(Option<PublicKey>, &&test_utils::TestKeysInterface)>>
+                       ::read(&mut rd, (None, &&node_signer)).unwrap();
        }
        // see above test, needs to be a separate method for use of the serialization macros.
        fn encode_big_payload() -> Result<Vec<u8>, io::Error> {