]> git.bitcoin.ninja Git - rust-lightning/commitdiff
Add BlindedPaymentPath type, to disambiguate from message paths.
authorValentine Wallace <vwallace@protonmail.com>
Mon, 5 Aug 2024 22:18:26 +0000 (15:18 -0700)
committerValentine Wallace <vwallace@protonmail.com>
Thu, 15 Aug 2024 17:03:56 +0000 (13:03 -0400)
Next up, we'll add a BlindedMessagePath type so the API is clear which type of
path is expected in each context.

21 files changed:
fuzz/src/chanmon_consistency.rs
fuzz/src/full_stack.rs
fuzz/src/invoice_request_deser.rs
fuzz/src/refund_deser.rs
fuzz/src/router.rs
lightning/src/blinded_path/mod.rs
lightning/src/blinded_path/payment.rs
lightning/src/ln/blinded_payment_tests.rs
lightning/src/ln/channelmanager.rs
lightning/src/ln/max_payment_path_len_tests.rs
lightning/src/ln/offers_tests.rs
lightning/src/ln/onion_utils.rs
lightning/src/ln/outbound_payment.rs
lightning/src/offers/invoice.rs
lightning/src/offers/invoice_macros.rs
lightning/src/offers/invoice_request.rs
lightning/src/offers/refund.rs
lightning/src/offers/static_invoice.rs
lightning/src/offers/test_utils.rs
lightning/src/routing/router.rs
lightning/src/util/test_utils.rs

index 4322fccb16f215e658f55a3175114e863cb8f777..249d1e51b44226779d337c06338c8500707b429f 100644 (file)
@@ -34,7 +34,7 @@ use bitcoin::hashes::Hash as TraitImport;
 use bitcoin::WPubkeyHash;
 
 use lightning::blinded_path::message::MessageContext;
-use lightning::blinded_path::payment::ReceiveTlvs;
+use lightning::blinded_path::payment::{BlindedPaymentPath, ReceiveTlvs};
 use lightning::blinded_path::BlindedPath;
 use lightning::chain;
 use lightning::chain::chaininterface::{BroadcasterInterface, ConfirmationTarget, FeeEstimator};
@@ -127,7 +127,7 @@ impl Router for FuzzRouter {
        fn create_blinded_payment_paths<T: secp256k1::Signing + secp256k1::Verification>(
                &self, _recipient: PublicKey, _first_hops: Vec<ChannelDetails>, _tlvs: ReceiveTlvs,
                _amount_msats: u64, _secp_ctx: &Secp256k1<T>,
-       ) -> Result<Vec<(BlindedPayInfo, BlindedPath)>, ()> {
+       ) -> Result<Vec<(BlindedPayInfo, BlindedPaymentPath)>, ()> {
                unreachable!()
        }
 }
index fa0c2906294abbe72b073130a5ea1bdcb97755a5..ed5f123e86ec0b569676bef2fb37faf88f3b96f7 100644 (file)
@@ -31,7 +31,7 @@ use bitcoin::hex::FromHex;
 use bitcoin::WPubkeyHash;
 
 use lightning::blinded_path::message::MessageContext;
-use lightning::blinded_path::payment::ReceiveTlvs;
+use lightning::blinded_path::payment::{BlindedPaymentPath, ReceiveTlvs};
 use lightning::blinded_path::BlindedPath;
 use lightning::chain;
 use lightning::chain::chaininterface::{BroadcasterInterface, ConfirmationTarget, FeeEstimator};
@@ -164,7 +164,7 @@ impl Router for FuzzRouter {
        fn create_blinded_payment_paths<T: secp256k1::Signing + secp256k1::Verification>(
                &self, _recipient: PublicKey, _first_hops: Vec<ChannelDetails>, _tlvs: ReceiveTlvs,
                _amount_msats: u64, _secp_ctx: &Secp256k1<T>,
-       ) -> Result<Vec<(BlindedPayInfo, BlindedPath)>, ()> {
+       ) -> Result<Vec<(BlindedPayInfo, BlindedPaymentPath)>, ()> {
                unreachable!()
        }
 }
index d418cbe51d8e87bffff9c61f998aed05b80fa5e2..a5db1c4be9928ee240d0d5505c41dc81b7f3fd7d 100644 (file)
@@ -11,10 +11,9 @@ use crate::utils::test_logger;
 use bitcoin::secp256k1::{self, Keypair, Parity, PublicKey, Secp256k1, SecretKey};
 use core::convert::TryFrom;
 use lightning::blinded_path::payment::{
-       Bolt12OfferContext, ForwardNode, ForwardTlvs, PaymentConstraints, PaymentContext, PaymentRelay,
-       ReceiveTlvs,
+       BlindedPaymentPath, Bolt12OfferContext, ForwardNode, ForwardTlvs, PaymentConstraints,
+       PaymentContext, PaymentRelay, ReceiveTlvs,
 };
-use lightning::blinded_path::BlindedPath;
 use lightning::ln::channelmanager::MIN_FINAL_CLTV_EXPIRY_DELTA;
 use lightning::ln::features::BlindedHopFeatures;
 use lightning::ln::types::PaymentSecret;
@@ -118,7 +117,7 @@ fn build_response<T: secp256k1::Signing + secp256k1::Verification>(
                node_id: pubkey(43),
                htlc_maximum_msat: 1_000_000_000_000,
        }];
