From caa836e8e5cd1ab2f3f67d196ced7c26c58c0f18 Mon Sep 17 00:00:00 2001 From: Valentine Wallace Date: Mon, 5 Aug 2024 15:18:26 -0700 Subject: [PATCH] Add BlindedPaymentPath type, to disambiguate from message paths. Next up, we'll add a BlindedMessagePath type so the API is clear which type of path is expected in each context. --- fuzz/src/chanmon_consistency.rs | 4 +- fuzz/src/full_stack.rs | 4 +- fuzz/src/invoice_request_deser.rs | 7 +- fuzz/src/refund_deser.rs | 7 +- fuzz/src/router.rs | 7 +- lightning/src/blinded_path/mod.rs | 47 ------ lightning/src/blinded_path/payment.rs | 88 ++++++++-- lightning/src/ln/blinded_payment_tests.rs | 19 +-- lightning/src/ln/channelmanager.rs | 8 +- .../src/ln/max_payment_path_len_tests.rs | 14 +- lightning/src/ln/offers_tests.rs | 14 +- lightning/src/ln/onion_utils.rs | 4 +- lightning/src/ln/outbound_payment.rs | 8 +- lightning/src/offers/invoice.rs | 37 +++-- lightning/src/offers/invoice_macros.rs | 2 +- lightning/src/offers/invoice_request.rs | 11 +- lightning/src/offers/refund.rs | 9 +- lightning/src/offers/static_invoice.rs | 9 +- lightning/src/offers/test_utils.rs | 11 +- lightning/src/routing/router.rs | 156 +++++++++--------- lightning/src/util/test_utils.rs | 8 +- 21 files changed, 243 insertions(+), 231 deletions(-) diff --git a/fuzz/src/chanmon_consistency.rs b/fuzz/src/chanmon_consistency.rs index 4322fccb1..249d1e51b 100644 --- a/fuzz/src/chanmon_consistency.rs +++ b/fuzz/src/chanmon_consistency.rs @@ -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( &self, _recipient: PublicKey, _first_hops: Vec, _tlvs: ReceiveTlvs, _amount_msats: u64, _secp_ctx: &Secp256k1, - ) -> Result, ()> { + ) -> Result, ()> { unreachable!() } } diff --git a/fuzz/src/full_stack.rs b/fuzz/src/full_stack.rs index fa0c29062..ed5f123e8 100644 --- a/fuzz/src/full_stack.rs +++ b/fuzz/src/full_stack.rs @@ -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( &self, _recipient: PublicKey, _first_hops: Vec, _tlvs: ReceiveTlvs, _amount_msats: u64, _secp_ctx: &Secp256k1, - ) -> Result, ()> { + ) -> Result, ()> { unreachable!() } } diff --git a/fuzz/src/invoice_request_deser.rs b/fuzz/src/invoice_request_deser.rs index d418cbe51..a5db1c4be 100644 --- a/fuzz/src/invoice_request_deser.rs +++ b/fuzz/src/invoice_request_deser.rs @@ -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( 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, diff --git a/fuzz/src/refund_deser.rs b/fuzz/src/refund_deser.rs index 5a6922806..58dc68eed 100644 --- a/fuzz/src/refund_deser.rs +++ b/fuzz/src/refund_deser.rs @@ -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( 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, diff --git a/fuzz/src/router.rs b/fuzz/src/router.rs index 96046f258..e0fadf44b 100644 --- a/fuzz/src/router.rs +++ b/fuzz/src/router.rs @@ -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(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(data: &[u8], out: Out) { } ( payinfo, - BlindedPath { + BlindedPaymentPath(BlindedPath { introduction_node: IntroductionNode::NodeId(hop.src_node_id), blinding_point: dummy_pk, blinded_hops, - }, + }), ) }) .collect(); diff --git a/lightning/src/blinded_path/mod.rs b/lightning/src/blinded_path/mod.rs index e34e64c7a..be6d315af 100644 --- a/lightning/src/blinded_path/mod.rs +++ b/lightning/src/blinded_path/mod.rs @@ -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( - payee_node_id: PublicKey, payee_tlvs: payment::ReceiveTlvs, min_final_cltv_expiry_delta: u16, - entropy_source: ES, secp_ctx: &Secp256k1 - ) -> 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( - 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 - ) -> 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>( diff --git a/lightning/src/blinded_path/payment.rs b/lightning/src/blinded_path/payment.rs index 8c892e896..a7191656a 100644 --- a/lightning/src/blinded_path/payment.rs +++ b/lightning/src/blinded_path/payment.rs @@ -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(&self, w: &mut W) -> Result<(), io::Error> { + self.0.write(w) + } +} + +impl Readable for BlindedPaymentPath { + fn read(r: &mut R) -> Result { + Ok(Self(BlindedPath::read(r)?)) + } +} + +impl BlindedPaymentPath { + /// Create a one-hop blinded path for a payment. + pub fn one_hop( + payee_node_id: PublicKey, payee_tlvs: ReceiveTlvs, min_final_cltv_expiry_delta: u16, + entropy_source: ES, secp_ctx: &Secp256k1 + ) -> 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( + 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 + ) -> 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( // // Will only modify `path` when returning `Ok`. pub(crate) fn advance_path_by_one( - path: &mut BlindedPath, node_signer: &NS, node_id_lookup: &NL, secp_ctx: &Secp256k1 + path: &mut BlindedPaymentPath, node_signer: &NS, node_id_lookup: &NL, secp_ctx: &Secp256k1 ) -> 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(()) diff --git a/lightning/src/ln/blinded_payment_tests.rs b/lightning/src/ln/blinded_payment_tests.rs index 9d246f1a7..b13b1e04d 100644 --- a/lightning/src/ln/blinded_payment_tests.rs +++ b/lightning/src/ln/blinded_payment_tests.rs @@ -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, 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(); diff --git a/lightning/src/ln/channelmanager.rs b/lightning/src/ln/channelmanager.rs index c6645956b..e3e9bcfe8 100644 --- a/lightning/src/ln/channelmanager.rs +++ b/lightning/src/ln/channelmanager.rs @@ -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, ()> { + ) -> Result, ()> { let secp_ctx = &self.secp_ctx; let first_hops = self.list_usable_channels(); diff --git a/lightning/src/ln/max_payment_path_len_tests.rs b/lightning/src/ln/max_payment_path_len_tests.rs index 096bcf963..f3ce1c39a 100644 --- a/lightning/src/ln/max_payment_path_len_tests.rs +++ b/lightning/src/ln/max_payment_path_len_tests.rs @@ -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(); diff --git a/lightning/src/ln/offers_tests.rs b/lightning/src/ln/offers_tests.rs index fd496b5f6..9302227dc 100644 --- a/lightning/src/ln/offers_tests.rs +++ b/lightning/src/ln/offers_tests.rs @@ -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)); } } diff --git a/lightning/src/ln/onion_utils.rs b/lightning/src/ln/onion_utils.rs index d6fe281d1..dbb76e87f 100644 --- a/lightning/src/ln/onion_utils.rs +++ b/lightning/src/ln/onion_utils.rs @@ -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, }); diff --git a/lightning/src/ln/outbound_payment.rs b/lightning/src/ln/outbound_payment.rs index c36f2c5c1..541a70411 100644 --- a/lightning/src/ln/outbound_payment.rs +++ b/lightning/src/ln/outbound_payment.rs @@ -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) { diff --git a/lightning/src/offers/invoice.rs b/lightning/src/offers/invoice.rs index 3fd2e73aa..af9f28d90 100644 --- a/lightning/src/offers/invoice.rs +++ b/lightning/src/offers/invoice.rs @@ -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) -> 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 { 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 { 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 { 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 { 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, 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> for Bolt12Invoice { } tlv_stream!(InvoiceTlvStream, InvoiceTlvStreamRef, 160..240, { - (160, paths: (Vec, WithoutLength, Iterable<'a, BlindedPathIter<'a>, BlindedPath>)), + (160, paths: (Vec, WithoutLength, Iterable<'a, BlindedPathIter<'a>, BlindedPaymentPath>)), (162, blindedpay: (Vec, 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 for InvoiceContents { } pub(super) fn construct_payment_paths( - blinded_payinfos: Option>, blinded_paths: Option> -) -> Result, Bolt12SemanticError> { + blinded_payinfos: Option>, blinded_paths: Option> +) -> Result, Bolt12SemanticError> { match (blinded_payinfos, blinded_paths) { (_, None) => Err(Bolt12SemanticError::MissingPaths), (None, _) => Err(Bolt12SemanticError::InvalidPayInfo), diff --git a/lightning/src/offers/invoice_macros.rs b/lightning/src/offers/invoice_macros.rs index c603c352c..a06c0663a 100644 --- a/lightning/src/offers/invoice_macros.rs +++ b/lightning/src/offers/invoice_macros.rs @@ -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() } diff --git a/lightning/src/offers/invoice_request.rs b/lightning/src/offers/invoice_request.rs index 6ed9b2a12..66ed8b1d0 100644 --- a/lightning/src/offers/invoice_request.rs +++ b/lightning/src/offers/invoice_request.rs @@ -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() { diff --git a/lightning/src/offers/refund.rs b/lightning/src/offers/refund.rs index 10f56f0a1..1835a099f 100644 --- a/lightning/src/offers/refund.rs +++ b/lightning/src/offers/refund.rs @@ -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( - &$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( - &$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 diff --git a/lightning/src/offers/static_invoice.rs b/lightning/src/offers/static_invoice.rs index c91496e17..fad3bd689 100644 --- a/lightning/src/offers/static_invoice.rs +++ b/lightning/src/offers/static_invoice.rs @@ -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, fallbacks: Option>, @@ -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( - offer: &'a Offer, payment_paths: Vec<(BlindedPayInfo, BlindedPath)>, + offer: &'a Offer, payment_paths: Vec<(BlindedPayInfo, BlindedPaymentPath)>, message_paths: Vec, created_at: Duration, expanded_key: &ExpandedKey, nonce: Nonce, secp_ctx: &Secp256k1, ) -> Result { @@ -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, 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[..] } diff --git a/lightning/src/offers/test_utils.rs b/lightning/src/offers/test_utils.rs index 0c35ee285..ebfb1f3a0 100644 --- a/lightning/src/offers/test_utils.rs +++ b/lightning/src/offers/test_utils.rs @@ -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![ diff --git a/lightning/src/routing/router.rs b/lightning/src/routing/router.rs index bf894f0eb..b6be139c0 100644 --- a/lightning/src/routing/router.rs +++ b/lightning/src/routing/router.rs @@ -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>, L: Deref, ES: Deref, S: Deref, SP: Size > ( &self, recipient: PublicKey, first_hops: Vec, tlvs: ReceiveTlvs, amount_msats: u64, secp_ctx: &Secp256k1 - ) -> Result, ()> { + ) -> Result, ()> { // Limit the number of blinded paths that are computed. const MAX_PAYMENT_PATHS: usize = 3; @@ -158,7 +158,7 @@ impl>, 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>, 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, tlvs: ReceiveTlvs, amount_msats: u64, secp_ctx: &Secp256k1 - ) -> Result, ()>; + ) -> Result, ()>; } /// [`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, - /// 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( #[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 { diff --git a/lightning/src/util/test_utils.rs b/lightning/src/util/test_utils.rs index f5256064e..2f2a48bd6 100644 --- a/lightning/src/util/test_utils.rs +++ b/lightning/src/util/test_utils.rs @@ -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>, pub next_routes: Mutex>)>>, - pub next_blinded_payment_paths: Mutex>, + pub next_blinded_payment_paths: Mutex>, pub scorer: &'a RwLock, } @@ -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, tlvs: ReceiveTlvs, amount_msats: u64, secp_ctx: &Secp256k1, - ) -> Result, ()> { + ) -> Result, ()> { let mut expected_paths = self.next_blinded_payment_paths.lock().unwrap(); if expected_paths.is_empty() { self.router.create_blinded_payment_paths( -- 2.39.5