]> git.bitcoin.ninja Git - rust-lightning/commitdiff
Support including invreqs when building onion payloads
authorValentine Wallace <vwallace@protonmail.com>
Fri, 28 Jun 2024 16:11:01 +0000 (12:11 -0400)
committerValentine Wallace <vwallace@protonmail.com>
Wed, 30 Oct 2024 20:17:20 +0000 (16:17 -0400)
Add a new invoice request parameter to onion_utils::build_onion_payloads.
As of this commit it will always be passed in as None, to be updated in future
commits.

Per BOLTs PR 1149, when paying a static invoice we need to include our original
invoice request in the HTLC onion since the recipient wouldn't have received it
previously.

lightning/src/ln/blinded_payment_tests.rs
lightning/src/ln/functional_tests.rs
lightning/src/ln/max_payment_path_len_tests.rs
lightning/src/ln/onion_payment.rs
lightning/src/ln/onion_route_tests.rs
lightning/src/ln/onion_utils.rs

index 79b24e06db39b8e954ecb2b158ddf4e5c2ee28b1..3a6d996b5a4a3fdd18e3bd7887c64ec27f3144f2 100644 (file)
@@ -318,7 +318,7 @@ fn do_forward_checks_failure(check: ForwardCheckFail, intro_fails: bool) {
                                        let onion_keys = onion_utils::construct_onion_keys(&Secp256k1::new(), &route.paths[0], &session_priv).unwrap();
                                        let cur_height = nodes[0].best_block_info().1;
                                        let (mut onion_payloads, ..) = onion_utils::build_onion_payloads(
-                                               &route.paths[0], amt_msat, &recipient_onion_fields, cur_height, &None).unwrap();
+                                               &route.paths[0], amt_msat, &recipient_onion_fields, cur_height, &None, None).unwrap();
                                        // Remove the receive payload so the blinded forward payload is encoded as a final payload
                                        // (i.e. next_hop_hmac == [0; 32])
                                        onion_payloads.pop();