-       let payment_path = BlindedPath::new_for_payment(
+       let payment_path = BlindedPaymentPath::new(
                &intermediate_nodes,
                pubkey(42),
                payee_tlvs,
index 5a692280683ca3ad39eed2689c82ed55b839bf59..58dc68eed5cb875940f3c18ee777f75458aebe19 100644 (file)
@@ -11,10 +11,9 @@ use crate::utils::test_logger;
 use bitcoin::secp256k1::{self, Keypair, PublicKey, Secp256k1, SecretKey};
 use core::convert::TryFrom;
 use lightning::blinded_path::payment::{
-       Bolt12RefundContext, ForwardNode, ForwardTlvs, PaymentConstraints, PaymentContext,
-       PaymentRelay, ReceiveTlvs,
+       BlindedPaymentPath, Bolt12RefundContext, ForwardNode, ForwardTlvs, PaymentConstraints,
+       PaymentContext, PaymentRelay, ReceiveTlvs,
 };
-use lightning::blinded_path::BlindedPath;
 use lightning::ln::channelmanager::MIN_FINAL_CLTV_EXPIRY_DELTA;
 use lightning::ln::features::BlindedHopFeatures;
 use lightning::ln::types::PaymentSecret;
@@ -96,7 +95,7 @@ fn build_response<T: secp256k1::Signing + secp256k1::Verification>(
                node_id: pubkey(43),
                htlc_maximum_msat: 1_000_000_000_000,
        }];
-       let payment_path = BlindedPath::new_for_payment(
+       let payment_path = BlindedPaymentPath::new(
                &intermediate_nodes,
                pubkey(42),
                payee_tlvs,
index 96046f258426e934f018761d8d58efeb36fbe1f9..e0fadf44befc241bd9a8c2af335c3621f9d6934d 100644 (file)
@@ -12,6 +12,7 @@ use bitcoin::constants::ChainHash;
 use bitcoin::script::Builder;
 use bitcoin::transaction::TxOut;
 
+use lightning::blinded_path::payment::BlindedPaymentPath;
 use lightning::blinded_path::{BlindedHop, BlindedPath, IntroductionNode};
 use lightning::chain::transaction::OutPoint;
 use lightning::ln::channel_state::{ChannelCounterparty, ChannelDetails, ChannelShutdownState};
@@ -380,7 +381,7 @@ pub fn do_test<Out: test_logger::Output>(data: &[u8], out: Out) {
                                let mut last_hops_unblinded = Vec::new();
                                last_hops!(last_hops_unblinded);
                                let dummy_pk = PublicKey::from_slice(&[2; 33]).unwrap();
-                               let last_hops: Vec<(BlindedPayInfo, BlindedPath)> = last_hops_unblinded
+                               let last_hops: Vec<(BlindedPayInfo, BlindedPaymentPath)> = last_hops_unblinded
                                        .into_iter()
                                        .map(|hint| {
                                                let hop = &hint.0[0];
@@ -402,11 +403,11 @@ pub fn do_test<Out: test_logger::Output>(data: &[u8], out: Out) {
                                                }
                                                (
                                                        payinfo,
-                                                       BlindedPath {
+                                                       BlindedPaymentPath(BlindedPath {
                                                                introduction_node: IntroductionNode::NodeId(hop.src_node_id),
                                                                blinding_point: dummy_pk,
                                                                blinded_hops,
-                                                       },
+                                                       }),
                                                )
                                        })
                                        .collect();
index e34e64c7ac29132ba53131cd1be7fdafbae7b222..be6d315afc1bf5769be306c79a81fb768802bb52 100644 (file)
@@ -18,7 +18,6 @@ use message::MessageContext;
 use core::ops::Deref;
 
 use crate::ln::msgs::DecodeError;
-use crate::offers::invoice::BlindedPayInfo;
 use crate::routing::gossip::{NodeId, ReadOnlyNetworkGraph};
 use crate::sign::EntropySource;
 use crate::util::ser::{Readable, Writeable, Writer};
@@ -154,52 +153,6 @@ impl BlindedPath {
                })
        }
 
-       /// Create a one-hop blinded path for a payment.
-       pub fn one_hop_for_payment<ES: Deref, T: secp256k1::Signing + secp256k1::Verification>(
-               payee_node_id: PublicKey, payee_tlvs: payment::ReceiveTlvs, min_final_cltv_expiry_delta: u16,
-               entropy_source: ES, secp_ctx: &Secp256k1<T>
-       ) -> Result<(BlindedPayInfo, Self), ()> where ES::Target: EntropySource {
-               // This value is not considered in pathfinding for 1-hop blinded paths, because it's intended to
-               // be in relation to a specific channel.
-               let htlc_maximum_msat = u64::max_value();
-               Self::new_for_payment(
-                       &[], payee_node_id, payee_tlvs, htlc_maximum_msat, min_final_cltv_expiry_delta,
-                       entropy_source, secp_ctx
-               )
-       }
-
-       /// Create a blinded path for a payment, to be forwarded along `intermediate_nodes`.
-       ///
-       /// Errors if:
-       /// * a provided node id is invalid
-       /// * [`BlindedPayInfo`] calculation results in an integer overflow
-       /// * any unknown features are required in the provided [`ForwardTlvs`]
-       ///
-       /// [`ForwardTlvs`]: crate::blinded_path::payment::ForwardTlvs
-       //  TODO: make all payloads the same size with padding + add dummy hops
-       pub fn new_for_payment<ES: Deref, T: secp256k1::Signing + secp256k1::Verification>(
-               intermediate_nodes: &[payment::ForwardNode], payee_node_id: PublicKey,
-               payee_tlvs: payment::ReceiveTlvs, htlc_maximum_msat: u64, min_final_cltv_expiry_delta: u16,
-               entropy_source: ES, secp_ctx: &Secp256k1<T>
-       ) -> Result<(BlindedPayInfo, Self), ()> where ES::Target: EntropySource {
-               let introduction_node = IntroductionNode::NodeId(
-                       intermediate_nodes.first().map_or(payee_node_id, |n| n.node_id)
-               );
-               let blinding_secret_bytes = entropy_source.get_secure_random_bytes();
-               let blinding_secret = SecretKey::from_slice(&blinding_secret_bytes[..]).expect("RNG is busted");
-
-               let blinded_payinfo = payment::compute_payinfo(
-                       intermediate_nodes, &payee_tlvs, htlc_maximum_msat, min_final_cltv_expiry_delta
-               )?;
-               Ok((blinded_payinfo, BlindedPath {
-                       introduction_node,
-                       blinding_point: PublicKey::from_secret_key(secp_ctx, &blinding_secret),
-                       blinded_hops: payment::blinded_hops(
-                               secp_ctx, intermediate_nodes, payee_node_id, payee_tlvs, &blinding_secret
-                       ).map_err(|_| ())?,
-               }))
-       }
-
        /// Returns the introduction [`NodeId`] of the blinded path, if it is publicly reachable (i.e.,
        /// it is found in the network graph).
        pub fn public_introduction_node_id<'a>(
index 8c892e896c86fe2fbaa3f33ae4c2742f275b01a4..a7191656a56c878736eff69505f30fa7830e8019 100644 (file)
@@ -7,9 +7,7 @@
 // You may not use this file except in accordance with one or both of these
 // licenses.
 
-//! Data structures and methods for constructing [`BlindedPath`]s to send a payment over.
-//!
-//! [`BlindedPath`]: crate::blinded_path::BlindedPath
+//! Data structures and methods for constructing [`BlindedPaymentPath`]s to send a payment over.
 
 use bitcoin::secp256k1::{self, PublicKey, Secp256k1, SecretKey};
 
@@ -26,7 +24,7 @@ use crate::ln::onion_utils;
 use crate::offers::invoice::BlindedPayInfo;
 use crate::offers::invoice_request::InvoiceRequestFields;
 use crate::offers::offer::OfferId;
-use crate::sign::{NodeSigner, Recipient};
+use crate::sign::{EntropySource, NodeSigner, Recipient};
 use crate::util::ser::{FixedLengthReader, LengthReadableArgs, HighZeroBytesDroppedBigSize, Readable, Writeable, Writer};
 
 use core::mem;
@@ -35,6 +33,69 @@ use core::ops::Deref;
 #[allow(unused_imports)]
 use crate::prelude::*;
 
+/// A [`BlindedPath`] to be used for sending or receiving a payment, hiding the identity of the
+/// recipient.
+#[derive(Clone, Debug, Hash, PartialEq, Eq)]
+pub struct BlindedPaymentPath(pub BlindedPath);
+
+impl Writeable for BlindedPaymentPath {
+       fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
+               self.0.write(w)
+       }
+}
+
+impl Readable for BlindedPaymentPath {
+       fn read<R: io::Read>(r: &mut R) -> Result<Self, DecodeError> {
+               Ok(Self(BlindedPath::read(r)?))
+       }
+}
+
+impl BlindedPaymentPath {
+       /// Create a one-hop blinded path for a payment.
+       pub fn one_hop<ES: Deref, T: secp256k1::Signing + secp256k1::Verification>(
+               payee_node_id: PublicKey, payee_tlvs: ReceiveTlvs, min_final_cltv_expiry_delta: u16,
+               entropy_source: ES, secp_ctx: &Secp256k1<T>
+       ) -> Result<(BlindedPayInfo, Self), ()> where ES::Target: EntropySource {
+               // This value is not considered in pathfinding for 1-hop blinded paths, because it's intended to
+               // be in relation to a specific channel.
+               let htlc_maximum_msat = u64::max_value();
+               Self::new(
+                       &[], payee_node_id, payee_tlvs, htlc_maximum_msat, min_final_cltv_expiry_delta,
+                       entropy_source, secp_ctx
+               )
+       }
+
+       /// Create a blinded path for a payment, to be forwarded along `intermediate_nodes`.
+       ///
+       /// Errors if:
+       /// * a provided node id is invalid
+       /// * [`BlindedPayInfo`] calculation results in an integer overflow
+       /// * any unknown features are required in the provided [`ForwardTlvs`]
+       //  TODO: make all payloads the same size with padding + add dummy hops
+       pub fn new<ES: Deref, T: secp256k1::Signing + secp256k1::Verification>(
+               intermediate_nodes: &[ForwardNode], payee_node_id: PublicKey, payee_tlvs: ReceiveTlvs,
+               htlc_maximum_msat: u64, min_final_cltv_expiry_delta: u16, entropy_source: ES,
+               secp_ctx: &Secp256k1<T>
+       ) -> Result<(BlindedPayInfo, Self), ()> where ES::Target: EntropySource {
+               let introduction_node = IntroductionNode::NodeId(
+                       intermediate_nodes.first().map_or(payee_node_id, |n| n.node_id)
+               );
+               let blinding_secret_bytes = entropy_source.get_secure_random_bytes();
+               let blinding_secret = SecretKey::from_slice(&blinding_secret_bytes[..]).expect("RNG is busted");
+
+               let blinded_payinfo = compute_payinfo(
+                       intermediate_nodes, &payee_tlvs, htlc_maximum_msat, min_final_cltv_expiry_delta
+               )?;
+               Ok((blinded_payinfo, Self(BlindedPath {
+                       introduction_node,
+                       blinding_point: PublicKey::from_secret_key(secp_ctx, &blinding_secret),
+                       blinded_hops: blinded_hops(
+                               secp_ctx, intermediate_nodes, payee_node_id, payee_tlvs, &blinding_secret
+                       ).map_err(|_| ())?,
+               })))
+       }
+}
+
 /// An intermediate node, its outbound channel, and relay parameters.
 #[derive(Clone, Debug)]
 pub struct ForwardNode {
@@ -117,10 +178,9 @@ pub struct PaymentConstraints {
        pub htlc_minimum_msat: u64,
 }
 
-/// The context of an inbound payment, which is included in a [`BlindedPath`] via [`ReceiveTlvs`]
-/// and surfaced in [`PaymentPurpose`].
+/// The context of an inbound payment, which is included in a [`BlindedPaymentPath`] via
+/// [`ReceiveTlvs`] and surfaced in [`PaymentPurpose`].
 ///
-/// [`BlindedPath`]: crate::blinded_path::BlindedPath
 /// [`PaymentPurpose`]: crate::events::PaymentPurpose
 #[derive(Clone, Debug, Eq, PartialEq)]
 pub enum PaymentContext {
@@ -286,16 +346,16 @@ pub(super) fn blinded_hops<T: secp256k1::Signing + secp256k1::Verification>(
 //
 // Will only modify `path` when returning `Ok`.
 pub(crate) fn advance_path_by_one<NS: Deref, NL: Deref, T>(
-       path: &mut BlindedPath, node_signer: &NS, node_id_lookup: &NL, secp_ctx: &Secp256k1<T>
+       path: &mut BlindedPaymentPath, node_signer: &NS, node_id_lookup: &NL, secp_ctx: &Secp256k1<T>
 ) -> Result<(), ()>
 where
        NS::Target: NodeSigner,
        NL::Target: NodeIdLookUp,
        T: secp256k1::Signing + secp256k1::Verification,
 {
-       let control_tlvs_ss = node_signer.ecdh(Recipient::Node, &path.blinding_point, None)?;
+       let control_tlvs_ss = node_signer.ecdh(Recipient::Node, &path.0.blinding_point, None)?;
        let rho = onion_utils::gen_rho_from_shared_secret(&control_tlvs_ss.secret_bytes());
-       let encrypted_control_tlvs = &path.blinded_hops.get(0).ok_or(())?.encrypted_payload;
+       let encrypted_control_tlvs = &path.0.blinded_hops.get(0).ok_or(())?.encrypted_payload;
        let mut s = Cursor::new(encrypted_control_tlvs);
        let mut reader = FixedLengthReader::new(&mut s, encrypted_control_tlvs.len() as u64);
        match ChaChaPolyReadAdapter::read(&mut reader, rho) {
@@ -307,11 +367,11 @@ where
                                None => return Err(()),
                        };
                        let mut new_blinding_point = onion_utils::next_hop_pubkey(
-                               secp_ctx, path.blinding_point, control_tlvs_ss.as_ref()
+                               secp_ctx, path.0.blinding_point, control_tlvs_ss.as_ref()
                        ).map_err(|_| ())?;
-                       mem::swap(&mut path.blinding_point, &mut new_blinding_point);
-                       path.introduction_node = IntroductionNode::NodeId(next_node_id);
-                       path.blinded_hops.remove(0);
+                       mem::swap(&mut path.0.blinding_point, &mut new_blinding_point);
+                       path.0.introduction_node = IntroductionNode::NodeId(next_node_id);
+                       path.0.blinded_hops.remove(0);
                        Ok(())
                },
                _ => Err(())
index 9d246f1a741840a72ca663f54e64cd1a3fb50098..b13b1e04d64f7ab1addd03489ad6841a534d8f9c 100644 (file)
@@ -8,8 +8,7 @@
 // licenses.
 
 use bitcoin::secp256k1::{PublicKey, Secp256k1, SecretKey};
-use crate::blinded_path::BlindedPath;
-use crate::blinded_path::payment::{ForwardNode, ForwardTlvs, PaymentConstraints, PaymentContext, PaymentRelay, ReceiveTlvs};
+use crate::blinded_path::payment::{BlindedPaymentPath, ForwardNode, ForwardTlvs, PaymentConstraints, PaymentContext, PaymentRelay, ReceiveTlvs};
 use crate::events::{Event, HTLCDestination, MessageSendEvent, MessageSendEventsProvider, PaymentFailureReason};
 use crate::ln::types::PaymentSecret;
 use crate::ln::channelmanager;
@@ -31,7 +30,7 @@ fn blinded_payment_path(
        payment_secret: PaymentSecret, intro_node_min_htlc: u64, intro_node_max_htlc: u64,
        node_ids: Vec<PublicKey>, channel_upds: &[&msgs::UnsignedChannelUpdate],
        keys_manager: &test_utils::TestKeysInterface
-) -> (BlindedPayInfo, BlindedPath) {
+) -> (BlindedPayInfo, BlindedPaymentPath) {
        let mut intermediate_nodes = Vec::new();
        let mut intro_node_min_htlc_opt = Some(intro_node_min_htlc);
        let mut intro_node_max_htlc_opt = Some(intro_node_max_htlc);
@@ -66,7 +65,7 @@ fn blinded_payment_path(
                payment_context: PaymentContext::unknown(),
        };
        let mut secp_ctx = Secp256k1::new();
-       BlindedPath::new_for_payment(
+       BlindedPaymentPath::new(
                &intermediate_nodes[..], *node_ids.last().unwrap(), payee_tlvs,
                intro_node_max_htlc_opt.unwrap_or_else(|| channel_upds.last().unwrap().htlc_maximum_msat),
                TEST_FINAL_CLTV as u16, keys_manager, &secp_ctx
@@ -112,8 +111,8 @@ fn do_one_hop_blinded_path(success: bool) {
                payment_context: PaymentContext::unknown(),
        };
        let mut secp_ctx = Secp256k1::new();
-       let blinded_path = BlindedPath::one_hop_for_payment(
-               nodes[1].node.get_our_node_id(), payee_tlvs, TEST_FINAL_CLTV as u16,
+       let blinded_path = BlindedPaymentPath::new(
+               &[], nodes[1].node.get_our_node_id(), payee_tlvs, u64::MAX, TEST_FINAL_CLTV as u16,
                &chanmon_cfgs[1].keys_manager, &secp_ctx
        ).unwrap();
 
@@ -155,8 +154,8 @@ fn mpp_to_one_hop_blinded_path() {
                },
                payment_context: PaymentContext::unknown(),
        };
-       let blinded_path = BlindedPath::one_hop_for_payment(
-               nodes[3].node.get_our_node_id(), payee_tlvs, TEST_FINAL_CLTV as u16,
+       let blinded_path = BlindedPaymentPath::new(
+               &[], nodes[3].node.get_our_node_id(), payee_tlvs, u64::MAX, TEST_FINAL_CLTV as u16,
                &chanmon_cfgs[3].keys_manager, &secp_ctx
        ).unwrap();
 
@@ -1301,8 +1300,8 @@ fn custom_tlvs_to_blinded_path() {
                payment_context: PaymentContext::unknown(),
        };
        let mut secp_ctx = Secp256k1::new();
-       let blinded_path = BlindedPath::one_hop_for_payment(
-               nodes[1].node.get_our_node_id(), payee_tlvs, TEST_FINAL_CLTV as u16,
+       let blinded_path = BlindedPaymentPath::new(
+               &[], nodes[1].node.get_our_node_id(), payee_tlvs, u64::MAX, TEST_FINAL_CLTV as u16,
                &chanmon_cfgs[1].keys_manager, &secp_ctx
        ).unwrap();
 
index c6645956b18decbcad3639f91f5db1f9015d7c61..e3e9bcfe8e343424f77a672d1e72e625aab3d265 100644 (file)
@@ -34,7 +34,7 @@ use bitcoin::{secp256k1, Sequence};
 use crate::blinded_path::message::{MessageContext, OffersContext};
 use crate::blinded_path::{BlindedPath, NodeIdLookUp};
 use crate::blinded_path::message::ForwardNode;
-use crate::blinded_path::payment::{Bolt12OfferContext, Bolt12RefundContext, PaymentConstraints, PaymentContext, ReceiveTlvs};
+use crate::blinded_path::payment::{BlindedPaymentPath, Bolt12OfferContext, Bolt12RefundContext, PaymentConstraints, PaymentContext, ReceiveTlvs};
 use crate::chain;
 use crate::chain::{Confirm, ChannelMonitorUpdateStatus, Watch, BestBlock};
 use crate::chain::chaininterface::{BroadcasterInterface, ConfirmationTarget, FeeEstimator, LowerBoundedFeeEstimator};
@@ -9073,8 +9073,8 @@ where
        /// message.
        ///
        /// The resulting invoice uses a [`PaymentHash`] recognized by the [`ChannelManager`] and a
-       /// [`BlindedPath`] containing the [`PaymentSecret`] needed to reconstruct the corresponding
-       /// [`PaymentPreimage`]. It is returned purely for informational purposes.
+       /// [`BlindedPaymentPath`] containing the [`PaymentSecret`] needed to reconstruct the
+       /// corresponding [`PaymentPreimage`]. It is returned purely for informational purposes.
        ///
        /// # Limitations
        ///
@@ -9350,7 +9350,7 @@ where
        /// [`Router::create_blinded_payment_paths`].
        fn create_blinded_payment_paths(
                &self, amount_msats: u64, payment_secret: PaymentSecret, payment_context: PaymentContext
-       ) -> Result<Vec<(BlindedPayInfo, BlindedPath)>, ()> {
+       ) -> Result<Vec<(BlindedPayInfo, BlindedPaymentPath)>, ()> {
                let secp_ctx = &self.secp_ctx;
 
                let first_hops = self.list_usable_channels();
index 096bcf9633c64e45238714b8cafa4a54ec63f3f6..f3ce1c39a36e0875a80b026f1c47ef246745f8b8 100644 (file)
@@ -12,7 +12,7 @@
 
 use bitcoin::secp256k1::{Secp256k1, PublicKey};
 use crate::blinded_path::{BlindedHop, BlindedPath, IntroductionNode};
-use crate::blinded_path::payment::{PaymentConstraints, PaymentContext, ReceiveTlvs};
+use crate::blinded_path::payment::{BlindedPaymentPath, PaymentConstraints, PaymentContext, ReceiveTlvs};
 use crate::events::{Event, MessageSendEventsProvider};
 use crate::ln::PaymentSecret;
 use crate::ln::blinded_payment_tests::get_blinded_route_parameters;
@@ -167,8 +167,8 @@ fn one_hop_blinded_path_with_custom_tlv() {
                payment_context: PaymentContext::unknown(),
        };
        let mut secp_ctx = Secp256k1::new();
-       let blinded_path = BlindedPath::one_hop_for_payment(
-               nodes[2].node.get_our_node_id(), payee_tlvs, TEST_FINAL_CLTV as u16,
+       let blinded_path = BlindedPaymentPath::new(
+               &[], nodes[2].node.get_our_node_id(), payee_tlvs, u64::MAX, TEST_FINAL_CLTV as u16,
                &chanmon_cfgs[2].keys_manager, &secp_ctx
        ).unwrap();
        let route_params = RouteParameters::from_payment_params_and_value(
@@ -182,8 +182,8 @@ fn one_hop_blinded_path_with_custom_tlv() {
                sender_intended_htlc_amt_msat: MIN_FINAL_VALUE_ESTIMATE_WITH_OVERPAY,
                total_msat: MIN_FINAL_VALUE_ESTIMATE_WITH_OVERPAY,
                cltv_expiry_height: nodes[0].best_block_info().1 + DEFAULT_MAX_TOTAL_CLTV_EXPIRY_DELTA,
-               encrypted_tlvs: &blinded_path.1.blinded_hops[0].encrypted_payload,
-               intro_node_blinding_point: Some(blinded_path.1.blinding_point),
+               encrypted_tlvs: &blinded_path.1.0.blinded_hops[0].encrypted_payload,
+               intro_node_blinding_point: Some(blinded_path.1.0.blinding_point),
                keysend_preimage: None,
                custom_tlvs: &Vec::new()
        }.serialized_length();
@@ -363,7 +363,7 @@ fn bolt12_invoice_too_large_blinded_paths() {
                        htlc_maximum_msat: 42_000_000,
                        features: BlindedHopFeatures::empty(),
                },
-               BlindedPath {
+               BlindedPaymentPath(BlindedPath {
                        introduction_node: IntroductionNode::NodeId(PublicKey::from_slice(&[2; 33]).unwrap()),
                        blinding_point: PublicKey::from_slice(&[2; 33]).unwrap(),
                        blinded_hops: vec![
@@ -376,7 +376,7 @@ fn bolt12_invoice_too_large_blinded_paths() {
                                        encrypted_payload: vec![42; 1300],
                                },
                        ],
-               }
+               })
        )]);
 
        let offer = nodes[1].node.create_offer_builder(None).unwrap().build().unwrap();
index fd496b5f639cbd57cb8af24c6c4c05e1f90e179f..9302227dc77d708b3d236753aa97d59d38e377b2 100644 (file)
@@ -584,7 +584,7 @@ fn creates_and_pays_for_offer_using_two_hop_blinded_path() {
        assert_ne!(invoice.signing_pubkey(), alice_id);
        assert!(!invoice.payment_paths().is_empty());
        for (_, path) in invoice.payment_paths() {
-               assert_eq!(path.introduction_node, IntroductionNode::NodeId(bob_id));
+               assert_eq!(path.0.introduction_node, IntroductionNode::NodeId(bob_id));
        }
 
        route_bolt12_payment(david, &[charlie, bob, alice], &invoice);
@@ -665,7 +665,7 @@ fn creates_and_pays_for_refund_using_two_hop_blinded_path() {
        assert_ne!(invoice.signing_pubkey(), alice_id);
        assert!(!invoice.payment_paths().is_empty());
        for (_, path) in invoice.payment_paths() {
-               assert_eq!(path.introduction_node, IntroductionNode::NodeId(bob_id));
+               assert_eq!(path.0.introduction_node, IntroductionNode::NodeId(bob_id));
        }
 
        route_bolt12_payment(david, &[charlie, bob, alice], &invoice);
@@ -730,7 +730,7 @@ fn creates_and_pays_for_offer_using_one_hop_blinded_path() {
        assert_ne!(invoice.signing_pubkey(), alice_id);
        assert!(!invoice.payment_paths().is_empty());
        for (_, path) in invoice.payment_paths() {
-               assert_eq!(path.introduction_node, IntroductionNode::NodeId(alice_id));
+               assert_eq!(path.0.introduction_node, IntroductionNode::NodeId(alice_id));
        }
 
        route_bolt12_payment(bob, &[alice], &invoice);
@@ -785,7 +785,7 @@ fn creates_and_pays_for_refund_using_one_hop_blinded_path() {
        assert_ne!(invoice.signing_pubkey(), alice_id);
        assert!(!invoice.payment_paths().is_empty());
        for (_, path) in invoice.payment_paths() {
-               assert_eq!(path.introduction_node, IntroductionNode::NodeId(alice_id));
+               assert_eq!(path.0.introduction_node, IntroductionNode::NodeId(alice_id));
        }
 
        route_bolt12_payment(bob, &[alice], &invoice);
@@ -1109,7 +1109,7 @@ fn pays_bolt12_invoice_asynchronously() {
        assert_ne!(invoice.signing_pubkey(), alice_id);
        assert!(!invoice.payment_paths().is_empty());
        for (_, path) in invoice.payment_paths() {
-               assert_eq!(path.introduction_node, IntroductionNode::NodeId(alice_id));
+               assert_eq!(path.0.introduction_node, IntroductionNode::NodeId(alice_id));
        }
 
        assert!(bob.node.send_payment_for_bolt12_invoice(&invoice, context.as_ref()).is_ok());
@@ -1193,7 +1193,7 @@ fn creates_offer_with_blinded_path_using_unannounced_introduction_node() {
        assert_ne!(invoice.signing_pubkey(), alice_id);
        assert!(!invoice.payment_paths().is_empty());
        for (_, path) in invoice.payment_paths() {
-               assert_eq!(path.introduction_node, IntroductionNode::NodeId(bob_id));
+               assert_eq!(path.0.introduction_node, IntroductionNode::NodeId(bob_id));
        }
 
        route_bolt12_payment(bob, &[alice], &invoice);
@@ -1243,7 +1243,7 @@ fn creates_refund_with_blinded_path_using_unannounced_introduction_node() {
        assert_ne!(invoice.signing_pubkey(), alice_id);
        assert!(!invoice.payment_paths().is_empty());
        for (_, path) in invoice.payment_paths() {
-               assert_eq!(path.introduction_node, IntroductionNode::NodeId(bob_id));
+               assert_eq!(path.0.introduction_node, IntroductionNode::NodeId(bob_id));
        }
 }
 
index d6fe281d1d32979979df9d6df8c2ea13ee989139..dbb76e87fbe200c9a32426feb5548d63a7fbc4c1 100644 (file)
@@ -340,8 +340,8 @@ pub(crate) fn set_max_path_length(
                .map(|(_, path)| path)
                .max_by_key(|path| path.serialized_length())
                .map(|largest_path| BlindedTailHopIter {
-                       hops: largest_path.blinded_hops.iter(),
-                       blinding_point: largest_path.blinding_point,
+                       hops: largest_path.0.blinded_hops.iter(),
+                       blinding_point: largest_path.0.blinding_point,
                        final_value_msat: final_value_msat_with_overpay_buffer,
                        excess_final_cltv_expiry_delta: 0,
                });
index c36f2c5c1a931faf3c5ea0a6949b638c7cc601c9..541a70411e87ed71710196d2614023dfc205e34f 100644 (file)
@@ -428,10 +428,10 @@ pub enum RetryableSendFailure {
        /// [`Event::PaymentFailed`]: crate::events::Event::PaymentFailed
        DuplicatePayment,
        /// The [`RecipientOnionFields::payment_metadata`], [`RecipientOnionFields::custom_tlvs`], or
-       /// [`BlindedPath`]s provided are too large and caused us to exceed the maximum onion packet size
-       /// of 1300 bytes.
+       /// [`BlindedPaymentPath`]s provided are too large and caused us to exceed the maximum onion
+       /// packet size of 1300 bytes.
        ///
-       /// [`BlindedPath`]: crate::blinded_path::BlindedPath
+       /// [`BlindedPaymentPath`]: crate::blinded_path::payment::BlindedPaymentPath
        OnionPacketSizeExceeded,
 }
 
@@ -835,7 +835,7 @@ impl OutboundPayments {
                // Advance any blinded path where the introduction node is our node.
                if let Ok(our_node_id) = node_signer.get_node_id(Recipient::Node) {
                        for (_, path) in payment_params.payee.blinded_route_hints_mut().iter_mut() {
-                               let introduction_node_id = match path.introduction_node {
+                               let introduction_node_id = match path.0.introduction_node {
                                        IntroductionNode::NodeId(pubkey) => pubkey,
                                        IntroductionNode::DirectedShortChannelId(direction, scid) => {
                                                match node_id_lookup.next_node_id(scid) {
index 3fd2e73aa5b46374b506dba39572fc0438d293e0..af9f28d905e84c9c9cd94c4ee182060cb36f09aa 100644 (file)
@@ -14,7 +14,7 @@
 //! then sends the invoice to the intended payer, who will then pay it.
 //!
 //! The payment recipient must include a [`PaymentHash`], so as to reveal the preimage upon payment
-//! receipt, and one or more [`BlindedPath`]s for the payer to use when sending the payment.
+//! receipt, and one or more [`BlindedPaymentPath`]s for the payer to use when sending the payment.
 //!
 //! ```
 //! extern crate bitcoin;
@@ -30,9 +30,9 @@
 //!
 //! # use lightning::ln::types::PaymentHash;
 //! # use lightning::offers::invoice::{BlindedPayInfo, ExplicitSigningPubkey, InvoiceBuilder};
-//! # use lightning::blinded_path::BlindedPath;
+//! # use lightning::blinded_path::payment::BlindedPaymentPath;
 //! #
-//! # fn create_payment_paths() -> Vec<(BlindedPayInfo, BlindedPath)> { unimplemented!() }
+//! # fn create_payment_paths() -> Vec<(BlindedPayInfo, BlindedPaymentPath)> { unimplemented!() }
 //! # fn create_payment_hash() -> PaymentHash { unimplemented!() }
 //! #
 //! # fn parse_invoice_request(bytes: Vec<u8>) -> Result<(), lightning::offers::parse::Bolt12ParseError> {
@@ -111,6 +111,7 @@ use core::time::Duration;
 use core::hash::{Hash, Hasher};
 use crate::io;
 use crate::blinded_path::BlindedPath;
+use crate::blinded_path::payment::BlindedPaymentPath;
 use crate::ln::types::PaymentHash;
 use crate::ln::channelmanager::PaymentId;
 use crate::ln::features::{BlindedHopFeatures, Bolt12InvoiceFeatures, InvoiceRequestFeatures, OfferFeatures};
@@ -211,7 +212,7 @@ impl SigningPubkeyStrategy for DerivedSigningPubkey {}
 macro_rules! invoice_explicit_signing_pubkey_builder_methods { ($self: ident, $self_type: ty) => {
        #[cfg_attr(c_bindings, allow(dead_code))]
        pub(super) fn for_offer(
-               invoice_request: &'a InvoiceRequest, payment_paths: Vec<(BlindedPayInfo, BlindedPath)>,
+               invoice_request: &'a InvoiceRequest, payment_paths: Vec<(BlindedPayInfo, BlindedPaymentPath)>,
                created_at: Duration, payment_hash: PaymentHash, signing_pubkey: PublicKey
        ) -> Result<Self, Bolt12SemanticError> {
                let amount_msats = Self::amount_msats(invoice_request)?;
@@ -227,7 +228,7 @@ macro_rules! invoice_explicit_signing_pubkey_builder_methods { ($self: ident, $s
 
        #[cfg_attr(c_bindings, allow(dead_code))]
        pub(super) fn for_refund(
-               refund: &'a Refund, payment_paths: Vec<(BlindedPayInfo, BlindedPath)>, created_at: Duration,
+               refund: &'a Refund, payment_paths: Vec<(BlindedPayInfo, BlindedPaymentPath)>, created_at: Duration,
                payment_hash: PaymentHash, signing_pubkey: PublicKey
        ) -> Result<Self, Bolt12SemanticError> {
                let amount_msats = refund.amount_msats();
@@ -269,7 +270,7 @@ macro_rules! invoice_explicit_signing_pubkey_builder_methods { ($self: ident, $s
 macro_rules! invoice_derived_signing_pubkey_builder_methods { ($self: ident, $self_type: ty) => {
        #[cfg_attr(c_bindings, allow(dead_code))]
        pub(super) fn for_offer_using_keys(
-               invoice_request: &'a InvoiceRequest, payment_paths: Vec<(BlindedPayInfo, BlindedPath)>,
+               invoice_request: &'a InvoiceRequest, payment_paths: Vec<(BlindedPayInfo, BlindedPaymentPath)>,
                created_at: Duration, payment_hash: PaymentHash, keys: Keypair
        ) -> Result<Self, Bolt12SemanticError> {
                let amount_msats = Self::amount_msats(invoice_request)?;
@@ -286,7 +287,7 @@ macro_rules! invoice_derived_signing_pubkey_builder_methods { ($self: ident, $se
 
        #[cfg_attr(c_bindings, allow(dead_code))]
        pub(super) fn for_refund_using_keys(
-               refund: &'a Refund, payment_paths: Vec<(BlindedPayInfo, BlindedPath)>, created_at: Duration,
+               refund: &'a Refund, payment_paths: Vec<(BlindedPayInfo, BlindedPaymentPath)>, created_at: Duration,
                payment_hash: PaymentHash, keys: Keypair,
        ) -> Result<Self, Bolt12SemanticError> {
                let amount_msats = refund.amount_msats();
@@ -355,7 +356,7 @@ macro_rules! invoice_builder_methods { (
 
        #[cfg_attr(c_bindings, allow(dead_code))]
        fn fields(
-               payment_paths: Vec<(BlindedPayInfo, BlindedPath)>, created_at: Duration,
+               payment_paths: Vec<(BlindedPayInfo, BlindedPaymentPath)>, created_at: Duration,
                payment_hash: PaymentHash, amount_msats: u64, signing_pubkey: PublicKey
        ) -> InvoiceFields {
                InvoiceFields {
@@ -602,7 +603,7 @@ enum InvoiceContents {
 /// Invoice-specific fields for an `invoice` message.
 #[derive(Clone, Debug, PartialEq)]
 struct InvoiceFields {
-       payment_paths: Vec<(BlindedPayInfo, BlindedPath)>,
+       payment_paths: Vec<(BlindedPayInfo, BlindedPaymentPath)>,
        created_at: Duration,
        relative_expiry: Option<Duration>,
        payment_hash: PaymentHash,
@@ -987,7 +988,7 @@ impl InvoiceContents {
                }
        }
 
-       fn payment_paths(&self) -> &[(BlindedPayInfo, BlindedPath)] {
+       fn payment_paths(&self) -> &[(BlindedPayInfo, BlindedPaymentPath)] {
                &self.fields().payment_paths[..]
        }
 
@@ -1192,7 +1193,7 @@ impl TryFrom<Vec<u8>> for Bolt12Invoice {
 }
 
 tlv_stream!(InvoiceTlvStream, InvoiceTlvStreamRef, 160..240, {
-       (160, paths: (Vec<BlindedPath>, WithoutLength, Iterable<'a, BlindedPathIter<'a>, BlindedPath>)),
+       (160, paths: (Vec<BlindedPaymentPath>, WithoutLength, Iterable<'a, BlindedPathIter<'a>, BlindedPaymentPath>)),
        (162, blindedpay: (Vec<BlindedPayInfo>, WithoutLength, Iterable<'a, BlindedPayInfoIter<'a>, BlindedPayInfo>)),
        (164, created_at: (u64, HighZeroBytesDroppedBigSize)),
        (166, relative_expiry: (u32, HighZeroBytesDroppedBigSize)),
@@ -1206,16 +1207,16 @@ tlv_stream!(InvoiceTlvStream, InvoiceTlvStreamRef, 160..240, {
 });
 
 pub(super) type BlindedPathIter<'a> = core::iter::Map<
-       core::slice::Iter<'a, (BlindedPayInfo, BlindedPath)>,
-       for<'r> fn(&'r (BlindedPayInfo, BlindedPath)) -> &'r BlindedPath,
+       core::slice::Iter<'a, (BlindedPayInfo, BlindedPaymentPath)>,
+       for<'r> fn(&'r (BlindedPayInfo, BlindedPaymentPath)) -> &'r BlindedPaymentPath,
 >;
 
 pub(super) type BlindedPayInfoIter<'a> = core::iter::Map<
-       core::slice::Iter<'a, (BlindedPayInfo, BlindedPath)>,
-       for<'r> fn(&'r (BlindedPayInfo, BlindedPath)) -> &'r BlindedPayInfo,
+       core::slice::Iter<'a, (BlindedPayInfo, BlindedPaymentPath)>,
+       for<'r> fn(&'r (BlindedPayInfo, BlindedPaymentPath)) -> &'r BlindedPayInfo,
 >;
 
-/// Information needed to route a payment across a [`BlindedPath`].
+/// Information needed to route a payment across a [`BlindedPaymentPath`].
 #[derive(Clone, Debug, Hash, Eq, PartialEq)]
 pub struct BlindedPayInfo {
        /// Base fee charged (in millisatoshi) for the entire blinded path.
@@ -1387,8 +1388,8 @@ impl TryFrom<PartialInvoiceTlvStream> for InvoiceContents {
 }
 
 pub(super) fn construct_payment_paths(
-       blinded_payinfos: Option<Vec<BlindedPayInfo>>, blinded_paths: Option<Vec<BlindedPath>>
-) -> Result<Vec<(BlindedPayInfo, BlindedPath)>, Bolt12SemanticError> {
+       blinded_payinfos: Option<Vec<BlindedPayInfo>>, blinded_paths: Option<Vec<BlindedPaymentPath>>
+) -> Result<Vec<(BlindedPayInfo, BlindedPaymentPath)>, Bolt12SemanticError> {
        match (blinded_payinfos, blinded_paths) {
                (_, None) => Err(Bolt12SemanticError::MissingPaths),
                (None, _) => Err(Bolt12SemanticError::InvalidPayInfo),
index c603c352ce9f5604cf7bc5eb75bf7f7d4c1583b6..a06c0663a0fb7d2899626fc61d851a0f04b1203b 100644 (file)
@@ -107,7 +107,7 @@ macro_rules! invoice_accessors_common { ($self: ident, $contents: expr, $invoice
        ///
        /// This is not exported to bindings users as slices with non-reference types cannot be ABI
        /// matched in another language.
-       pub fn payment_paths(&$self) -> &[(BlindedPayInfo, BlindedPath)] {
+       pub fn payment_paths(&$self) -> &[(BlindedPayInfo, BlindedPaymentPath)] {
                $contents.payment_paths()
        }
 
index 6ed9b2a1295086f6598a404047df0667ad527027..66ed8b1d0ac386ead268e0bfbcf5ad0ddb9832de 100644 (file)
@@ -63,6 +63,7 @@ use bitcoin::secp256k1::{Keypair, PublicKey, Secp256k1, self};
 use bitcoin::secp256k1::schnorr::Signature;
 use crate::io;
 use crate::blinded_path::BlindedPath;
+use crate::blinded_path::payment::BlindedPaymentPath;
 use crate::ln::types::PaymentHash;
 use crate::ln::channelmanager::PaymentId;
 use crate::ln::features::InvoiceRequestFeatures;
@@ -707,7 +708,7 @@ macro_rules! invoice_request_respond_with_explicit_signing_pubkey_methods { (
        /// [`Duration`]: core::time::Duration
        #[cfg(feature = "std")]
        pub fn respond_with(
-               &$self, payment_paths: Vec<(BlindedPayInfo, BlindedPath)>, payment_hash: PaymentHash
+               &$self, payment_paths: Vec<(BlindedPayInfo, BlindedPaymentPath)>, payment_hash: PaymentHash
        ) -> Result<$builder, Bolt12SemanticError> {
                let created_at = std::time::SystemTime::now()
                        .duration_since(std::time::SystemTime::UNIX_EPOCH)
@@ -742,7 +743,7 @@ macro_rules! invoice_request_respond_with_explicit_signing_pubkey_methods { (
        /// [`Bolt12Invoice::created_at`]: crate::offers::invoice::Bolt12Invoice::created_at
        /// [`OfferBuilder::deriving_signing_pubkey`]: crate::offers::offer::OfferBuilder::deriving_signing_pubkey
        pub fn respond_with_no_std(
-               &$self, payment_paths: Vec<(BlindedPayInfo, BlindedPath)>, payment_hash: PaymentHash,
+               &$self, payment_paths: Vec<(BlindedPayInfo, BlindedPaymentPath)>, payment_hash: PaymentHash,
                created_at: core::time::Duration
        ) -> Result<$builder, Bolt12SemanticError> {
                if $contents.invoice_request_features().requires_unknown_bits() {
@@ -760,7 +761,7 @@ macro_rules! invoice_request_respond_with_explicit_signing_pubkey_methods { (
        #[cfg(test)]
        #[allow(dead_code)]
        pub(super) fn respond_with_no_std_using_signing_pubkey(
-               &$self, payment_paths: Vec<(BlindedPayInfo, BlindedPath)>, payment_hash: PaymentHash,
+               &$self, payment_paths: Vec<(BlindedPayInfo, BlindedPaymentPath)>, payment_hash: PaymentHash,
                created_at: core::time::Duration, signing_pubkey: PublicKey
        ) -> Result<$builder, Bolt12SemanticError> {
                debug_assert!($contents.contents.inner.offer.signing_pubkey().is_none());
@@ -880,7 +881,7 @@ macro_rules! invoice_request_respond_with_derived_signing_pubkey_methods { (
        /// [`Bolt12Invoice`]: crate::offers::invoice::Bolt12Invoice
        #[cfg(feature = "std")]
        pub fn respond_using_derived_keys(
-               &$self, payment_paths: Vec<(BlindedPayInfo, BlindedPath)>, payment_hash: PaymentHash
+               &$self, payment_paths: Vec<(BlindedPayInfo, BlindedPaymentPath)>, payment_hash: PaymentHash
        ) -> Result<$builder, Bolt12SemanticError> {
                let created_at = std::time::SystemTime::now()
                        .duration_since(std::time::SystemTime::UNIX_EPOCH)
@@ -897,7 +898,7 @@ macro_rules! invoice_request_respond_with_derived_signing_pubkey_methods { (
        ///
        /// [`Bolt12Invoice`]: crate::offers::invoice::Bolt12Invoice
        pub fn respond_using_derived_keys_no_std(
-               &$self, payment_paths: Vec<(BlindedPayInfo, BlindedPath)>, payment_hash: PaymentHash,
+               &$self, payment_paths: Vec<(BlindedPayInfo, BlindedPaymentPath)>, payment_hash: PaymentHash,
                created_at: core::time::Duration
        ) -> Result<$builder, Bolt12SemanticError> {
                if $self.inner.invoice_request_features().requires_unknown_bits() {
index 10f56f0a14ce638f50766eea5f157cfde1f443de..1835a099f63e336195ac7e8371a39d8b4eafb7e3 100644 (file)
@@ -92,6 +92,7 @@ use core::time::Duration;
 use crate::sign::EntropySource;
 use crate::io;
 use crate::blinded_path::BlindedPath;
+use crate::blinded_path::payment::BlindedPaymentPath;
 use crate::ln::types::PaymentHash;
 use crate::ln::channelmanager::PaymentId;
 use crate::ln::features::InvoiceRequestFeatures;
@@ -532,7 +533,7 @@ macro_rules! respond_with_explicit_signing_pubkey_methods { ($self: ident, $buil
        /// [`Duration`]: core::time::Duration
        #[cfg(feature = "std")]
        pub fn respond_with(
-               &$self, payment_paths: Vec<(BlindedPayInfo, BlindedPath)>, payment_hash: PaymentHash,
+               &$self, payment_paths: Vec<(BlindedPayInfo, BlindedPaymentPath)>, payment_hash: PaymentHash,
                signing_pubkey: PublicKey,
        ) -> Result<$builder, Bolt12SemanticError> {
                let created_at = std::time::SystemTime::now()
@@ -565,7 +566,7 @@ macro_rules! respond_with_explicit_signing_pubkey_methods { ($self: ident, $buil
        ///
        /// [`Bolt12Invoice::created_at`]: crate::offers::invoice::Bolt12Invoice::created_at
        pub fn respond_with_no_std(
-               &$self, payment_paths: Vec<(BlindedPayInfo, BlindedPath)>, payment_hash: PaymentHash,
+               &$self, payment_paths: Vec<(BlindedPayInfo, BlindedPaymentPath)>, payment_hash: PaymentHash,
                signing_pubkey: PublicKey, created_at: Duration
        ) -> Result<$builder, Bolt12SemanticError> {
                if $self.features().requires_unknown_bits() {
@@ -587,7 +588,7 @@ macro_rules! respond_with_derived_signing_pubkey_methods { ($self: ident, $build
        /// [`Bolt12Invoice`]: crate::offers::invoice::Bolt12Invoice
        #[cfg(feature = "std")]
        pub fn respond_using_derived_keys<ES: Deref>(
-               &$self, payment_paths: Vec<(BlindedPayInfo, BlindedPath)>, payment_hash: PaymentHash,
+               &$self, payment_paths: Vec<(BlindedPayInfo, BlindedPaymentPath)>, payment_hash: PaymentHash,
                expanded_key: &ExpandedKey, entropy_source: ES
        ) -> Result<$builder, Bolt12SemanticError>
        where
@@ -611,7 +612,7 @@ macro_rules! respond_with_derived_signing_pubkey_methods { ($self: ident, $build
        ///
        /// [`Bolt12Invoice`]: crate::offers::invoice::Bolt12Invoice
        pub fn respond_using_derived_keys_no_std<ES: Deref>(
-               &$self, payment_paths: Vec<(BlindedPayInfo, BlindedPath)>, payment_hash: PaymentHash,
+               &$self, payment_paths: Vec<(BlindedPayInfo, BlindedPaymentPath)>, payment_hash: PaymentHash,
                created_at: core::time::Duration, expanded_key: &ExpandedKey, entropy_source: ES
        ) -> Result<$builder, Bolt12SemanticError>
        where
index c91496e17a151a0898943b5940479ec331f0470b..fad3bd689122d430a2548b81d1b8df42b24f33fb 100644 (file)
@@ -9,6 +9,7 @@
 
 //! Data structures and encoding for static BOLT 12 invoices.
 
+use crate::blinded_path::payment::BlindedPaymentPath;
 use crate::blinded_path::BlindedPath;
 use crate::io;
 use crate::ln::features::{Bolt12InvoiceFeatures, OfferFeatures};
@@ -70,7 +71,7 @@ pub struct StaticInvoice {
 #[derive(Clone, Debug)]
 struct InvoiceContents {
        offer: OfferContents,
-       payment_paths: Vec<(BlindedPayInfo, BlindedPath)>,
+       payment_paths: Vec<(BlindedPayInfo, BlindedPaymentPath)>,
        created_at: Duration,
        relative_expiry: Option<Duration>,
        fallbacks: Option<Vec<FallbackAddress>>,
@@ -96,7 +97,7 @@ impl<'a> StaticInvoiceBuilder<'a> {
        /// Unless [`StaticInvoiceBuilder::relative_expiry`] is set, the invoice will expire 24 hours
        /// after `created_at`.
        pub fn for_offer_using_derived_keys<T: secp256k1::Signing>(
-               offer: &'a Offer, payment_paths: Vec<(BlindedPayInfo, BlindedPath)>,
+               offer: &'a Offer, payment_paths: Vec<(BlindedPayInfo, BlindedPaymentPath)>,
                message_paths: Vec<BlindedPath>, created_at: Duration, expanded_key: &ExpandedKey,
                nonce: Nonce, secp_ctx: &Secp256k1<T>,
        ) -> Result<Self, Bolt12SemanticError> {
@@ -325,7 +326,7 @@ impl InvoiceContents {
        }
 
        fn new(
-               offer: &Offer, payment_paths: Vec<(BlindedPayInfo, BlindedPath)>,
+               offer: &Offer, payment_paths: Vec<(BlindedPayInfo, BlindedPaymentPath)>,
                message_paths: Vec<BlindedPath>, created_at: Duration, signing_pubkey: PublicKey,
        ) -> Self {
                Self {
@@ -406,7 +407,7 @@ impl InvoiceContents {
                self.offer.supported_quantity()
        }
 
-       fn payment_paths(&self) -> &[(BlindedPayInfo, BlindedPath)] {
+       fn payment_paths(&self) -> &[(BlindedPayInfo, BlindedPaymentPath)] {
                &self.payment_paths[..]
        }
 
index 0c35ee2859878a7bb98171481b5c1fc4132fed2b..ebfb1f3a011fec04bbc46883d404f399dacd53da 100644 (file)
@@ -14,6 +14,7 @@ use bitcoin::secp256k1::schnorr::Signature;
 
 use core::time::Duration;
 use crate::blinded_path::{BlindedHop, BlindedPath, IntroductionNode};
+use crate::blinded_path::payment::BlindedPaymentPath;
 use crate::sign::EntropySource;
 use crate::ln::types::PaymentHash;
 use crate::ln::features::BlindedHopFeatures;
@@ -66,24 +67,24 @@ pub(super) fn privkey(byte: u8) -> SecretKey {
        SecretKey::from_slice(&[byte; 32]).unwrap()
 }
 
-pub(crate) fn payment_paths() -> Vec<(BlindedPayInfo, BlindedPath)> {
+pub(crate) fn payment_paths() -> Vec<(BlindedPayInfo, BlindedPaymentPath)> {
        let paths = vec![
-               BlindedPath {
+               BlindedPaymentPath(BlindedPath {
                        introduction_node: IntroductionNode::NodeId(pubkey(40)),
                        blinding_point: pubkey(41),
                        blinded_hops: vec![
                                BlindedHop { blinded_node_id: pubkey(43), encrypted_payload: vec![0; 43] },
                                BlindedHop { blinded_node_id: pubkey(44), encrypted_payload: vec![0; 44] },
                        ],
-               },
-               BlindedPath {
+               }),
+               BlindedPaymentPath(BlindedPath {
                        introduction_node: IntroductionNode::NodeId(pubkey(40)),
                        blinding_point: pubkey(41),
                        blinded_hops: vec![
                                BlindedHop { blinded_node_id: pubkey(45), encrypted_payload: vec![0; 45] },
                                BlindedHop { blinded_node_id: pubkey(46), encrypted_payload: vec![0; 46] },
                        ],
-               },
+               }),
        ];
 
        let payinfo = vec![
index bf894f0ebb6de49fdae6a62b8078b5644ac36e75..b6be139c009badb06c14ab7d5fb8ee6bcc3a4de4 100644 (file)
@@ -13,7 +13,7 @@ use bitcoin::secp256k1::{PublicKey, Secp256k1, self};
 
 use crate::blinded_path::{BlindedHop, BlindedPath, Direction, IntroductionNode};
 use crate::blinded_path::message::{self, MessageContext};
-use crate::blinded_path::payment::{ForwardTlvs, PaymentConstraints, PaymentRelay, ReceiveTlvs, self};
+use crate::blinded_path::payment::{BlindedPaymentPath, ForwardTlvs, PaymentConstraints, PaymentRelay, ReceiveTlvs, self};
 use crate::ln::{PaymentHash, PaymentPreimage};
 use crate::ln::channel_state::ChannelDetails;
 use crate::ln::channelmanager::{PaymentId, MIN_FINAL_CLTV_EXPIRY_DELTA, RecipientOnionFields};
@@ -94,7 +94,7 @@ impl<G: Deref<Target = NetworkGraph<L>>, L: Deref, ES: Deref, S: Deref, SP: Size
        > (
                &self, recipient: PublicKey, first_hops: Vec<ChannelDetails>, tlvs: ReceiveTlvs,
                amount_msats: u64, secp_ctx: &Secp256k1<T>
-       ) -> Result<Vec<(BlindedPayInfo, BlindedPath)>, ()> {
+       ) -> Result<Vec<(BlindedPayInfo, BlindedPaymentPath)>, ()> {
                // Limit the number of blinded paths that are computed.
                const MAX_PAYMENT_PATHS: usize = 3;
 
@@ -158,7 +158,7 @@ impl<G: Deref<Target = NetworkGraph<L>>, L: Deref, ES: Deref, S: Deref, SP: Size
                                })
                        })
                        .map(|forward_node| {
-                               BlindedPath::new_for_payment(
+                               BlindedPaymentPath::new(
                                        &[forward_node], recipient, tlvs.clone(), u64::MAX, MIN_FINAL_CLTV_EXPIRY_DELTA,
                                        &*self.entropy_source, secp_ctx
                                )
@@ -170,8 +170,9 @@ impl<G: Deref<Target = NetworkGraph<L>>, L: Deref, ES: Deref, S: Deref, SP: Size
                        Ok(paths) if !paths.is_empty() => Ok(paths),
                        _ => {
                                if network_graph.nodes().contains_key(&NodeId::from_pubkey(&recipient)) {
-                                       BlindedPath::one_hop_for_payment(
-                                               recipient, tlvs, MIN_FINAL_CLTV_EXPIRY_DELTA, &*self.entropy_source, secp_ctx
+                                       BlindedPaymentPath::new(
+                                               &[], recipient, tlvs, u64::MAX, MIN_FINAL_CLTV_EXPIRY_DELTA, &*self.entropy_source,
+                                               secp_ctx
                                        ).map(|path| vec![path])
                                } else {
                                        Err(())
@@ -235,7 +236,7 @@ pub trait Router: MessageRouter {
                self.find_route(payer, route_params, first_hops, inflight_htlcs)
        }
 
-       /// Creates [`BlindedPath`]s for payment to the `recipient` node. The channels in `first_hops`
+       /// Creates [`BlindedPaymentPath`]s for payment to the `recipient` node. The channels in `first_hops`
        /// are assumed to be with the `recipient`'s peers. The payment secret and any constraints are
        /// given in `tlvs`.
        fn create_blinded_payment_paths<
@@ -243,7 +244,7 @@ pub trait Router: MessageRouter {
        > (
                &self, recipient: PublicKey, first_hops: Vec<ChannelDetails>, tlvs: ReceiveTlvs,
                amount_msats: u64, secp_ctx: &Secp256k1<T>
-       ) -> Result<Vec<(BlindedPayInfo, BlindedPath)>, ()>;
+       ) -> Result<Vec<(BlindedPayInfo, BlindedPaymentPath)>, ()>;
 }
 
 /// [`ScoreLookUp`] implementation that factors in in-flight HTLC liquidity.
@@ -382,17 +383,15 @@ pub struct RouteHop {
        pub channel_features: ChannelFeatures,
        /// The fee taken on this hop (for paying for the use of the *next* channel in the path).
        /// If this is the last hop in [`Path::hops`]:
-       /// * if we're sending to a [`BlindedPath`], this is the fee paid for use of the entire blinded path
+       /// * if we're sending to a [`BlindedPaymentPath`], this is the fee paid for use of the entire
+       ///   blinded path
        /// * otherwise, this is the full value of this [`Path`]'s part of the payment
-       ///
-       /// [`BlindedPath`]: crate::blinded_path::BlindedPath
        pub fee_msat: u64,
        /// The CLTV delta added for this hop.
        /// If this is the last hop in [`Path::hops`]:
-       /// * if we're sending to a [`BlindedPath`], this is the CLTV delta for the entire blinded path
+       /// * if we're sending to a [`BlindedPaymentPath`], this is the CLTV delta for the entire blinded
+       ///   path
        /// * otherwise, this is the CLTV delta expected at the destination
-       ///
-       /// [`BlindedPath`]: crate::blinded_path::BlindedPath
        pub cltv_expiry_delta: u32,
        /// Indicates whether this hop is possibly announced in the public network graph.
        ///
@@ -421,13 +420,9 @@ impl_writeable_tlv_based!(RouteHop, {
 /// [`Bolt12Invoice`]: crate::offers::invoice::Bolt12Invoice
 #[derive(Clone, Debug, Hash, PartialEq, Eq)]
 pub struct BlindedTail {
-       /// The hops of the [`BlindedPath`] provided by the recipient.
-       ///
-       /// [`BlindedPath`]: crate::blinded_path::BlindedPath
+       /// The hops of the [`BlindedPaymentPath`] provided by the recipient.
        pub hops: Vec<BlindedHop>,
-       /// The blinding point of the [`BlindedPath`] provided by the recipient.
-       ///
-       /// [`BlindedPath`]: crate::blinded_path::BlindedPath
+       /// The blinding point of the [`BlindedPaymentPath`] provided by the recipient.
        pub blinding_point: PublicKey,
        /// Excess CLTV delta added to the recipient's CLTV expiry to deter intermediate nodes from
        /// inferring the destination. May be 0.
@@ -876,7 +871,7 @@ impl PaymentParameters {
        }
 
        /// Creates parameters for paying to a blinded payee from the provided blinded route hints.
-       pub fn blinded(blinded_route_hints: Vec<(BlindedPayInfo, BlindedPath)>) -> Self {
+       pub fn blinded(blinded_route_hints: Vec<(BlindedPayInfo, BlindedPaymentPath)>) -> Self {
                Self {
                        payee: Payee::Blinded { route_hints: blinded_route_hints, features: None },
                        expiry_time: None,
@@ -965,8 +960,8 @@ impl PaymentParameters {
        pub(crate) fn insert_previously_failed_blinded_path(&mut self, failed_blinded_tail: &BlindedTail) {
                let mut found_blinded_tail = false;
                for (idx, (_, path)) in self.payee.blinded_route_hints().iter().enumerate() {
-                       if failed_blinded_tail.hops == path.blinded_hops &&
-                               failed_blinded_tail.blinding_point == path.blinding_point
+                       if failed_blinded_tail.hops == path.0.blinded_hops &&
+                               failed_blinded_tail.blinding_point == path.0.blinding_point
                        {
                                self.previously_failed_blinded_path_idxs.push(idx as u64);
                                found_blinded_tail = true;
@@ -985,7 +980,7 @@ pub enum Payee {
        Blinded {
                /// Aggregated routing info and blinded paths, for routing to the payee without knowing their
                /// node id.
-               route_hints: Vec<(BlindedPayInfo, BlindedPath)>,
+               route_hints: Vec<(BlindedPayInfo, BlindedPaymentPath)>,
                /// Features supported by the payee.
                ///
                /// May be set from the payee's invoice. May be `None` if the invoice does not contain any
@@ -1041,14 +1036,14 @@ impl Payee {
                        _ => None,
                }
        }
-       pub(crate) fn blinded_route_hints(&self) -> &[(BlindedPayInfo, BlindedPath)] {
+       pub(crate) fn blinded_route_hints(&self) -> &[(BlindedPayInfo, BlindedPaymentPath)] {
                match self {
                        Self::Blinded { route_hints, .. } => &route_hints[..],
                        Self::Clear { .. } => &[]
                }
        }
 
-       pub(crate) fn blinded_route_hints_mut(&mut self) -> &mut [(BlindedPayInfo, BlindedPath)] {
+       pub(crate) fn blinded_route_hints_mut(&mut self) -> &mut [(BlindedPayInfo, BlindedPaymentPath)] {
                match self {
                        Self::Blinded { route_hints, .. } => &mut route_hints[..],
                        Self::Clear { .. } => &mut []
@@ -1250,7 +1245,7 @@ pub struct BlindedPathCandidate<'a> {
        /// cryptographic material required to build an HTLC through the given path.
        ///
        /// This is not exported to bindings users as lifetimes are not expressible in most languages.
-       pub hint: &'a (BlindedPayInfo, BlindedPath),
+       pub hint: &'a (BlindedPayInfo, BlindedPaymentPath),
        /// Index of the hint in the original list of blinded hints.
        ///
        /// This is used to cheaply uniquely identify this blinded path, even though we don't have
@@ -1279,7 +1274,7 @@ pub struct OneHopBlindedPathCandidate<'a> {
        /// Note that the [`BlindedPayInfo`] is ignored here.
        ///
        /// This is not exported to bindings users as lifetimes are not expressible in most languages.
-       pub hint: &'a (BlindedPayInfo, BlindedPath),
+       pub hint: &'a (BlindedPayInfo, BlindedPaymentPath),
        /// Index of the hint in the original list of blinded hints.
        ///
        /// This is used to cheaply uniquely identify this blinded path, even though we don't have
@@ -1487,7 +1482,7 @@ impl<'a> CandidateRouteHop<'a> {
                        _ => CandidateHopId::Clear((self.short_channel_id().unwrap(), self.source() < self.target().unwrap())),
                }
        }
-       fn blinded_path(&self) -> Option<&'a BlindedPath> {
+       fn blinded_path(&self) -> Option<&'a BlindedPaymentPath> {
                match self {
                        CandidateRouteHop::Blinded(BlindedPathCandidate { hint, .. }) | CandidateRouteHop::OneHopBlinded(OneHopBlindedPathCandidate { hint, .. }) => {
                                Some(&hint.1)
@@ -1644,14 +1639,14 @@ fn calculate_blinded_path_intro_points<'a, L: Deref>(
 where L::Target: Logger {
        let introduction_node_id_cache = payment_params.payee.blinded_route_hints().iter()
                .map(|(_, path)| {
-                       match &path.introduction_node {
+                       match &path.0.introduction_node {
                                IntroductionNode::NodeId(pubkey) => {
                                        // Note that this will only return `Some` if the `pubkey` is somehow known to
                                        // us (i.e. a channel counterparty or in the network graph).
                                        node_counters.node_counter_from_id(&NodeId::from_pubkey(&pubkey))
                                },
                                IntroductionNode::DirectedShortChannelId(direction, scid) => {
-                                       path.public_introduction_node_id(network_graph)
+                                       path.0.public_introduction_node_id(network_graph)
                                                .map(|node_id_ref| *node_id_ref)
                                                .or_else(|| {
                                                        first_hop_targets.iter().find(|(_, (channels, _))|
@@ -1683,7 +1678,7 @@ where L::Target: Logger {
                                return Err(LightningError{err: "Cannot generate a route to blinded paths if we are the introduction node to all of them".to_owned(), action: ErrorAction::IgnoreError});
                        }
                        for ((_, blinded_path), info_opt) in route_hints.iter().zip(introduction_node_id_cache.iter()) {
-                               if blinded_path.blinded_hops.len() == 0 {
+                               if blinded_path.0.blinded_hops.len() == 0 {
                                        return Err(LightningError{err: "0-hop blinded path provided".to_owned(), action: ErrorAction::IgnoreError});
                                }
                                let introduction_node_id = match info_opt {
@@ -1692,10 +1687,10 @@ where L::Target: Logger {
                                };
                                if *introduction_node_id == our_node_id {
                                        log_info!(logger, "Got blinded path with ourselves as the introduction node, ignoring");
-                               } else if blinded_path.blinded_hops.len() == 1 &&
+                               } else if blinded_path.0.blinded_hops.len() == 1 &&
                                        route_hints
                                                .iter().zip(introduction_node_id_cache.iter())
-                                               .filter(|((_, p), _)| p.blinded_hops.len() == 1)
+                                               .filter(|((_, p), _)| p.0.blinded_hops.len() == 1)
                                                .any(|(_, iter_info_opt)| iter_info_opt.is_some() && iter_info_opt != info_opt)
                                {
                                        return Err(LightningError{err: format!("1-hop blinded paths must all have matching introduction node ids"), action: ErrorAction::IgnoreError});
@@ -1978,7 +1973,7 @@ impl<'a> fmt::Display for LoggedCandidateHop<'a> {
                match self.0 {
                        CandidateRouteHop::Blinded(BlindedPathCandidate { hint, .. }) | CandidateRouteHop::OneHopBlinded(OneHopBlindedPathCandidate { hint, .. }) => {
                                "blinded route hint with introduction node ".fmt(f)?;
-                               match &hint.1.introduction_node {
+                               match &hint.1.0.introduction_node {
                                        IntroductionNode::NodeId(pubkey) => write!(f, "id {}", pubkey)?,
                                        IntroductionNode::DirectedShortChannelId(direction, scid) => {
                                                match direction {
@@ -1992,7 +1987,7 @@ impl<'a> fmt::Display for LoggedCandidateHop<'a> {
                                        }
                                }
                                " and blinding point ".fmt(f)?;
-                               hint.1.blinding_point.fmt(f)
+                               hint.1.0.blinding_point.fmt(f)
                        },
                        CandidateRouteHop::FirstHop(_) => {
                                "first hop with SCID ".fmt(f)?;
@@ -2825,7 +2820,7 @@ where L::Target: Logger {
                        let source_node_opt = introduction_node_id_cache[hint_idx];
                        let (source_node_id, source_node_counter) = if let Some(v) = source_node_opt { v } else { continue };
                        if our_node_id == *source_node_id { continue }
-                       let candidate = if hint.1.blinded_hops.len() == 1 {
+                       let candidate = if hint.1.0.blinded_hops.len() == 1 {
                                CandidateRouteHop::OneHopBlinded(
                                        OneHopBlindedPathCandidate { source_node_counter, source_node_id, hint, hint_idx }
                                )
@@ -3348,8 +3343,8 @@ where L::Target: Logger {
                        if let Some(blinded_path) = h.candidate.blinded_path() {
                                final_cltv_delta = h.candidate.cltv_expiry_delta();
                                Some(BlindedTail {
-                                       hops: blinded_path.blinded_hops.clone(),
-                                       blinding_point: blinded_path.blinding_point,
+                                       hops: blinded_path.0.blinded_hops.clone(),
+                                       blinding_point: blinded_path.0.blinding_point,
                                        excess_final_cltv_expiry_delta: 0,
                                        final_value_msat: h.fee_msat,
                                })
@@ -3547,6 +3542,7 @@ fn build_route_from_hops_internal<L: Deref>(
 #[cfg(test)]
 mod tests {
        use crate::blinded_path::{BlindedHop, BlindedPath, IntroductionNode};
+       use crate::blinded_path::payment::BlindedPaymentPath;
        use crate::routing::gossip::{NetworkGraph, P2PGossipSync, NodeId, EffectiveCapacity};
        use crate::routing::utxo::UtxoResult;
        use crate::routing::router::{get_route, build_route_from_hops_internal, add_random_cltv_offset, default_node_features,
@@ -5453,11 +5449,11 @@ mod tests {
 
                // MPP to a 1-hop blinded path for nodes[2]
                let bolt12_features = channelmanager::provided_bolt12_invoice_features(&config);
-               let blinded_path = BlindedPath {
+               let blinded_path = BlindedPaymentPath(BlindedPath {
                        introduction_node: IntroductionNode::NodeId(nodes[2]),
                        blinding_point: ln_test_utils::pubkey(42),
                        blinded_hops: vec![BlindedHop { blinded_node_id: ln_test_utils::pubkey(42 as u8), encrypted_payload: Vec::new() }],
-               };
+               });
                let blinded_payinfo = BlindedPayInfo { // These fields are ignored for 1-hop blinded paths
                        fee_base_msat: 0,
                        fee_proportional_millionths: 0,
@@ -5472,18 +5468,18 @@ mod tests {
 
                // MPP to 3 2-hop blinded paths
                let mut blinded_path_node_0 = blinded_path.clone();
-               blinded_path_node_0.introduction_node = IntroductionNode::NodeId(nodes[0]);
-               blinded_path_node_0.blinded_hops.push(blinded_path.blinded_hops[0].clone());
+               blinded_path_node_0.0.introduction_node = IntroductionNode::NodeId(nodes[0]);
+               blinded_path_node_0.0.blinded_hops.push(blinded_path.0.blinded_hops[0].clone());
                let mut node_0_payinfo = blinded_payinfo.clone();
                node_0_payinfo.htlc_maximum_msat = 50_000;
 
                let mut blinded_path_node_7 = blinded_path_node_0.clone();
-               blinded_path_node_7.introduction_node = IntroductionNode::NodeId(nodes[7]);
+               blinded_path_node_7.0.introduction_node = IntroductionNode::NodeId(nodes[7]);
                let mut node_7_payinfo = blinded_payinfo.clone();
                node_7_payinfo.htlc_maximum_msat = 60_000;
 
                let mut blinded_path_node_1 = blinded_path_node_0.clone();
-               blinded_path_node_1.introduction_node = IntroductionNode::NodeId(nodes[1]);
+               blinded_path_node_1.0.introduction_node = IntroductionNode::NodeId(nodes[1]);
                let mut node_1_payinfo = blinded_payinfo.clone();
                node_1_payinfo.htlc_maximum_msat = 180_000;
 
@@ -5675,7 +5671,7 @@ mod tests {
                                                        NodeId::from_pubkey(&path.hops.last().unwrap().pubkey),
                                                        payment_params.payee.blinded_route_hints().iter()
                                                                .find(|(p, _)| p.htlc_maximum_msat == path.final_value_msat())
-                                                               .and_then(|(_, p)| p.public_introduction_node_id(&network_graph))
+                                                               .and_then(|(_, p)| p.0.public_introduction_node_id(&network_graph))
                                                                .copied()
                                                                .unwrap()
                                                );
@@ -7648,14 +7644,14 @@ mod tests {
                assert_eq!(route.get_total_amount(), amt_msat);
 
                // Make sure this works for blinded route hints.
-               let blinded_path = BlindedPath {
+               let blinded_path = BlindedPaymentPath(BlindedPath {
                        introduction_node: IntroductionNode::NodeId(intermed_node_id),
                        blinding_point: ln_test_utils::pubkey(42),
                        blinded_hops: vec![
                                BlindedHop { blinded_node_id: ln_test_utils::pubkey(42), encrypted_payload: vec![] },
                                BlindedHop { blinded_node_id: ln_test_utils::pubkey(43), encrypted_payload: vec![] },
                        ],
-               };
+               });
                let blinded_payinfo = BlindedPayInfo {
                        fee_base_msat: 100,
                        fee_proportional_millionths: 0,
@@ -7847,13 +7843,13 @@ mod tests {
                let scorer = ln_test_utils::TestScorer::new();
                let random_seed_bytes = [42; 32];
 
-               let mut blinded_path = BlindedPath {
+               let mut blinded_path = BlindedPaymentPath(BlindedPath {
                        introduction_node: IntroductionNode::NodeId(nodes[2]),
                        blinding_point: ln_test_utils::pubkey(42),
                        blinded_hops: Vec::with_capacity(num_blinded_hops),
-               };
+               });
                for i in 0..num_blinded_hops {
-                       blinded_path.blinded_hops.push(
+                       blinded_path.0.blinded_hops.push(
                                BlindedHop { blinded_node_id: ln_test_utils::pubkey(42 + i as u8), encrypted_payload: Vec::new() },
                        );
                }
@@ -7875,14 +7871,14 @@ mod tests {
                assert_eq!(route.paths[0].hops.len(), 2);
 
                let tail = route.paths[0].blinded_tail.as_ref().unwrap();
-               assert_eq!(tail.hops, blinded_path.blinded_hops);
+               assert_eq!(tail.hops, blinded_path.0.blinded_hops);
                assert_eq!(tail.excess_final_cltv_expiry_delta, 0);
                assert_eq!(tail.final_value_msat, 1001);
 
                let final_hop = route.paths[0].hops.last().unwrap();
                assert_eq!(
                        NodeId::from_pubkey(&final_hop.pubkey),
-                       *blinded_path.public_introduction_node_id(&network_graph).unwrap()
+                       *blinded_path.0.public_introduction_node_id(&network_graph).unwrap()
                );
                if tail.hops.len() > 1 {
                        assert_eq!(final_hop.fee_msat,
@@ -7904,13 +7900,13 @@ mod tests {
                let scorer = ln_test_utils::TestScorer::new();
                let random_seed_bytes = [42; 32];
 
-               let mut invalid_blinded_path = BlindedPath {
+               let mut invalid_blinded_path = BlindedPaymentPath(BlindedPath {
                        introduction_node: IntroductionNode::NodeId(nodes[2]),
                        blinding_point: ln_test_utils::pubkey(42),
                        blinded_hops: vec![
                                BlindedHop { blinded_node_id: ln_test_utils::pubkey(43), encrypted_payload: vec![0; 43] },
                        ],
-               };
+               });
                let blinded_payinfo = BlindedPayInfo {
                        fee_base_msat: 100,
                        fee_proportional_millionths: 500,
@@ -7921,7 +7917,7 @@ mod tests {
                };
 
                let mut invalid_blinded_path_2 = invalid_blinded_path.clone();
-               invalid_blinded_path_2.introduction_node = IntroductionNode::NodeId(nodes[3]);
+               invalid_blinded_path_2.0.introduction_node = IntroductionNode::NodeId(nodes[3]);
                let payment_params = PaymentParameters::blinded(vec![
                        (blinded_payinfo.clone(), invalid_blinded_path.clone()),
                        (blinded_payinfo.clone(), invalid_blinded_path_2)]);
@@ -7935,7 +7931,7 @@ mod tests {
                        _ => panic!("Expected error")
                }
 
-               invalid_blinded_path.introduction_node = IntroductionNode::NodeId(our_id);
+               invalid_blinded_path.0.introduction_node = IntroductionNode::NodeId(our_id);
                let payment_params = PaymentParameters::blinded(vec![(blinded_payinfo.clone(), invalid_blinded_path.clone())]);
                let route_params = RouteParameters::from_payment_params_and_value(payment_params, 1001);
                match get_route(&our_id, &route_params, &network_graph, None, Arc::clone(&logger), &scorer,
@@ -7947,8 +7943,8 @@ mod tests {
                        _ => panic!("Expected error")
                }
 
-               invalid_blinded_path.introduction_node = IntroductionNode::NodeId(ln_test_utils::pubkey(46));
-               invalid_blinded_path.blinded_hops.clear();
+               invalid_blinded_path.0.introduction_node = IntroductionNode::NodeId(ln_test_utils::pubkey(46));
+               invalid_blinded_path.0.blinded_hops.clear();
                let payment_params = PaymentParameters::blinded(vec![(blinded_payinfo, invalid_blinded_path)]);
                let route_params = RouteParameters::from_payment_params_and_value(payment_params, 1001);
                match get_route(&our_id, &route_params, &network_graph, None, Arc::clone(&logger), &scorer,
@@ -7974,14 +7970,14 @@ mod tests {
                let config = UserConfig::default();
 
                let bolt12_features = channelmanager::provided_bolt12_invoice_features(&config);
-               let blinded_path_1 = BlindedPath {
+               let blinded_path_1 = BlindedPaymentPath(BlindedPath {
                        introduction_node: IntroductionNode::NodeId(nodes[2]),
                        blinding_point: ln_test_utils::pubkey(42),
                        blinded_hops: vec![
                                BlindedHop { blinded_node_id: ln_test_utils::pubkey(42 as u8), encrypted_payload: Vec::new() },
                                BlindedHop { blinded_node_id: ln_test_utils::pubkey(42 as u8), encrypted_payload: Vec::new() }
                        ],
-               };
+               });
                let blinded_payinfo_1 = BlindedPayInfo {
                        fee_base_msat: 0,
                        fee_proportional_millionths: 0,
@@ -7992,7 +7988,7 @@ mod tests {
                };
 
                let mut blinded_path_2 = blinded_path_1.clone();
-               blinded_path_2.blinding_point = ln_test_utils::pubkey(43);
+               blinded_path_2.0.blinding_point = ln_test_utils::pubkey(43);
                let mut blinded_payinfo_2 = blinded_payinfo_1.clone();
                blinded_payinfo_2.htlc_maximum_msat = 70_000;
 
@@ -8014,7 +8010,7 @@ mod tests {
                        if let Some(bt) = &path.blinded_tail {
                                assert_eq!(bt.blinding_point,
                                        blinded_hints.iter().find(|(p, _)| p.htlc_maximum_msat == path.final_value_msat())
-                                               .map(|(_, bp)| bp.blinding_point).unwrap());
+                                               .map(|(_, bp)| bp.0.blinding_point).unwrap());
                        } else { panic!(); }
                        total_amount_paid_msat += path.final_value_msat();
                }
@@ -8072,14 +8068,14 @@ mod tests {
                let first_hops = vec![
                        get_channel_details(Some(1), nodes[1], InitFeatures::from_le_bytes(vec![0b11]), 10_000_000)];
 
-               let blinded_path = BlindedPath {
+               let blinded_path = BlindedPaymentPath(BlindedPath {
                        introduction_node: IntroductionNode::NodeId(nodes[1]),
                        blinding_point: ln_test_utils::pubkey(42),
                        blinded_hops: vec![
                                BlindedHop { blinded_node_id: ln_test_utils::pubkey(42 as u8), encrypted_payload: Vec::new() },
                                BlindedHop { blinded_node_id: ln_test_utils::pubkey(42 as u8), encrypted_payload: Vec::new() }
                        ],
-               };
+               });
                let blinded_payinfo = BlindedPayInfo {
                        fee_base_msat: 1000,
                        fee_proportional_millionths: 0,
@@ -8140,14 +8136,14 @@ mod tests {
                        get_channel_details(Some(1), nodes[1], channelmanager::provided_init_features(&config),
                                18446744073709551615)];
 
-               let blinded_path = BlindedPath {
+               let blinded_path = BlindedPaymentPath(BlindedPath {
                        introduction_node: IntroductionNode::NodeId(nodes[1]),
                        blinding_point: ln_test_utils::pubkey(42),
                        blinded_hops: vec![
                                BlindedHop { blinded_node_id: ln_test_utils::pubkey(42 as u8), encrypted_payload: Vec::new() },
                                BlindedHop { blinded_node_id: ln_test_utils::pubkey(42 as u8), encrypted_payload: Vec::new() }
                        ],
-               };
+               });
                let blinded_payinfo = BlindedPayInfo {
                        fee_base_msat: 5046_2720,
                        fee_proportional_millionths: 0,
@@ -8195,14 +8191,14 @@ mod tests {
                // Values are taken from the fuzz input that uncovered this panic.
                let amt_msat = 21_7020_5185_1423_0019;
 
-               let blinded_path = BlindedPath {
+               let blinded_path = BlindedPaymentPath(BlindedPath {
                        introduction_node: IntroductionNode::NodeId(our_id),
                        blinding_point: ln_test_utils::pubkey(42),
                        blinded_hops: vec![
                                BlindedHop { blinded_node_id: ln_test_utils::pubkey(42 as u8), encrypted_payload: Vec::new() },
                                BlindedHop { blinded_node_id: ln_test_utils::pubkey(42 as u8), encrypted_payload: Vec::new() }
                        ],
-               };
+               });
                let blinded_payinfo = BlindedPayInfo {
                        fee_base_msat: 5052_9027,
                        fee_proportional_millionths: 0,
@@ -8215,7 +8211,7 @@ mod tests {
                        (blinded_payinfo.clone(), blinded_path.clone()),
                        (blinded_payinfo.clone(), blinded_path.clone()),
                ];
-               blinded_hints[1].1.introduction_node = IntroductionNode::NodeId(nodes[6]);
+               blinded_hints[1].1.0.introduction_node = IntroductionNode::NodeId(nodes[6]);
 
                let bolt12_features = channelmanager::provided_bolt12_invoice_features(&config);
                let payment_params = PaymentParameters::blinded(blinded_hints.clone())
@@ -8246,14 +8242,14 @@ mod tests {
                // Values are taken from the fuzz input that uncovered this panic.
                let amt_msat = 21_7020_5185_1423_0019;
 
-               let blinded_path = BlindedPath {
+               let blinded_path = BlindedPaymentPath(BlindedPath {
                        introduction_node: IntroductionNode::NodeId(our_id),
                        blinding_point: ln_test_utils::pubkey(42),
                        blinded_hops: vec![
                                BlindedHop { blinded_node_id: ln_test_utils::pubkey(42 as u8), encrypted_payload: Vec::new() },
                                BlindedHop { blinded_node_id: ln_test_utils::pubkey(42 as u8), encrypted_payload: Vec::new() }
                        ],
-               };
+               });
                let blinded_payinfo = BlindedPayInfo {
                        fee_base_msat: 10_4425_1395,
                        fee_proportional_millionths: 0,
@@ -8271,7 +8267,7 @@ mod tests {
                blinded_hints[1].0.htlc_minimum_msat = 21_7020_5185_1423_0019;
                blinded_hints[1].0.htlc_maximum_msat = 1844_6744_0737_0955_1615;
 
-               blinded_hints[2].1.introduction_node = IntroductionNode::NodeId(nodes[6]);
+               blinded_hints[2].1.0.introduction_node = IntroductionNode::NodeId(nodes[6]);
 
                let bolt12_features = channelmanager::provided_bolt12_invoice_features(&config);
                let payment_params = PaymentParameters::blinded(blinded_hints.clone())
@@ -8316,14 +8312,14 @@ mod tests {
                let base_fee = 1_6778_3453;
                let htlc_min = 2_5165_8240;
                let payment_params = if blinded_payee {
-                       let blinded_path = BlindedPath {
+                       let blinded_path = BlindedPaymentPath(BlindedPath {
                                introduction_node: IntroductionNode::NodeId(nodes[0]),
                                blinding_point: ln_test_utils::pubkey(42),
                                blinded_hops: vec![
                                        BlindedHop { blinded_node_id: ln_test_utils::pubkey(42 as u8), encrypted_payload: Vec::new() },
                                        BlindedHop { blinded_node_id: ln_test_utils::pubkey(42 as u8), encrypted_payload: Vec::new() }
                                ],
-                       };
+                       });
                        let blinded_payinfo = BlindedPayInfo {
                                fee_base_msat: base_fee,
                                fee_proportional_millionths: 0,
@@ -8395,14 +8391,14 @@ mod tests {
                let base_fees = [0, 425_9840, 0, 0];
                let htlc_mins = [1_4392, 19_7401, 1027, 6_5535];
                let payment_params = if blinded_payee {
-                       let blinded_path = BlindedPath {
+                       let blinded_path = BlindedPaymentPath(BlindedPath {
                                introduction_node: IntroductionNode::NodeId(nodes[0]),
                                blinding_point: ln_test_utils::pubkey(42),
                                blinded_hops: vec![
                                        BlindedHop { blinded_node_id: ln_test_utils::pubkey(42 as u8), encrypted_payload: Vec::new() },
                                        BlindedHop { blinded_node_id: ln_test_utils::pubkey(42 as u8), encrypted_payload: Vec::new() }
                                ],
-                       };
+                       });
                        let mut blinded_hints = Vec::new();
                        for (base_fee, htlc_min) in base_fees.iter().zip(htlc_mins.iter()) {
                                blinded_hints.push((BlindedPayInfo {
@@ -8496,14 +8492,14 @@ mod tests {
                                htlc_maximum_msat: htlc_min * 100,
                                cltv_expiry_delta: 10,
                                features: BlindedHopFeatures::empty(),
-                       }, BlindedPath {
+                       }, BlindedPaymentPath(BlindedPath {
                                introduction_node: IntroductionNode::NodeId(nodes[0]),
                                blinding_point: ln_test_utils::pubkey(42),
                                blinded_hops: vec![
                                        BlindedHop { blinded_node_id: ln_test_utils::pubkey(42 as u8), encrypted_payload: Vec::new() },
                                        BlindedHop { blinded_node_id: ln_test_utils::pubkey(42 as u8), encrypted_payload: Vec::new() }
                                ],
-                       })
+                       }))
                ];
                let bolt12_features = channelmanager::provided_bolt12_invoice_features(&config);
                let payment_params = PaymentParameters::blinded(blinded_hints.clone())
@@ -8545,14 +8541,14 @@ mod tests {
 
                let htlc_mins = [49_0000, 1125_0000];
                let payment_params = {
-                       let blinded_path = BlindedPath {
+                       let blinded_path = BlindedPaymentPath(BlindedPath {
                                introduction_node: IntroductionNode::NodeId(nodes[0]),
                                blinding_point: ln_test_utils::pubkey(42),
                                blinded_hops: vec![
                                        BlindedHop { blinded_node_id: ln_test_utils::pubkey(42 as u8), encrypted_payload: Vec::new() },
                                        BlindedHop { blinded_node_id: ln_test_utils::pubkey(42 as u8), encrypted_payload: Vec::new() }
                                ],
-                       };
+                       });
                        let mut blinded_hints = Vec::new();
                        for htlc_min in htlc_mins.iter() {
                                blinded_hints.push((BlindedPayInfo {
index f5256064edf84a3657f4758e812d7da007798c6e..2f2a48bd61f4199ad3ecdbee02f0e1bfe70530b9 100644 (file)
@@ -10,7 +10,7 @@
 use crate::blinded_path::message::MessageContext;
 use crate::blinded_path::BlindedPath;
 use crate::blinded_path::message::ForwardNode;
-use crate::blinded_path::payment::ReceiveTlvs;
+use crate::blinded_path::payment::{BlindedPaymentPath, ReceiveTlvs};
 use crate::chain;
 use crate::chain::WatchedOutput;
 use crate::chain::chaininterface;
@@ -120,7 +120,7 @@ pub struct TestRouter<'a> {
        >,
        pub network_graph: Arc<NetworkGraph<&'a TestLogger>>,
        pub next_routes: Mutex<VecDeque<(RouteParameters, Option<Result<Route, LightningError>>)>>,
-       pub next_blinded_payment_paths: Mutex<Vec<(BlindedPayInfo, BlindedPath)>>,
+       pub next_blinded_payment_paths: Mutex<Vec<(BlindedPayInfo, BlindedPaymentPath)>>,
        pub scorer: &'a RwLock<TestScorer>,
 }
 
@@ -149,7 +149,7 @@ impl<'a> TestRouter<'a> {
                expected_routes.push_back((query, None));
        }
 
-       pub fn expect_blinded_payment_paths(&self, mut paths: Vec<(BlindedPayInfo, BlindedPath)>) {
+       pub fn expect_blinded_payment_paths(&self, mut paths: Vec<(BlindedPayInfo, BlindedPaymentPath)>) {
                let mut expected_paths = self.next_blinded_payment_paths.lock().unwrap();
                core::mem::swap(&mut *expected_paths, &mut paths);
        }
@@ -247,7 +247,7 @@ impl<'a> Router for TestRouter<'a> {
        >(
                &self, recipient: PublicKey, first_hops: Vec<ChannelDetails>, tlvs: ReceiveTlvs,
                amount_msats: u64, secp_ctx: &Secp256k1<T>,
-       ) -> Result<Vec<(BlindedPayInfo, BlindedPath)>, ()> {
+       ) -> Result<Vec<(BlindedPayInfo, BlindedPaymentPath)>, ()> {
                let mut expected_paths = self.next_blinded_payment_paths.lock().unwrap();
                if expected_paths.is_empty() {
                        self.router.create_blinded_payment_paths(