Merge pull request #3011 from jkczyz/2024-04-compact-blinded-path-creation
[rust-lightning] / lightning / src / ln / channelmanager.rs
index f751ae7abcf406d43e7484faf1d8c5457bdd2785..51b3fc1539bcd9edc04f355ece36da40598db5b6 100644 (file)
@@ -32,6 +32,7 @@ use bitcoin::secp256k1::Secp256k1;
 use bitcoin::{secp256k1, Sequence};
 
 use crate::blinded_path::{BlindedPath, NodeIdLookUp};
+use crate::blinded_path::message::ForwardNode;
 use crate::blinded_path::payment::{Bolt12OfferContext, Bolt12RefundContext, PaymentConstraints, PaymentContext, ReceiveTlvs};
 use crate::chain;
 use crate::chain::{Confirm, ChannelMonitorUpdateStatus, Watch, BestBlock};
@@ -4084,8 +4085,8 @@ where
        pub(crate) fn test_send_payment_along_path(&self, path: &Path, payment_hash: &PaymentHash, recipient_onion: RecipientOnionFields, total_value: u64, cur_height: u32, payment_id: PaymentId, keysend_preimage: &Option<PaymentPreimage>, session_priv_bytes: [u8; 32]) -> Result<(), APIError> {
                let _lck = self.total_consistency_lock.read().unwrap();
                self.send_payment_along_path(SendAlongPathArgs {
-                       path, payment_hash, recipient_onion, total_value, cur_height, payment_id, keysend_preimage,
-                       session_priv_bytes
+                       path, payment_hash, recipient_onion: &recipient_onion, total_value,
+                       cur_height, payment_id, keysend_preimage, session_priv_bytes
                })
        }
 
@@ -8996,8 +8997,16 @@ where
 
                let peers = self.per_peer_state.read().unwrap()
                        .iter()
-                       .filter(|(_, peer)| peer.lock().unwrap().latest_features.supports_onion_messages())
-                       .map(|(node_id, _)| *node_id)
+                       .map(|(node_id, peer_state)| (node_id, peer_state.lock().unwrap()))
+                       .filter(|(_, peer)| peer.latest_features.supports_onion_messages())
+                       .map(|(node_id, peer)| ForwardNode {
+                               node_id: *node_id,
+                               short_channel_id: peer.channel_by_id
+                                       .iter()
+                                       .filter(|(_, channel)| channel.context().is_usable())
+                                       .min_by_key(|(_, channel)| channel.context().channel_creation_height)
+                                       .and_then(|(_, channel)| channel.context().get_short_channel_id()),
+                       })
                        .collect::<Vec<_>>();
 
                self.router
@@ -9954,11 +9963,14 @@ where
                                                        }
                                                        &mut chan.context
                                                },
-                                               // We retain UnfundedOutboundV1 channel for some time in case
-                                               // peer unexpectedly disconnects, and intends to reconnect again.
-                                               ChannelPhase::UnfundedOutboundV1(_) => {
-                                                       return true;
-                                               },
+                                               // If we get disconnected and haven't yet committed to a funding
+                                               // transaction, we can replay the `open_channel` on reconnection, so don't
+                                               // bother dropping the channel here. However, if we already committed to
+                                               // the funding transaction we don't yet support replaying the funding
+                                               // handshake (and bailing if the peer rejects it), so we force-close in
+                                               // that case.
+                                               ChannelPhase::UnfundedOutboundV1(chan) if chan.is_resumable() => return true,
+                                               ChannelPhase::UnfundedOutboundV1(chan) => &mut chan.context,
                                                // Unfunded inbound channels will always be removed.
                                                ChannelPhase::UnfundedInboundV1(chan) => {
                                                        &mut chan.context