@@ -897,7 +897,7 @@ fn do_multi_hop_receiver_fail(check: ReceiveCheckFail) {
                        let cur_height = nodes[0].best_block_info().1;
                        let recipient_onion_fields = RecipientOnionFields::spontaneous_empty();
                        let (mut onion_payloads, ..) = onion_utils::build_onion_payloads(
-                               &route.paths[0], amt_msat, &recipient_onion_fields, cur_height, &None).unwrap();
+                               &route.paths[0], amt_msat, &recipient_onion_fields, cur_height, &None, None).unwrap();
 
                        let update_add = &mut payment_event_1_2.msgs[0];
                        onion_payloads.last_mut().map(|p| {
index 42a57b114cb7767fe2abfc83f224606f9645e8d5..cb6e8d521ccc4ebb59508dde9aaf287706b15ecb 100644 (file)
@@ -1438,7 +1438,7 @@ fn test_fee_spike_violation_fails_htlc() {
        let onion_keys = onion_utils::construct_onion_keys(&secp_ctx, &route.paths[0], &session_priv).unwrap();
        let recipient_onion_fields = RecipientOnionFields::secret_only(payment_secret);
        let (onion_payloads, htlc_msat, htlc_cltv) = onion_utils::build_onion_payloads(&route.paths[0],
-               3460001, &recipient_onion_fields, cur_height, &None).unwrap();
+               3460001, &recipient_onion_fields, cur_height, &None, None).unwrap();
        let onion_packet = onion_utils::construct_onion_packet(onion_payloads, onion_keys, [0; 32], &payment_hash).unwrap();
        let msg = msgs::UpdateAddHTLC {
                channel_id: chan.2,
@@ -1637,7 +1637,7 @@ fn test_chan_reserve_violation_inbound_htlc_outbound_channel() {
        let onion_keys = onion_utils::construct_onion_keys(&secp_ctx, &route.paths[0], &session_priv).unwrap();
        let recipient_onion_fields = RecipientOnionFields::secret_only(payment_secret);
        let (onion_payloads, htlc_msat, htlc_cltv) = onion_utils::build_onion_payloads(&route.paths[0],
-               700_000, &recipient_onion_fields, cur_height, &None).unwrap();
+               700_000, &recipient_onion_fields, cur_height, &None, None).unwrap();
        let onion_packet = onion_utils::construct_onion_packet(onion_payloads, onion_keys, [0; 32], &payment_hash).unwrap();
        let msg = msgs::UpdateAddHTLC {
                channel_id: chan.2,
@@ -1817,7 +1817,7 @@ fn test_chan_reserve_violation_inbound_htlc_inbound_chan() {
        let onion_keys = onion_utils::construct_onion_keys(&secp_ctx, &route_2.paths[0], &session_priv).unwrap();
        let recipient_onion_fields = RecipientOnionFields::spontaneous_empty();
        let (onion_payloads, htlc_msat, htlc_cltv) = onion_utils::build_onion_payloads(
-               &route_2.paths[0], recv_value_2, &recipient_onion_fields, cur_height, &None).unwrap();
+               &route_2.paths[0], recv_value_2, &recipient_onion_fields, cur_height, &None, None).unwrap();
        let onion_packet = onion_utils::construct_onion_packet(onion_payloads, onion_keys, [0; 32], &our_payment_hash_1).unwrap();
        let msg = msgs::UpdateAddHTLC {
                channel_id: chan.2,
@@ -3556,7 +3556,7 @@ fn fail_backward_pending_htlc_upon_channel_failure() {
                let current_height = nodes[1].node.best_block.read().unwrap().height + 1;
                let recipient_onion_fields = RecipientOnionFields::secret_only(payment_secret);
                let (onion_payloads, _amount_msat, cltv_expiry) = onion_utils::build_onion_payloads(
-                       &route.paths[0], 50_000, &recipient_onion_fields, current_height, &None).unwrap();
+                       &route.paths[0], 50_000, &recipient_onion_fields, current_height, &None, None).unwrap();
                let onion_keys = onion_utils::construct_onion_keys(&secp_ctx, &route.paths[0], &session_priv).unwrap();
                let onion_routing_packet = onion_utils::construct_onion_packet(onion_payloads, onion_keys, [0; 32], &payment_hash).unwrap();
 
@@ -6548,7 +6548,7 @@ fn test_update_add_htlc_bolt2_receiver_check_max_htlc_limit() {
        let onion_keys = onion_utils::construct_onion_keys(&Secp256k1::signing_only(), &route.paths[0], &session_priv).unwrap();
        let recipient_onion_fields = RecipientOnionFields::secret_only(our_payment_secret);
        let (onion_payloads, _htlc_msat, htlc_cltv) = onion_utils::build_onion_payloads(
-               &route.paths[0], send_amt, &recipient_onion_fields, cur_height, &None).unwrap();
+               &route.paths[0], send_amt, &recipient_onion_fields, cur_height, &None, None).unwrap();
        let onion_packet = onion_utils::construct_onion_packet(onion_payloads, onion_keys, [0; 32], &our_payment_hash).unwrap();
 
        let mut msg = msgs::UpdateAddHTLC {
@@ -8291,7 +8291,7 @@ fn test_onion_value_mpp_set_calculation() {
                        let mut onion_keys = onion_utils::construct_onion_keys(&Secp256k1::new(), &route.paths[0], &session_priv).unwrap();
                        let recipient_onion_fields = RecipientOnionFields::secret_only(our_payment_secret);
                        let (mut onion_payloads, _, _) = onion_utils::build_onion_payloads(&route.paths[0], 100_000,
-                               &recipient_onion_fields, height + 1, &None).unwrap();
+                               &recipient_onion_fields, height + 1, &None, None).unwrap();
                        // Edit amt_to_forward to simulate the sender having set
                        // the final amount and the routing node taking less fee
                        if let msgs::OutboundOnionPayload::Receive {
index 501ddcc5721d623d20ae0749d49226b77495cdb8..90326b9c54ce87339a93c6e8d487e825fe2e0dd8 100644 (file)
@@ -276,7 +276,7 @@ fn blinded_path_with_custom_tlv() {
        let reserved_packet_bytes_without_custom_tlv: usize = onion_utils::build_onion_payloads(
                &route.paths[0], MIN_FINAL_VALUE_ESTIMATE_WITH_OVERPAY,
                &RecipientOnionFields::spontaneous_empty(),
-               nodes[0].best_block_info().1 + DEFAULT_MAX_TOTAL_CLTV_EXPIRY_DELTA, &None
+               nodes[0].best_block_info().1 + DEFAULT_MAX_TOTAL_CLTV_EXPIRY_DELTA, &None, None
        )
                .unwrap()
                .0
index 528b5e7d8865a6c7627eec82d52cd28f607e04de..d76c0d3a99dc4a96501b61df093fe289b235bf8c 100644 (file)
@@ -541,7 +541,7 @@ mod tests {
                let path = Path { hops, blinded_tail: None, };
                let onion_keys = super::onion_utils::construct_onion_keys(&secp_ctx, &path, &session_priv).unwrap();
                let (onion_payloads, ..) = super::onion_utils::build_onion_payloads(
-                       &path, total_amt_msat, &recipient_onion, cur_height + 1, &Some(keysend_preimage)
+                       &path, total_amt_msat, &recipient_onion, cur_height + 1, &Some(keysend_preimage), None
                ).unwrap();
 
                assert!(super::onion_utils::construct_onion_packet(
index c0253166d991e14944db07372debd322a1b4ee05..3ab03ae91fe7a87955a78f7c909628fbd4d47031 100644 (file)
@@ -356,7 +356,7 @@ fn test_onion_failure() {
                let onion_keys = onion_utils::construct_onion_keys(&Secp256k1::new(), &route.paths[0], &session_priv).unwrap();
                let recipient_onion_fields = RecipientOnionFields::spontaneous_empty();
                let (mut onion_payloads, _htlc_msat, _htlc_cltv) = onion_utils::build_onion_payloads(
-                       &route.paths[0], 40000, &recipient_onion_fields, cur_height, &None).unwrap();
+                       &route.paths[0], 40000, &recipient_onion_fields, cur_height, &None, None).unwrap();
                let mut new_payloads = Vec::new();
                for payload in onion_payloads.drain(..) {
                        new_payloads.push(BogusOnionHopData::new(payload));
@@ -375,7 +375,7 @@ fn test_onion_failure() {
                let onion_keys = onion_utils::construct_onion_keys(&Secp256k1::new(), &route.paths[0], &session_priv).unwrap();
                let recipient_onion_fields = RecipientOnionFields::spontaneous_empty();
                let (mut onion_payloads, _htlc_msat, _htlc_cltv) = onion_utils::build_onion_payloads(
-                       &route.paths[0], 40000, &recipient_onion_fields, cur_height, &None).unwrap();
+                       &route.paths[0], 40000, &recipient_onion_fields, cur_height, &None, None).unwrap();
                let mut new_payloads = Vec::new();
                for payload in onion_payloads.drain(..) {
                        new_payloads.push(BogusOnionHopData::new(payload));
@@ -627,7 +627,7 @@ fn test_onion_failure() {
                let onion_keys = onion_utils::construct_onion_keys(&Secp256k1::new(), &route.paths[0], &session_priv).unwrap();
                let recipient_onion_fields = RecipientOnionFields::spontaneous_empty();
                let (onion_payloads, _, htlc_cltv) = onion_utils::build_onion_payloads(
-                       &route.paths[0], 40000, &recipient_onion_fields, height, &None).unwrap();
+                       &route.paths[0], 40000, &recipient_onion_fields, height, &None, None).unwrap();
                let onion_packet = onion_utils::construct_onion_packet(onion_payloads, onion_keys, [0; 32], &payment_hash).unwrap();
                msg.cltv_expiry = htlc_cltv;
                msg.onion_routing_packet = onion_packet;
@@ -964,7 +964,7 @@ fn test_always_create_tlv_format_onion_payloads() {
        let cur_height = nodes[0].best_block_info().1 + 1;
        let recipient_onion_fields = RecipientOnionFields::spontaneous_empty();
        let (onion_payloads, _htlc_msat, _htlc_cltv) = onion_utils::build_onion_payloads(
-               &route.paths[0], 40000, &recipient_onion_fields, cur_height, &None).unwrap();
+               &route.paths[0], 40000, &recipient_onion_fields, cur_height, &None, None).unwrap();
 
        match onion_payloads[0] {
                msgs::OutboundOnionPayload::Forward {..} => {},
@@ -1221,7 +1221,7 @@ fn test_phantom_invalid_onion_payload() {
                                        let recipient_onion_fields = RecipientOnionFields::secret_only(payment_secret);
                                        let (mut onion_payloads, _, _) = onion_utils::build_onion_payloads(
                                                &route.paths[0], msgs::MAX_VALUE_MSAT + 1,
-                                               &recipient_onion_fields, height + 1, &None).unwrap();
+                                               &recipient_onion_fields, height + 1, &None, None).unwrap();
                                        // We only want to construct the onion packet for the last hop, not the entire route, so
                                        // remove the first hop's payload and its keys.
                                        onion_keys.remove(0);
index 68866fc03f83f5b33f4529bce22fe4875cc8ba73..16b8885d2fb9bff53c5ed19d0fec5561bd617667 100644 (file)
@@ -13,6 +13,7 @@ use crate::crypto::streams::ChaChaReader;
 use crate::ln::channel::TOTAL_BITCOIN_SUPPLY_SATOSHIS;
 use crate::ln::channelmanager::{HTLCSource, RecipientOnionFields};
 use crate::ln::msgs;
+use crate::offers::invoice_request::InvoiceRequest;
 use crate::routing::gossip::NetworkUpdate;
 use crate::routing::router::{Path, RouteHop, RouteParameters};
 use crate::sign::NodeSigner;
@@ -179,6 +180,7 @@ pub(super) fn construct_onion_keys<T: secp256k1::Signing>(
 pub(super) fn build_onion_payloads<'a>(
        path: &'a Path, total_msat: u64, recipient_onion: &'a RecipientOnionFields,
        starting_htlc_offset: u32, keysend_preimage: &Option<PaymentPreimage>,
+       invoice_request: Option<&'a InvoiceRequest>,
 ) -> Result<(Vec<msgs::OutboundOnionPayload<'a>>, u64, u32), APIError> {
        let mut res: Vec<msgs::OutboundOnionPayload> = Vec::with_capacity(
                path.hops.len() + path.blinded_tail.as_ref().map_or(0, |t| t.hops.len()),
@@ -197,6 +199,7 @@ pub(super) fn build_onion_payloads<'a>(
                recipient_onion,
                starting_htlc_offset,
                keysend_preimage,
+               invoice_request,
                |action, payload| match action {
                        PayloadCallbackAction::PushBack => res.push(payload),
                        PayloadCallbackAction::PushFront => res.insert(0, payload),
@@ -218,7 +221,8 @@ enum PayloadCallbackAction {
 fn build_onion_payloads_callback<'a, H, B, F>(
        hops: H, mut blinded_tail: Option<BlindedTailHopIter<'a, B>>, total_msat: u64,
        recipient_onion: &'a RecipientOnionFields, starting_htlc_offset: u32,
-       keysend_preimage: &Option<PaymentPreimage>, mut callback: F,
+       keysend_preimage: &Option<PaymentPreimage>, invoice_request: Option<&'a InvoiceRequest>,
+       mut callback: F,
 ) -> Result<(u64, u32), APIError>
 where
        H: DoubleEndedIterator<Item = &'a RouteHop>,
@@ -262,7 +266,7 @@ where
                                                                encrypted_tlvs: &blinded_hop.encrypted_payload,
                                                                intro_node_blinding_point: blinding_point.take(),
                                                                keysend_preimage: *keysend_preimage,
-                                                               invoice_request: None,
+                                                               invoice_request,
                                                                custom_tlvs: &recipient_onion.custom_tlvs,
                                                        },
                                                );
@@ -363,6 +367,7 @@ pub(crate) fn set_max_path_length(
                &recipient_onion,
                best_block_height,
                &keysend_preimage,
+               None,
                |_, payload| {
                        num_reserved_bytes = num_reserved_bytes
                                .saturating_add(payload.serialized_length())
@@ -1169,6 +1174,7 @@ pub fn create_payment_onion<T: secp256k1::Signing>(
                recipient_onion,
                cur_block_height,
                keysend_preimage,
+               None,
        )?;
        let onion_packet = construct_onion_packet(onion_payloads, onion_keys, prng_seed, payment_hash)
                .map_err(|_| APIError::InvalidRoute {