Persist whether an HTLC is blinded in HTLCPreviousHopData.
[rust-lightning] / lightning / src / ln / channelmanager.rs
index d57b6fe951419a0024a9c8aecc3a22ac5051053f..e3fe74d1a07f9bf67f7a3c83fbd06525c4ebf594 100644 (file)
@@ -66,7 +66,8 @@ use crate::offers::offer::{DerivedMetadata, Offer, OfferBuilder};
 use crate::offers::parse::Bolt12SemanticError;
 use crate::offers::refund::{Refund, RefundBuilder};
 use crate::onion_message::{Destination, OffersMessage, OffersMessageHandler, PendingOnionMessage, new_pending_onion_message};
-use crate::sign::{EntropySource, KeysManager, NodeSigner, Recipient, SignerProvider, WriteableEcdsaChannelSigner};
+use crate::sign::{EntropySource, KeysManager, NodeSigner, Recipient, SignerProvider};
+use crate::sign::ecdsa::WriteableEcdsaChannelSigner;
 use crate::util::config::{UserConfig, ChannelConfig, ChannelConfigUpdate};
 use crate::util::wakers::{Future, Notifier};
 use crate::util::scid_utils::fake_scid;
@@ -118,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,
@@ -154,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 {
@@ -212,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 {
@@ -221,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.
@@ -922,7 +943,7 @@ pub trait AChannelManager {
        /// A type implementing [`WriteableEcdsaChannelSigner`].
        type Signer: WriteableEcdsaChannelSigner + Sized;
        /// A type implementing [`SignerProvider`] for [`Self::Signer`].
-       type SignerProvider: SignerProvider<Signer = Self::Signer> + ?Sized;
+       type SignerProvider: SignerProvider<EcdsaSigner= Self::Signer> + ?Sized;
        /// A type that may be dereferenced to [`Self::SignerProvider`].
        type SP: Deref<Target = Self::SignerProvider>;
        /// A type implementing [`FeeEstimator`].
@@ -944,7 +965,7 @@ pub trait AChannelManager {
 impl<M: Deref, T: Deref, ES: Deref, NS: Deref, SP: Deref, F: Deref, R: Deref, L: Deref> AChannelManager
 for ChannelManager<M, T, ES, NS, SP, F, R, L>
 where
-       M::Target: chain::Watch<<SP::Target as SignerProvider>::Signer>,
+       M::Target: chain::Watch<<SP::Target as SignerProvider>::EcdsaSigner>,
        T::Target: BroadcasterInterface,
        ES::Target: EntropySource,
        NS::Target: NodeSigner,
@@ -961,7 +982,7 @@ where
        type ES = ES;
        type NodeSigner = NS::Target;
        type NS = NS;
-       type Signer = <SP::Target as SignerProvider>::Signer;
+       type Signer = <SP::Target as SignerProvider>::EcdsaSigner;
        type SignerProvider = SP::Target;
        type SP = SP;
        type FeeEstimator = F::Target;
@@ -1069,7 +1090,7 @@ where
 //
 pub struct ChannelManager<M: Deref, T: Deref, ES: Deref, NS: Deref, SP: Deref, F: Deref, R: Deref, L: Deref>
 where
-       M::Target: chain::Watch<<SP::Target as SignerProvider>::Signer>,
+       M::Target: chain::Watch<<SP::Target as SignerProvider>::EcdsaSigner>,
        T::Target: BroadcasterInterface,
        ES::Target: EntropySource,
        NS::Target: NodeSigner,
@@ -2284,7 +2305,7 @@ macro_rules! process_events_body {
 
 impl<M: Deref, T: Deref, ES: Deref, NS: Deref, SP: Deref, F: Deref, R: Deref, L: Deref> ChannelManager<M, T, ES, NS, SP, F, R, L>
 where
-       M::Target: chain::Watch<<SP::Target as SignerProvider>::Signer>,
+       M::Target: chain::Watch<<SP::Target as SignerProvider>::EcdsaSigner>,
        T::Target: BroadcasterInterface,
        ES::Target: EntropySource,
        NS::Target: NodeSigner,
@@ -4012,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
                };
@@ -4057,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);
@@ -4105,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 {
@@ -4221,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(),
@@ -4304,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
@@ -4334,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 },
@@ -6583,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,
@@ -7803,7 +7832,7 @@ where
 
 impl<M: Deref, T: Deref, ES: Deref, NS: Deref, SP: Deref, F: Deref, R: Deref, L: Deref> MessageSendEventsProvider for ChannelManager<M, T, ES, NS, SP, F, R, L>
 where
-       M::Target: chain::Watch<<SP::Target as SignerProvider>::Signer>,
+       M::Target: chain::Watch<<SP::Target as SignerProvider>::EcdsaSigner>,
        T::Target: BroadcasterInterface,
        ES::Target: EntropySource,
        NS::Target: NodeSigner,
@@ -7865,7 +7894,7 @@ where
 
 impl<M: Deref, T: Deref, ES: Deref, NS: Deref, SP: Deref, F: Deref, R: Deref, L: Deref> EventsProvider for ChannelManager<M, T, ES, NS, SP, F, R, L>
 where
-       M::Target: chain::Watch<<SP::Target as SignerProvider>::Signer>,
+       M::Target: chain::Watch<<SP::Target as SignerProvider>::EcdsaSigner>,
        T::Target: BroadcasterInterface,
        ES::Target: EntropySource,
        NS::Target: NodeSigner,
@@ -7886,7 +7915,7 @@ where
 
 impl<M: Deref, T: Deref, ES: Deref, NS: Deref, SP: Deref, F: Deref, R: Deref, L: Deref> chain::Listen for ChannelManager<M, T, ES, NS, SP, F, R, L>
 where
-       M::Target: chain::Watch<<SP::Target as SignerProvider>::Signer>,
+       M::Target: chain::Watch<<SP::Target as SignerProvider>::EcdsaSigner>,
        T::Target: BroadcasterInterface,
        ES::Target: EntropySource,
        NS::Target: NodeSigner,
@@ -7928,7 +7957,7 @@ where
 
 impl<M: Deref, T: Deref, ES: Deref, NS: Deref, SP: Deref, F: Deref, R: Deref, L: Deref> chain::Confirm for ChannelManager<M, T, ES, NS, SP, F, R, L>
 where
-       M::Target: chain::Watch<<SP::Target as SignerProvider>::Signer>,
+       M::Target: chain::Watch<<SP::Target as SignerProvider>::EcdsaSigner>,
        T::Target: BroadcasterInterface,
        ES::Target: EntropySource,
        NS::Target: NodeSigner,
@@ -7996,14 +8025,17 @@ where
                });
        }
 
