Merge pull request #1678 from TheBlueMatt/2022-08-funding-locked-mon-persist-fail
[rust-lightning] / lightning / src / onion_message / messenger.rs
index b9da9246cb103bcf44eb82050bd5870f45521ae5..3677efda420cc8663914512ea38c732216de8f59 100644 (file)
@@ -16,6 +16,7 @@ use bitcoin::hashes::sha256::Hash as Sha256;
 use bitcoin::secp256k1::{self, PublicKey, Scalar, Secp256k1, SecretKey};
 
 use chain::keysinterface::{InMemorySigner, KeysInterface, KeysManager, Recipient, Sign};
+use ln::features::{InitFeatures, NodeFeatures};
 use ln::msgs::{self, OnionMessageHandler};
 use ln::onion_utils;
 use super::blinded_route::{BlindedRoute, ForwardTlvs, ReceiveTlvs};
@@ -23,6 +24,7 @@ use super::packet::{BIG_PACKET_HOP_DATA_LEN, ForwardControlTlvs, Packet, Payload
 use super::utils;
 use util::events::OnionMessageProvider;
 use util::logger::Logger;
+use util::ser::Writeable;
 
 use core::ops::Deref;
 use sync::{Arc, Mutex};
@@ -69,7 +71,7 @@ use prelude::*;
 /// // Create a blinded route to yourself, for someone to send an onion message to.
 /// # let your_node_id = hop_node_id1;
 /// let hops = [hop_node_id3, hop_node_id4, your_node_id];
-/// let blinded_route = BlindedRoute::new::<InMemorySigner, _, _>(&hops, &keys_manager, &secp_ctx).unwrap();
+/// let blinded_route = BlindedRoute::new(&hops, &keys_manager, &secp_ctx).unwrap();
 ///
 /// // Send an empty onion message to a blinded route.
 /// # let intermediate_hops = [hop_node_id1, hop_node_id2];
@@ -112,7 +114,7 @@ impl Destination {
 /// Errors that may occur when [sending an onion message].
 ///
 /// [sending an onion message]: OnionMessenger::send_onion_message
-#[derive(Debug, PartialEq)]
+#[derive(Debug, PartialEq, Eq)]
 pub enum SendError {
        /// Errored computing onion message packet keys.
        Secp256k1(secp256k1::Error),
@@ -124,6 +126,8 @@ pub enum SendError {
        TooFewBlindedHops,
        /// Our next-hop peer was offline or does not support onion message forwarding.
        InvalidFirstHop,
+       /// Our next-hop peer's buffer was full or our total outbound buffer was full.
+       BufferFull,
 }
 
 impl<Signer: Sign, K: Deref, L: Deref> OnionMessenger<Signer, K, L>
@@ -171,6 +175,7 @@ impl<Signer: Sign, K: Deref, L: Deref> OnionMessenger<Signer, K, L>
                        packet_payloads, packet_keys, prng_seed).map_err(|()| SendError::TooBigPacket)?;
 
                let mut pending_per_peer_msgs = self.pending_messages.lock().unwrap();
+               if outbound_buffer_full(&introduction_node_id, &pending_per_peer_msgs) { return Err(SendError::BufferFull) }
                match pending_per_peer_msgs.entry(introduction_node_id) {
                        hash_map::Entry::Vacant(_) => Err(SendError::InvalidFirstHop),
                        hash_map::Entry::Occupied(mut e) => {
@@ -193,6 +198,29 @@ impl<Signer: Sign, K: Deref, L: Deref> OnionMessenger<Signer, K, L>
        }
 }
 
+fn outbound_buffer_full(peer_node_id: &PublicKey, buffer: &HashMap<PublicKey, VecDeque<msgs::OnionMessage>>) -> bool {
+       const MAX_TOTAL_BUFFER_SIZE: usize = (1 << 20) * 128;
+       const MAX_PER_PEER_BUFFER_SIZE: usize = (1 << 10) * 256;
+       let mut total_buffered_bytes = 0;
+       let mut peer_buffered_bytes = 0;
+       for (pk, peer_buf) in buffer {
+               for om in peer_buf {
+                       let om_len = om.serialized_length();
+                       if pk == peer_node_id {
+                               peer_buffered_bytes += om_len;
+                       }
+                       total_buffered_bytes += om_len;
+
+                       if total_buffered_bytes >= MAX_TOTAL_BUFFER_SIZE ||
+                               peer_buffered_bytes >= MAX_PER_PEER_BUFFER_SIZE
+                       {
+                               return true
+                       }
+               }
+       }
+       false
+}
+
 impl<Signer: Sign, K: Deref, L: Deref> OnionMessageHandler for OnionMessenger<Signer, K, L>
        where K::Target: KeysInterface<Signer = Signer>,
              L::Target: Logger,
@@ -255,8 +283,34 @@ impl<Signer: Sign, K: Deref, L: Deref> OnionMessageHandler for OnionMessenger<Si
                                        hop_data: new_packet_bytes,
                                        hmac: next_hop_hmac,
                                };
+                               let onion_message = msgs::OnionMessage {
+                                       blinding_point: match next_blinding_override {
+                                               Some(blinding_point) => blinding_point,
+                                               None => {
+                                                       let blinding_factor = {
+                                                               let mut sha = Sha256::engine();
+                                                               sha.input(&msg.blinding_point.serialize()[..]);
+                                                               sha.input(control_tlvs_ss.as_ref());
+                                                               Sha256::from_engine(sha).into_inner()
+                                                       };
+                                                       let next_blinding_point = msg.blinding_point;
+                                                       match next_blinding_point.mul_tweak(&self.secp_ctx, &Scalar::from_be_bytes(blinding_factor).unwrap()) {
+                                                               Ok(bp) => bp,
+                                                               Err(e) => {
+                                                                       log_trace!(self.logger, "Failed to compute next blinding point: {}", e);
+                                                                       return
+                                                               }
+                                                       }
+                                               },
+                                       },
+                                       onion_routing_packet: outgoing_packet,
+                               };
 
                                let mut pending_per_peer_msgs = self.pending_messages.lock().unwrap();
+                               if outbound_buffer_full(&next_node_id, &pending_per_peer_msgs) {
+                                       log_trace!(self.logger, "Dropping forwarded onion message to peer {:?}: outbound buffer full", next_node_id);
+                                       return
+                               }
 
                                #[cfg(fuzzing)]
                                pending_per_peer_msgs.entry(next_node_id).or_insert_with(VecDeque::new);
@@ -267,30 +321,7 @@ impl<Signer: Sign, K: Deref, L: Deref> OnionMessageHandler for OnionMessenger<Si
                                                return
                                        },
                                        hash_map::Entry::Occupied(mut e) => {
-                                               e.get_mut().push_back(
-                                                       msgs::OnionMessage {
-                                                               blinding_point: match next_blinding_override {
-                                                                       Some(blinding_point) => blinding_point,
-                                                                       None => {
-                                                                               let blinding_factor = {
-                                                                                       let mut sha = Sha256::engine();
-                                                                                       sha.input(&msg.blinding_point.serialize()[..]);
-                                                                                       sha.input(control_tlvs_ss.as_ref());
-                                                                                       Sha256::from_engine(sha).into_inner()
-                                                                               };
-                                                                               let next_blinding_point = msg.blinding_point;
-                                                                               match next_blinding_point.mul_tweak(&self.secp_ctx, &Scalar::from_be_bytes(blinding_factor).unwrap()) {
-                                                                                       Ok(bp) => bp,
-                                                                                       Err(e) => {
-                                                                                               log_trace!(self.logger, "Failed to compute next blinding point: {}", e);
-                                                                                               return
-                                                                                       }
-                                                                               }
-                                                                       },
-                                                               },
-                                                               onion_routing_packet: outgoing_packet,
-                                                       },
-                                               );
+                                               e.get_mut().push_back(onion_message);
                                                log_trace!(self.logger, "Forwarding an onion message to peer {}", next_node_id);
                                        }
                                };
