Persist whether an HTLC is blinded in HTLCPreviousHopData.
[rust-lightning] / lightning / src / ln / channelmanager.rs
index 694d7734dba744af356d0b2eaa5466680316e2aa..e3fe74d1a07f9bf67f7a3c83fbd06525c4ebf594 100644 (file)
@@ -119,6 +119,8 @@ pub enum PendingHTLCRouting {
                /// The SCID from the onion that we should forward to. This could be a real SCID or a fake one
                /// generated using `get_fake_scid` from the scid_utils::fake_scid module.
                short_channel_id: u64, // This should be NonZero<u64> eventually when we bump MSRV
+               /// Set if this HTLC is being forwarded within a blinded path.
+               blinded: Option<BlindedForward>,
        },
        /// An HTLC paid to an invoice (supposedly) generated by us.
        /// At this point, we have not checked that the invoice being paid was actually generated by us,
@@ -155,6 +157,16 @@ pub enum PendingHTLCRouting {
        },
 }
 
+/// Information used to forward or fail this HTLC that is being forwarded within a blinded path.
+#[derive(Clone, Copy, Hash, PartialEq, Eq)]
+pub struct BlindedForward {
+       /// The `blinding_point` that was set in the inbound [`msgs::UpdateAddHTLC`], or in the inbound
+       /// onion payload if we're the introduction node. Useful for calculating the next hop's
+       /// [`msgs::UpdateAddHTLC::blinding_point`].
+       pub inbound_blinding_point: PublicKey,
+       // Another field will be added here when we support forwarding as a non-intro node.
+}
+
 /// Full details of an incoming HTLC, including routing info.
 #[derive(Clone)] // See Channel::revoke_and_ack for why, tl;dr: Rust bug
 pub struct PendingHTLCInfo {
@@ -213,6 +225,13 @@ pub(super) enum HTLCForwardInfo {
        },
 }
 
+// Used for failing blinded HTLCs backwards correctly.
+#[derive(Clone, Debug, Hash, PartialEq, Eq)]
+enum BlindedFailure {
+       FromIntroductionNode,
+       // Another variant will be added here for non-intro nodes.
+}
+
 /// Tracks the inbound corresponding to an outbound HTLC
 #[derive(Clone, Debug, Hash, PartialEq, Eq)]
 pub(crate) struct HTLCPreviousHopData {
@@ -222,6 +241,7 @@ pub(crate) struct HTLCPreviousHopData {
        htlc_id: u64,
        incoming_packet_shared_secret: [u8; 32],
        phantom_shared_secret: Option<[u8; 32]>,
+       blinded_failure: Option<BlindedFailure>,
 
        // This field is consumed by `claim_funds_from_hop()` when updating a force-closed backwards
        // channel with a preimage provided by the forward channel.
@@ -4013,8 +4033,10 @@ where
                        })?;
 
                let routing = match payment.forward_info.routing {
-                       PendingHTLCRouting::Forward { onion_packet, .. } => {
-                               PendingHTLCRouting::Forward { onion_packet, short_channel_id: next_hop_scid }
+                       PendingHTLCRouting::Forward { onion_packet, blinded, .. } => {
+                               PendingHTLCRouting::Forward {
+                                       onion_packet, blinded, short_channel_id: next_hop_scid
+                               }
                        },
                        _ => unreachable!() // Only `PendingHTLCRouting::Forward`s are intercepted
                };
@@ -4058,6 +4080,7 @@ where
                                htlc_id: payment.prev_htlc_id,
                                incoming_packet_shared_secret: payment.forward_info.incoming_shared_secret,
                                phantom_shared_secret: None,
+                               blinded_failure: None,
                        });
 
                        let failure_reason = HTLCFailReason::from_failure_code(0x4000 | 10);
@@ -4106,6 +4129,7 @@ where
                                                                                                        htlc_id: prev_htlc_id,
                                                                                                        incoming_packet_shared_secret: incoming_shared_secret,
                                                                                                        phantom_shared_secret: $phantom_ss,
+                                                                                                       blinded_failure: None,
                                                                                                });
 
                                                                                                let reason = if $next_hop_unknown {
@@ -4222,6 +4246,7 @@ where
                                                                                incoming_packet_shared_secret: incoming_shared_secret,
                                                                                // Phantom payments are only PendingHTLCRouting::Receive.
                                                                                phantom_shared_secret: None,
+                                                                               blinded_failure: None,
                                                                        });
                                                                        if let Err(e) = chan.queue_add_htlc(outgoing_amt_msat,
                                                                                payment_hash, outgoing_cltv_value, htlc_source.clone(),
@@ -4305,6 +4330,7 @@ where
                                                                                htlc_id: prev_htlc_id,
                                                                                incoming_packet_shared_secret: incoming_shared_secret,
                                                                                phantom_shared_secret,
+                                                                               blinded_failure: None,
                                                                        },
                                                                        // We differentiate the received value from the sender intended value
                                                                        // if possible so that we don't prematurely mark MPP payments complete
@@ -4335,6 +4361,7 @@ where
                                                                                                htlc_id: $htlc.prev_hop.htlc_id,
                                                                                                incoming_packet_shared_secret: $htlc.prev_hop.incoming_packet_shared_secret,
                                                                                                phantom_shared_secret,
+                                                                                               blinded_failure: None,
                                                                                        }), payment_hash,
                                                                                        HTLCFailReason::reason(0x4000 | 15, htlc_msat_height_data),
                                                                                        HTLCDestination::FailedPayment { payment_hash: $payment_hash },
@@ -6584,6 +6611,7 @@ where
                                                                                        htlc_id: prev_htlc_id,
                                                                                        incoming_packet_shared_secret: forward_info.incoming_shared_secret,
                                                                                        phantom_shared_secret: None,
+                                                                                       blinded_failure: None,
                                                                                });
 
                                                                                failed_intercept_forwards.push((htlc_source, forward_info.payment_hash,
@@ -8180,6 +8208,7 @@ where
                                                incoming_packet_shared_secret: htlc.forward_info.incoming_shared_secret,
                                                phantom_shared_secret: None,
                                                outpoint: htlc.prev_funding_outpoint,
+                                               blinded_failure: None,
                                        });
 
                                        let requested_forward_scid /* intercept scid */ = match htlc.forward_info.routing {
@@ -9143,9 +9172,14 @@ impl_writeable_tlv_based!(PhantomRouteHints, {
        (6, real_node_pubkey, required),
 });
 
+impl_writeable_tlv_based!(BlindedForward, {
+       (0, inbound_blinding_point, required),
+});
+
 impl_writeable_tlv_based_enum!(PendingHTLCRouting,
        (0, Forward) => {
                (0, onion_packet, required),
+               (1, blinded, option),
                (2, short_channel_id, required),
        },
        (1, Receive) => {
@@ -9247,10 +9281,15 @@ impl_writeable_tlv_based_enum!(PendingHTLCStatus, ;
        (1, Fail),
 );
 
+impl_writeable_tlv_based_enum!(BlindedFailure,
+       (0, FromIntroductionNode) => {}, ;
+);
+
 impl_writeable_tlv_based!(HTLCPreviousHopData, {
        (0, short_channel_id, required),
        (1, phantom_shared_secret, option),
        (2, outpoint, required),
+       (3, blinded_failure, option),
        (4, htlc_id, required),
        (6, incoming_packet_shared_secret, required),
        (7, user_channel_id, option),