-       fn get_relevant_txids(&self) -> Vec<(Txid, Option<BlockHash>)> {
+       fn get_relevant_txids(&self) -> Vec<(Txid, u32, Option<BlockHash>)> {
                let mut res = Vec::with_capacity(self.short_to_chan_info.read().unwrap().len());
                for (_cp_id, peer_state_mutex) in self.per_peer_state.read().unwrap().iter() {
                        let mut peer_state_lock = peer_state_mutex.lock().unwrap();
                        let peer_state = &mut *peer_state_lock;
                        for chan in peer_state.channel_by_id.values().filter_map(|phase| if let ChannelPhase::Funded(chan) = phase { Some(chan) } else { None }) {
-                               if let (Some(funding_txo), Some(block_hash)) = (chan.context.get_funding_txo(), chan.context.get_funding_tx_confirmed_in()) {
-                                       res.push((funding_txo.txid, Some(block_hash)));
+                               let txid_opt = chan.context.get_funding_txo();
+                               let height_opt = chan.context.get_funding_tx_confirmation_height();
+                               let hash_opt = chan.context.get_funding_tx_confirmed_in();
+                               if let (Some(funding_txo), Some(conf_height), Some(block_hash)) = (txid_opt, height_opt, hash_opt) {
+                                       res.push((funding_txo.txid, conf_height, Some(block_hash)));
                                }
                        }
                }
@@ -8026,7 +8058,7 @@ where
 
 impl<M: Deref, T: Deref, ES: Deref, NS: Deref, SP: Deref, F: Deref, R: Deref, L: Deref> ChannelManager<M, T, ES, NS, SP, F, R, L>
 where
-       M::Target: chain::Watch<<SP::Target as SignerProvider>::Signer>,
+       M::Target: chain::Watch<<SP::Target as SignerProvider>::EcdsaSigner>,
        T::Target: BroadcasterInterface,
        ES::Target: EntropySource,
        NS::Target: NodeSigner,
@@ -8176,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 {
@@ -8270,7 +8303,7 @@ where
 impl<M: Deref, T: Deref, ES: Deref, NS: Deref, SP: Deref, F: Deref, R: Deref, L: Deref>
        ChannelMessageHandler for ChannelManager<M, T, ES, NS, SP, F, R, L>
 where
-       M::Target: chain::Watch<<SP::Target as SignerProvider>::Signer>,
+       M::Target: chain::Watch<<SP::Target as SignerProvider>::EcdsaSigner>,
        T::Target: BroadcasterInterface,
        ES::Target: EntropySource,
        NS::Target: NodeSigner,
@@ -8824,7 +8857,7 @@ where
 impl<M: Deref, T: Deref, ES: Deref, NS: Deref, SP: Deref, F: Deref, R: Deref, L: Deref>
 OffersMessageHandler for ChannelManager<M, T, ES, NS, SP, F, R, L>
 where
-       M::Target: chain::Watch<<SP::Target as SignerProvider>::Signer>,
+       M::Target: chain::Watch<<SP::Target as SignerProvider>::EcdsaSigner>,
        T::Target: BroadcasterInterface,
        ES::Target: EntropySource,
        NS::Target: NodeSigner,
@@ -9139,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) => {
@@ -9243,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),
@@ -9421,7 +9464,7 @@ impl_writeable_tlv_based!(PendingInboundPayment, {
 
 impl<M: Deref, T: Deref, ES: Deref, NS: Deref, SP: Deref, F: Deref, R: Deref, L: Deref> Writeable for ChannelManager<M, T, ES, NS, SP, F, R, L>
 where
-       M::Target: chain::Watch<<SP::Target as SignerProvider>::Signer>,
+       M::Target: chain::Watch<<SP::Target as SignerProvider>::EcdsaSigner>,
        T::Target: BroadcasterInterface,
        ES::Target: EntropySource,
        NS::Target: NodeSigner,
@@ -9725,7 +9768,7 @@ impl_writeable_tlv_based_enum!(ChannelShutdownState,
 /// [`ChainMonitor`]: crate::chain::chainmonitor::ChainMonitor
 pub struct ChannelManagerReadArgs<'a, M: Deref, T: Deref, ES: Deref, NS: Deref, SP: Deref, F: Deref, R: Deref, L: Deref>
 where
-       M::Target: chain::Watch<<SP::Target as SignerProvider>::Signer>,
+       M::Target: chain::Watch<<SP::Target as SignerProvider>::EcdsaSigner>,
        T::Target: BroadcasterInterface,
        ES::Target: EntropySource,
        NS::Target: NodeSigner,
@@ -9784,13 +9827,13 @@ where
        /// this struct.
        ///
        /// This is not exported to bindings users because we have no HashMap bindings
-       pub channel_monitors: HashMap<OutPoint, &'a mut ChannelMonitor<<SP::Target as SignerProvider>::Signer>>,
+       pub channel_monitors: HashMap<OutPoint, &'a mut ChannelMonitor<<SP::Target as SignerProvider>::EcdsaSigner>>,
 }
 
 impl<'a, M: Deref, T: Deref, ES: Deref, NS: Deref, SP: Deref, F: Deref, R: Deref, L: Deref>
                ChannelManagerReadArgs<'a, M, T, ES, NS, SP, F, R, L>
 where
-       M::Target: chain::Watch<<SP::Target as SignerProvider>::Signer>,
+       M::Target: chain::Watch<<SP::Target as SignerProvider>::EcdsaSigner>,
        T::Target: BroadcasterInterface,
        ES::Target: EntropySource,
        NS::Target: NodeSigner,
@@ -9803,7 +9846,7 @@ where
        /// HashMap for you. This is primarily useful for C bindings where it is not practical to
        /// populate a HashMap directly from C.
        pub fn new(entropy_source: ES, node_signer: NS, signer_provider: SP, fee_estimator: F, chain_monitor: M, tx_broadcaster: T, router: R, logger: L, default_config: UserConfig,
-                       mut channel_monitors: Vec<&'a mut ChannelMonitor<<SP::Target as SignerProvider>::Signer>>) -> Self {
+                       mut channel_monitors: Vec<&'a mut ChannelMonitor<<SP::Target as SignerProvider>::EcdsaSigner>>) -> Self {
                Self {
                        entropy_source, node_signer, signer_provider, fee_estimator, chain_monitor, tx_broadcaster, router, logger, default_config,
                        channel_monitors: channel_monitors.drain(..).map(|monitor| { (monitor.get_funding_txo().0, monitor) }).collect()
@@ -9816,7 +9859,7 @@ where
 impl<'a, M: Deref, T: Deref, ES: Deref, NS: Deref, SP: Deref, F: Deref, R: Deref, L: Deref>
        ReadableArgs<ChannelManagerReadArgs<'a, M, T, ES, NS, SP, F, R, L>> for (BlockHash, Arc<ChannelManager<M, T, ES, NS, SP, F, R, L>>)
 where
-       M::Target: chain::Watch<<SP::Target as SignerProvider>::Signer>,
+       M::Target: chain::Watch<<SP::Target as SignerProvider>::EcdsaSigner>,
        T::Target: BroadcasterInterface,
        ES::Target: EntropySource,
        NS::Target: NodeSigner,
@@ -9834,7 +9877,7 @@ where
 impl<'a, M: Deref, T: Deref, ES: Deref, NS: Deref, SP: Deref, F: Deref, R: Deref, L: Deref>
        ReadableArgs<ChannelManagerReadArgs<'a, M, T, ES, NS, SP, F, R, L>> for (BlockHash, ChannelManager<M, T, ES, NS, SP, F, R, L>)
 where
-       M::Target: chain::Watch<<SP::Target as SignerProvider>::Signer>,
+       M::Target: chain::Watch<<SP::Target as SignerProvider>::EcdsaSigner>,
        T::Target: BroadcasterInterface,
        ES::Target: EntropySource,
        NS::Target: NodeSigner,