diff --git a/lightning-liquidity/tests/lsps2_integration_tests.rs b/lightning-liquidity/tests/lsps2_integration_tests.rs index 45c2891227d..8dc907ae7fd 100644 --- a/lightning-liquidity/tests/lsps2_integration_tests.rs +++ b/lightning-liquidity/tests/lsps2_integration_tests.rs @@ -9,8 +9,7 @@ use common::{ use lightning::events::{ClosureReason, Event}; use lightning::get_event_msg; -use lightning::ln::channelmanager::PaymentId; -use lightning::ln::channelmanager::Retry; +use lightning::ln::channelmanager::{OptionalBolt11PaymentParams, PaymentId}; use lightning::ln::functional_test_utils::*; use lightning::ln::msgs::BaseMessageHandler; use lightning::ln::msgs::ChannelMessageHandler; @@ -1214,8 +1213,7 @@ fn client_trusts_lsp_end_to_end_test() { &invoice, PaymentId(invoice.payment_hash().0), None, - Default::default(), - Retry::Attempts(3), + OptionalBolt11PaymentParams::default(), ) .unwrap(); @@ -1687,8 +1685,7 @@ fn late_payment_forwarded_and_safe_after_force_close_does_not_broadcast() { &invoice, PaymentId(invoice.payment_hash().0), None, - Default::default(), - Retry::Attempts(3), + OptionalBolt11PaymentParams::default(), ) .unwrap(); @@ -1878,8 +1875,7 @@ fn htlc_timeout_before_client_claim_results_in_handling_failed() { &invoice, PaymentId(invoice.payment_hash().0), None, - Default::default(), - Retry::Attempts(3), + OptionalBolt11PaymentParams::default(), ) .unwrap(); @@ -2215,8 +2211,7 @@ fn client_trusts_lsp_partial_fee_does_not_trigger_broadcast() { &invoice, PaymentId(invoice.payment_hash().0), None, - Default::default(), - Retry::Attempts(3), + OptionalBolt11PaymentParams::default(), ) .unwrap(); diff --git a/lightning/src/ln/blinded_payment_tests.rs b/lightning/src/ln/blinded_payment_tests.rs index 5a7c326ebaa..80da76452c0 100644 --- a/lightning/src/ln/blinded_payment_tests.rs +++ b/lightning/src/ln/blinded_payment_tests.rs @@ -22,7 +22,7 @@ use crate::ln::msgs::{ }; use crate::ln::onion_payment; use crate::ln::onion_utils::{self, LocalHTLCFailureReason}; -use crate::ln::outbound_payment::{Retry, IDEMPOTENCY_TIMEOUT_TICKS}; +use crate::ln::outbound_payment::{RecipientCustomTlvs, Retry, IDEMPOTENCY_TIMEOUT_TICKS}; use crate::ln::types::ChannelId; use crate::offers::invoice::UnsignedBolt12Invoice; use crate::prelude::*; @@ -1431,8 +1431,7 @@ fn custom_tlvs_to_blinded_path() { ); let recipient_onion_fields = RecipientOnionFields::spontaneous_empty() - .with_custom_tlvs(vec![((1 << 16) + 1, vec![42, 42])]) - .unwrap(); + .with_custom_tlvs(RecipientCustomTlvs::new(vec![((1 << 16) + 1, vec![42, 42])]).unwrap()); nodes[0].node.send_payment(payment_hash, recipient_onion_fields.clone(), PaymentId(payment_hash.0), route_params, Retry::Attempts(0)).unwrap(); check_added_monitors(&nodes[0], 1); diff --git a/lightning/src/ln/bolt11_payment_tests.rs b/lightning/src/ln/bolt11_payment_tests.rs index 63c5576e333..690335e034d 100644 --- a/lightning/src/ln/bolt11_payment_tests.rs +++ b/lightning/src/ln/bolt11_payment_tests.rs @@ -10,11 +10,10 @@ //! Tests for verifying the correct end-to-end handling of BOLT11 payments, including metadata propagation. use crate::events::Event; -use crate::ln::channelmanager::{PaymentId, Retry}; +use crate::ln::channelmanager::{OptionalBolt11PaymentParams, PaymentId}; use crate::ln::functional_test_utils::*; use crate::ln::msgs::ChannelMessageHandler; use crate::ln::outbound_payment::Bolt11PaymentError; -use crate::routing::router::RouteParametersConfig; use crate::sign::{NodeSigner, Recipient}; use bitcoin::hashes::sha256::Hash as Sha256; use bitcoin::hashes::Hash; @@ -55,8 +54,7 @@ fn payment_metadata_end_to_end_for_invoice_with_amount() { &invoice, PaymentId(payment_hash.0), Some(100), - RouteParametersConfig::default(), - Retry::Attempts(0), + OptionalBolt11PaymentParams::default(), ) { Err(Bolt11PaymentError::InvalidAmount) => (), _ => panic!("Unexpected result"), @@ -68,8 +66,7 @@ fn payment_metadata_end_to_end_for_invoice_with_amount() { &invoice, PaymentId(payment_hash.0), None, - RouteParametersConfig::default(), - Retry::Attempts(0), + OptionalBolt11PaymentParams::default(), ) .unwrap(); @@ -123,8 +120,7 @@ fn payment_metadata_end_to_end_for_invoice_with_no_amount() { &invoice, PaymentId(payment_hash.0), None, - RouteParametersConfig::default(), - Retry::Attempts(0), + OptionalBolt11PaymentParams::default(), ) { Err(Bolt11PaymentError::InvalidAmount) => (), _ => panic!("Unexpected result"), @@ -136,8 +132,7 @@ fn payment_metadata_end_to_end_for_invoice_with_no_amount() { &invoice, PaymentId(payment_hash.0), Some(50_000), - RouteParametersConfig::default(), - Retry::Attempts(0), + OptionalBolt11PaymentParams::default(), ) .unwrap(); diff --git a/lightning/src/ln/channelmanager.rs b/lightning/src/ln/channelmanager.rs index fd5e5d15b9f..890831126e7 100644 --- a/lightning/src/ln/channelmanager.rs +++ b/lightning/src/ln/channelmanager.rs @@ -85,8 +85,8 @@ use crate::ln::our_peer_storage::{EncryptedOurPeerStorage, PeerStorageMonitorHol #[cfg(test)] use crate::ln::outbound_payment; use crate::ln::outbound_payment::{ - OutboundPayments, PendingOutboundPayment, RetryableInvoiceRequest, SendAlongPathArgs, - StaleExpiration, + OutboundPayments, PendingOutboundPayment, RecipientCustomTlvs, RetryableInvoiceRequest, + SendAlongPathArgs, StaleExpiration, }; use crate::ln::types::ChannelId; use crate::offers::async_receive_offer_cache::AsyncReceiveOfferCache; @@ -674,6 +674,36 @@ impl Readable for InterceptId { } } +/// Optional arguments to [`ChannelManager::pay_for_bolt11_invoice`] +/// +/// These fields will often not need to be set, and the provided [`Self::default`] can be used. +pub struct OptionalBolt11PaymentParams { + /// A set of custom tlvs, user can send along the payment. + pub custom_tlvs: RecipientCustomTlvs, + /// Pathfinding options which tweak how the path is constructed to the recipient. + pub route_params_config: RouteParametersConfig, + /// The number of tries or time during which we'll retry this payment if some paths to the + /// recipient fail. + /// + /// Once the retry limit is reached, further path failures will not be retried and the payment + /// will ultimately fail once all pending paths have failed (generating an + /// [`Event::PaymentFailed`]). + pub retry_strategy: Retry, +} + +impl Default for OptionalBolt11PaymentParams { + fn default() -> Self { + Self { + custom_tlvs: RecipientCustomTlvs::new(vec![]).unwrap(), + route_params_config: Default::default(), + #[cfg(feature = "std")] + retry_strategy: Retry::Timeout(core::time::Duration::from_secs(2)), + #[cfg(not(feature = "std"))] + retry_strategy: Retry::Attempts(3), + } + } +} + /// Optional arguments to [`ChannelManager::pay_for_offer`] #[cfg_attr( feature = "dnssec", @@ -2277,19 +2307,19 @@ where /// # use bitcoin::hashes::Hash; /// # use lightning::events::{Event, EventsProvider}; /// # use lightning::types::payment::PaymentHash; -/// # use lightning::ln::channelmanager::{AChannelManager, PaymentId, RecentPaymentDetails, Retry}; -/// # use lightning::routing::router::RouteParametersConfig; +/// # use lightning::ln::channelmanager::{AChannelManager, OptionalBolt11PaymentParams, PaymentId, RecentPaymentDetails, Retry}; /// # use lightning_invoice::Bolt11Invoice; /// # /// # fn example( -/// # channel_manager: T, invoice: &Bolt11Invoice, route_params_config: RouteParametersConfig, +/// # channel_manager: T, invoice: &Bolt11Invoice, optional_params: OptionalBolt11PaymentParams, /// # retry: Retry /// # ) { /// # let channel_manager = channel_manager.get_cm(); /// # let payment_id = PaymentId([42; 32]); /// # let payment_hash = invoice.payment_hash(); +/// /// match channel_manager.pay_for_bolt11_invoice( -/// invoice, payment_id, None, route_params_config, retry +/// invoice, payment_id, None, optional_params /// ) { /// Ok(()) => println!("Sending payment with hash {}", payment_hash), /// Err(e) => println!("Failed sending payment with hash {}: {:?}", payment_hash, e), @@ -5498,7 +5528,7 @@ where /// To use default settings, call the function with [`RouteParametersConfig::default`]. pub fn pay_for_bolt11_invoice( &self, invoice: &Bolt11Invoice, payment_id: PaymentId, amount_msats: Option, - route_params_config: RouteParametersConfig, retry_strategy: Retry, + optional_params: OptionalBolt11PaymentParams, ) -> Result<(), Bolt11PaymentError> { let best_block_height = self.best_block.read().unwrap().height; let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(self); @@ -5506,8 +5536,7 @@ where invoice, payment_id, amount_msats, - route_params_config, - retry_strategy, + optional_params, &self.router, self.list_usable_channels(), || self.compute_inflight_htlcs(), diff --git a/lightning/src/ln/invoice_utils.rs b/lightning/src/ln/invoice_utils.rs index e72ea4518a4..90b3b5c38a9 100644 --- a/lightning/src/ln/invoice_utils.rs +++ b/lightning/src/ln/invoice_utils.rs @@ -615,12 +615,13 @@ mod test { use super::*; use crate::chain::channelmonitor::HTLC_FAIL_BACK_BUFFER; use crate::ln::channelmanager::{ - Bolt11InvoiceParameters, PaymentId, PhantomRouteHints, RecipientOnionFields, Retry, - MIN_FINAL_CLTV_EXPIRY_DELTA, + Bolt11InvoiceParameters, OptionalBolt11PaymentParams, PaymentId, PhantomRouteHints, + RecipientOnionFields, Retry, MIN_FINAL_CLTV_EXPIRY_DELTA, }; use crate::ln::functional_test_utils::*; use crate::ln::msgs::{BaseMessageHandler, ChannelMessageHandler, MessageSendEvent}; - use crate::routing::router::{PaymentParameters, RouteParameters}; + use crate::ln::outbound_payment::RecipientCustomTlvs; + use crate::routing::router::{PaymentParameters, RouteParameters, RouteParametersConfig}; use crate::sign::PhantomKeysManager; use crate::types::payment::{PaymentHash, PaymentPreimage}; use crate::util::config::UserConfig; @@ -663,26 +664,26 @@ mod test { } #[test] - fn create_and_pay_for_bolt11_invoice() { + fn create_and_pay_for_bolt11_invoice_with_custom_tlvs() { let chanmon_cfgs = create_chanmon_cfgs(2); let node_cfgs = create_node_cfgs(2, &chanmon_cfgs); let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]); let nodes = create_network(2, &node_cfgs, &node_chanmgrs); create_unannounced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 10001); - let node_a_id = nodes[0].node.get_our_node_id(); - + let amt_msat = 10_000; let description = Bolt11InvoiceDescription::Direct(Description::new("test".to_string()).unwrap()); let non_default_invoice_expiry_secs = 4200; + let invoice_params = Bolt11InvoiceParameters { - amount_msats: Some(10_000), + amount_msats: Some(amt_msat), description, invoice_expiry_delta_secs: Some(non_default_invoice_expiry_secs), ..Default::default() }; let invoice = nodes[1].node.create_bolt11_invoice(invoice_params).unwrap(); - assert_eq!(invoice.amount_milli_satoshis(), Some(10_000)); + assert_eq!(invoice.amount_milli_satoshis(), Some(amt_msat)); // If no `min_final_cltv_expiry_delta` is specified, then it should be `MIN_FINAL_CLTV_EXPIRY_DELTA`. assert_eq!(invoice.min_final_cltv_expiry_delta(), MIN_FINAL_CLTV_EXPIRY_DELTA as u64); assert_eq!( @@ -694,6 +695,10 @@ mod test { Duration::from_secs(non_default_invoice_expiry_secs.into()) ); + let (payment_hash, payment_secret) = (invoice.payment_hash(), *invoice.payment_secret()); + + let preimage = nodes[1].node.get_payment_preimage(payment_hash, payment_secret).unwrap(); + // Invoice SCIDs should always use inbound SCID aliases over the real channel ID, if one is // available. let chan = &nodes[1].node.list_usable_channels()[0]; @@ -707,21 +712,34 @@ mod test { assert_eq!(invoice.route_hints()[0].0[0].htlc_minimum_msat, chan.inbound_htlc_minimum_msat); assert_eq!(invoice.route_hints()[0].0[0].htlc_maximum_msat, chan.inbound_htlc_maximum_msat); - let retry = Retry::Attempts(0); + let custom_tlvs = RecipientCustomTlvs::new(vec![(65537, vec![42; 42])]).unwrap(); + let optional_params = OptionalBolt11PaymentParams { + custom_tlvs: custom_tlvs.clone(), + route_params_config: RouteParametersConfig::default(), + retry_strategy: Retry::Attempts(0), + }; + nodes[0] .node - .pay_for_bolt11_invoice(&invoice, PaymentId([42; 32]), None, Default::default(), retry) + .pay_for_bolt11_invoice(&invoice, PaymentId([42; 32]), None, optional_params) .unwrap(); check_added_monitors(&nodes[0], 1); let mut events = nodes[0].node.get_and_clear_pending_msg_events(); assert_eq!(events.len(), 1); - let payment_event = SendEvent::from_event(events.remove(0)); - nodes[1].node.handle_update_add_htlc(node_a_id, &payment_event.msgs[0]); - nodes[1].node.handle_commitment_signed_batch_test(node_a_id, &payment_event.commitment_msg); - check_added_monitors(&nodes[1], 1); - let events = nodes[1].node.get_and_clear_pending_msg_events(); - assert_eq!(events.len(), 2); + let ev = remove_first_msg_event_to_node(&nodes[1].node.get_our_node_id(), &mut events); + + let path = &[&nodes[1]]; + let args = PassAlongPathArgs::new(&nodes[0], path, amt_msat, payment_hash, ev) + .with_payment_preimage(preimage) + .with_payment_secret(payment_secret) + .with_custom_tlvs(custom_tlvs.clone().into_inner()); + + do_pass_along_path(args); + claim_payment_along_route( + ClaimAlongRouteArgs::new(&nodes[0], &[&[&nodes[1]]], preimage) + .with_custom_tlvs(custom_tlvs.into_inner()), + ); } fn do_create_invoice_min_final_cltv_delta(with_custom_delta: bool) { diff --git a/lightning/src/ln/max_payment_path_len_tests.rs b/lightning/src/ln/max_payment_path_len_tests.rs index fa7e8d8f132..b947273115e 100644 --- a/lightning/src/ln/max_payment_path_len_tests.rs +++ b/lightning/src/ln/max_payment_path_len_tests.rs @@ -23,7 +23,9 @@ use crate::ln::msgs; use crate::ln::msgs::{BaseMessageHandler, OnionMessageHandler}; use crate::ln::onion_utils; use crate::ln::onion_utils::MIN_FINAL_VALUE_ESTIMATE_WITH_OVERPAY; -use crate::ln::outbound_payment::{RecipientOnionFields, Retry, RetryableSendFailure}; +use crate::ln::outbound_payment::{ + RecipientCustomTlvs, RecipientOnionFields, Retry, RetryableSendFailure, +}; use crate::prelude::*; use crate::routing::router::{ PaymentParameters, RouteParameters, DEFAULT_MAX_TOTAL_CLTV_EXPIRY_DELTA, @@ -259,9 +261,9 @@ fn one_hop_blinded_path_with_custom_tlv() { - final_payload_len_without_custom_tlv; // Check that we can send the maximum custom TLV with 1 blinded hop. - let max_sized_onion = RecipientOnionFields::spontaneous_empty() - .with_custom_tlvs(vec![(CUSTOM_TLV_TYPE, vec![42; max_custom_tlv_len])]) - .unwrap(); + let max_sized_onion = RecipientOnionFields::spontaneous_empty().with_custom_tlvs( + RecipientCustomTlvs::new(vec![(CUSTOM_TLV_TYPE, vec![42; max_custom_tlv_len])]).unwrap(), + ); let id = PaymentId(payment_hash.0); let no_retry = Retry::Attempts(0); nodes[1] @@ -385,9 +387,9 @@ fn blinded_path_with_custom_tlv() { - reserved_packet_bytes_without_custom_tlv; // Check that we can send the maximum custom TLV size with 0 intermediate unblinded hops. - let max_sized_onion = RecipientOnionFields::spontaneous_empty() - .with_custom_tlvs(vec![(CUSTOM_TLV_TYPE, vec![42; max_custom_tlv_len])]) - .unwrap(); + let max_sized_onion = RecipientOnionFields::spontaneous_empty().with_custom_tlvs( + RecipientCustomTlvs::new(vec![(CUSTOM_TLV_TYPE, vec![42; max_custom_tlv_len])]).unwrap(), + ); let no_retry = Retry::Attempts(0); let id = PaymentId(payment_hash.0); nodes[1] diff --git a/lightning/src/ln/msgs.rs b/lightning/src/ln/msgs.rs index 2bb2b244ccb..994443dc0d5 100644 --- a/lightning/src/ln/msgs.rs +++ b/lightning/src/ln/msgs.rs @@ -3537,7 +3537,7 @@ impl<'a> Writeable for OutboundOnionPayload<'a> { ref invoice_request, ref custom_tlvs, } => { - // We need to update [`ln::outbound_payment::RecipientOnionFields::with_custom_tlvs`] + // We need to update [`ln::outbound_payments::RecipientCustomTlvs::new`] // to reject any reserved types in the experimental range if new ones are ever // standardized. let invoice_request_tlv = invoice_request.map(|invreq| (77_777, invreq.encode())); // TODO: update TLV type once the async payments spec is merged diff --git a/lightning/src/ln/outbound_payment.rs b/lightning/src/ln/outbound_payment.rs index 65493829635..83977ad13a3 100644 --- a/lightning/src/ln/outbound_payment.rs +++ b/lightning/src/ln/outbound_payment.rs @@ -18,7 +18,8 @@ use crate::blinded_path::{IntroductionNode, NodeIdLookUp}; use crate::events::{self, PaidBolt12Invoice, PaymentFailureReason}; use crate::ln::channel_state::ChannelDetails; use crate::ln::channelmanager::{ - EventCompletionAction, HTLCSource, PaymentCompleteUpdate, PaymentId, + EventCompletionAction, HTLCSource, OptionalBolt11PaymentParams, PaymentCompleteUpdate, + PaymentId, }; use crate::ln::onion_utils; use crate::ln::onion_utils::{DecodedOnionFailure, HTLCFailReason}; @@ -677,6 +678,54 @@ pub enum ProbeSendFailure { DuplicateProbe, } +/// A validated, sorted set of custom TLVs for payment recipient onion fields. +#[derive(Clone)] +pub struct RecipientCustomTlvs(Vec<(u64, Vec)>); + +impl RecipientCustomTlvs { + /// Each TLV is provided as a `(u64, Vec)` for the type number and + /// serialized value respectively. TLV type numbers must be unique and + /// within the range reserved for custom types, i.e. >= 2^16, otherwise + /// this method will return `Err(())`. + /// + /// This method will also error for TLV types in the experimental range + /// which have since been standardized within the protocol. This currently + /// includes 5482373484 (keysend) and 77_777 (invoice requests for async + /// payments). + pub fn new(mut tlvs: Vec<(u64, Vec)>) -> Result { + tlvs.sort_unstable_by_key(|(typ, _)| *typ); + let mut prev_type = None; + for (typ, _) in tlvs.iter() { + if *typ < 1 << 16 { + return Err(()); + } + if *typ == 5482373484 { + return Err(()); + } // keysend + if *typ == 77_777 { + return Err(()); + } // invoice requests for async payments + match prev_type { + Some(prev) if prev >= *typ => return Err(()), + _ => {}, + } + prev_type = Some(*typ); + } + + Ok(Self(tlvs)) + } + + /// Returns the inner TLV list. + pub(super) fn into_inner(self) -> Vec<(u64, Vec)> { + self.0 + } + + /// Borrow the inner TLV list. + pub fn as_slice(&self) -> &[(u64, Vec)] { + &self.0 + } +} + /// Information which is provided, encrypted, to the payment recipient when sending HTLCs. /// /// This should generally be constructed with data communicated to us from the recipient (via a @@ -739,31 +788,13 @@ impl RecipientOnionFields { Self { payment_secret: None, payment_metadata: None, custom_tlvs: Vec::new() } } - /// Creates a new [`RecipientOnionFields`] from an existing one, adding custom TLVs. Each - /// TLV is provided as a `(u64, Vec)` for the type number and serialized value - /// respectively. TLV type numbers must be unique and within the range - /// reserved for custom types, i.e. >= 2^16, otherwise this method will return `Err(())`. - /// - /// This method will also error for types in the experimental range which have been - /// standardized within the protocol, which only includes 5482373484 (keysend) for now. + /// Creates a new [`RecipientOnionFields`] from an existing one, adding validated custom TLVs. /// /// See [`Self::custom_tlvs`] for more info. #[rustfmt::skip] - pub fn with_custom_tlvs(mut self, mut custom_tlvs: Vec<(u64, Vec)>) -> Result { - custom_tlvs.sort_unstable_by_key(|(typ, _)| *typ); - let mut prev_type = None; - for (typ, _) in custom_tlvs.iter() { - if *typ < 1 << 16 { return Err(()); } - if *typ == 5482373484 { return Err(()); } // keysend - if *typ == 77_777 { return Err(()); } // invoice requests for async payments - match prev_type { - Some(prev) if prev >= *typ => return Err(()), - _ => {}, - } - prev_type = Some(*typ); - } - self.custom_tlvs = custom_tlvs; - Ok(self) + pub fn with_custom_tlvs(mut self, custom_tlvs: RecipientCustomTlvs) -> Self { + self.custom_tlvs = custom_tlvs.into_inner(); + self } /// Gets the custom TLVs that will be sent or have been received. @@ -919,8 +950,7 @@ where pub(super) fn pay_for_bolt11_invoice( &self, invoice: &Bolt11Invoice, payment_id: PaymentId, amount_msats: Option, - route_params_config: RouteParametersConfig, - retry_strategy: Retry, + optional_params: OptionalBolt11PaymentParams, router: &R, first_hops: Vec, compute_inflight_htlcs: IH, entropy_source: &ES, node_signer: &NS, best_block_height: u32, @@ -942,19 +972,20 @@ where (None, None) => return Err(Bolt11PaymentError::InvalidAmount), }; - let mut recipient_onion = RecipientOnionFields::secret_only(*invoice.payment_secret()); + let mut recipient_onion = RecipientOnionFields::secret_only(*invoice.payment_secret()) + .with_custom_tlvs(optional_params.custom_tlvs); recipient_onion.payment_metadata = invoice.payment_metadata().map(|v| v.clone()); let payment_params = PaymentParameters::from_bolt11_invoice(invoice) - .with_user_config_ignoring_fee_limit(route_params_config); + .with_user_config_ignoring_fee_limit(optional_params.route_params_config); let mut route_params = RouteParameters::from_payment_params_and_value(payment_params, amount); - if let Some(max_fee_msat) = route_params_config.max_total_routing_fee_msat { + if let Some(max_fee_msat) = optional_params.route_params_config.max_total_routing_fee_msat { route_params.max_total_routing_fee_msat = Some(max_fee_msat); } - self.send_payment_for_non_bolt12_invoice(payment_id, payment_hash, recipient_onion, None, retry_strategy, route_params, + self.send_payment_for_non_bolt12_invoice(payment_id, payment_hash, recipient_onion, None, optional_params.retry_strategy, route_params, router, first_hops, compute_inflight_htlcs, entropy_source, node_signer, best_block_height, pending_events, send_payment_along_path @@ -2815,8 +2846,8 @@ mod tests { use crate::ln::channelmanager::{PaymentId, RecipientOnionFields}; use crate::ln::inbound_payment::ExpandedKey; use crate::ln::outbound_payment::{ - Bolt12PaymentError, OutboundPayments, PendingOutboundPayment, Retry, RetryableSendFailure, - StaleExpiration, + Bolt12PaymentError, OutboundPayments, PendingOutboundPayment, RecipientCustomTlvs, Retry, + RetryableSendFailure, StaleExpiration, }; #[cfg(feature = "std")] use crate::offers::invoice::DEFAULT_RELATIVE_EXPIRY; @@ -2843,22 +2874,23 @@ mod tests { fn test_recipient_onion_fields_with_custom_tlvs() { let onion_fields = RecipientOnionFields::spontaneous_empty(); - let bad_type_range_tlvs = vec![ + let bad_type_range_tlvs = RecipientCustomTlvs::new(vec![ (0, vec![42]), (1, vec![42; 32]), - ]; - assert!(onion_fields.clone().with_custom_tlvs(bad_type_range_tlvs).is_err()); + ]); + assert!(bad_type_range_tlvs.is_err()); - let keysend_tlv = vec![ + let keysend_tlv = RecipientCustomTlvs::new(vec![ (5482373484, vec![42; 32]), - ]; - assert!(onion_fields.clone().with_custom_tlvs(keysend_tlv).is_err()); + ]); + assert!(keysend_tlv.is_err()); - let good_tlvs = vec![ + let good_tlvs = RecipientCustomTlvs::new(vec![ ((1 << 16) + 1, vec![42]), ((1 << 16) + 3, vec![42; 32]), - ]; - assert!(onion_fields.with_custom_tlvs(good_tlvs).is_ok()); + ]); + assert!(good_tlvs.is_ok()); + onion_fields.with_custom_tlvs(good_tlvs.unwrap()); } #[test] diff --git a/lightning/src/ln/payment_tests.rs b/lightning/src/ln/payment_tests.rs index 14446239a31..e41e60a46a7 100644 --- a/lightning/src/ln/payment_tests.rs +++ b/lightning/src/ln/payment_tests.rs @@ -32,7 +32,7 @@ use crate::ln::msgs; use crate::ln::msgs::{BaseMessageHandler, ChannelMessageHandler, MessageSendEvent}; use crate::ln::onion_utils::{self, LocalHTLCFailureReason}; use crate::ln::outbound_payment::{ - ProbeSendFailure, Retry, RetryableSendFailure, IDEMPOTENCY_TIMEOUT_TICKS, + ProbeSendFailure, RecipientCustomTlvs, Retry, RetryableSendFailure, IDEMPOTENCY_TIMEOUT_TICKS, }; use crate::ln::types::ChannelId; use crate::routing::gossip::{EffectiveCapacity, RoutingFees}; @@ -4539,7 +4539,7 @@ fn test_retry_custom_tlvs() { let custom_tlvs = vec![((1 << 16) + 1, vec![0x42u8; 16])]; let onion = RecipientOnionFields::secret_only(payment_secret); - let onion = onion.with_custom_tlvs(custom_tlvs.clone()).unwrap(); + let onion = onion.with_custom_tlvs(RecipientCustomTlvs::new(custom_tlvs.clone()).unwrap()); nodes[0].router.expect_find_route(route_params.clone(), Ok(route.clone())); nodes[0].node.send_payment(hash, onion, id, route_params.clone(), Retry::Attempts(1)).unwrap(); @@ -5079,8 +5079,7 @@ fn peel_payment_onion_custom_tlvs() { let route_params = RouteParameters::from_payment_params_and_value(payment_params, amt_msat); let route = functional_test_utils::get_route(&nodes[0], &route_params).unwrap(); let mut recipient_onion = RecipientOnionFields::spontaneous_empty() - .with_custom_tlvs(vec![(414141, vec![42; 1200])]) - .unwrap(); + .with_custom_tlvs(RecipientCustomTlvs::new(vec![(414141, vec![42; 1200])]).unwrap()); let prng_seed = chanmon_cfgs[0].keys_manager.get_secure_random_bytes(); let session_priv = SecretKey::from_slice(&prng_seed[..]).expect("RNG is busted"); let keysend_preimage = PaymentPreimage([42; 32]); @@ -5404,11 +5403,10 @@ fn max_out_mpp_path() { ..Default::default() }; let invoice = nodes[2].node.create_bolt11_invoice(invoice_params).unwrap(); - let route_params_cfg = crate::routing::router::RouteParametersConfig::default(); + let optional_params = crate::ln::channelmanager::OptionalBolt11PaymentParams::default(); let id = PaymentId([42; 32]); - let retry = Retry::Attempts(0); - nodes[0].node.pay_for_bolt11_invoice(&invoice, id, None, route_params_cfg, retry).unwrap(); + nodes[0].node.pay_for_bolt11_invoice(&invoice, id, None, optional_params).unwrap(); assert!(nodes[0].node.list_recent_payments().len() == 1); check_added_monitors(&nodes[0], 2); // one monitor update per MPP part