@@ -304,17 +335,30 @@ impl<Signer: Sign, K: Deref, L: Deref> OnionMessageHandler for OnionMessenger<Si
                };
        }
 
-       fn peer_connected(&self, their_node_id: &PublicKey, init: &msgs::Init) {
+       fn peer_connected(&self, their_node_id: &PublicKey, init: &msgs::Init) -> Result<(), ()> {
                if init.features.supports_onion_messages() {
                        let mut peers = self.pending_messages.lock().unwrap();
                        peers.insert(their_node_id.clone(), VecDeque::new());
                }
+               Ok(())
        }
 
        fn peer_disconnected(&self, their_node_id: &PublicKey, _no_connection_possible: bool) {
                let mut pending_msgs = self.pending_messages.lock().unwrap();
                pending_msgs.remove(their_node_id);
        }
+
+       fn provided_node_features(&self) -> NodeFeatures {
+               let mut features = NodeFeatures::empty();
+               features.set_onion_messages_optional();
+               features
+       }
+
+       fn provided_init_features(&self, _their_node_id: &PublicKey) -> InitFeatures {
+               let mut features = InitFeatures::empty();
+               features.set_onion_messages_optional();
+               features
+       }
 }
 
 impl<Signer: Sign, K: Deref, L: Deref> OnionMessageProvider for OnionMessenger<Signer, K, L>
@@ -335,14 +379,18 @@ impl<Signer: Sign, K: Deref, L: Deref> OnionMessageProvider for OnionMessenger<S
 /// Useful for simplifying the parameters of [`SimpleArcChannelManager`] and
 /// [`SimpleArcPeerManager`]. See their docs for more details.
 ///
-///[`SimpleArcChannelManager`]: crate::ln::channelmanager::SimpleArcChannelManager
-///[`SimpleArcPeerManager`]: crate::ln::peer_handler::SimpleArcPeerManager
+/// (C-not exported) as `Arc`s don't make sense in bindings.
+///
+/// [`SimpleArcChannelManager`]: crate::ln::channelmanager::SimpleArcChannelManager
+/// [`SimpleArcPeerManager`]: crate::ln::peer_handler::SimpleArcPeerManager
 pub type SimpleArcOnionMessenger<L> = OnionMessenger<InMemorySigner, Arc<KeysManager>, Arc<L>>;
 /// Useful for simplifying the parameters of [`SimpleRefChannelManager`] and
 /// [`SimpleRefPeerManager`]. See their docs for more details.
 ///
-///[`SimpleRefChannelManager`]: crate::ln::channelmanager::SimpleRefChannelManager
-///[`SimpleRefPeerManager`]: crate::ln::peer_handler::SimpleRefPeerManager
+/// (C-not exported) as general type aliases don't make sense in bindings.
+///
+/// [`SimpleRefChannelManager`]: crate::ln::channelmanager::SimpleRefChannelManager
+/// [`SimpleRefPeerManager`]: crate::ln::peer_handler::SimpleRefPeerManager
 pub type SimpleRefOnionMessenger<'a, 'b, L> = OnionMessenger<InMemorySigner, &'a KeysManager, &'b L>;
 
 /// Construct onion packet payloads and keys for sending an onion message along the given