Merge pull request #3125 from valentinewallace/2024-06-async-payments-prefactor
[rust-lightning] / lightning / src / ln / onion_payment.rs
index 31ecc6ddd2345a6fdf52e764bb40453530902239..f62ca5d84e637bc4d95bb48d679f00151a756d0e 100644 (file)
@@ -11,8 +11,8 @@ use bitcoin::secp256k1::{self, PublicKey, Scalar, Secp256k1};
 use crate::blinded_path;
 use crate::blinded_path::payment::{PaymentConstraints, PaymentRelay};
 use crate::chain::channelmonitor::{HTLC_FAIL_BACK_BUFFER, LATENCY_GRACE_PERIOD_BLOCKS};
-use crate::ln::PaymentHash;
-use crate::ln::channelmanager::{BlindedForward, CLTV_FAR_FAR_AWAY, HTLCFailureMsg, MIN_CLTV_EXPIRY_DELTA, PendingHTLCInfo, PendingHTLCRouting};
+use crate::ln::types::PaymentHash;
+use crate::ln::channelmanager::{BlindedFailure, BlindedForward, CLTV_FAR_FAR_AWAY, HTLCFailureMsg, MIN_CLTV_EXPIRY_DELTA, PendingHTLCInfo, PendingHTLCRouting};
 use crate::ln::features::BlindedHopFeatures;
 use crate::ln::msgs;
 use crate::ln::onion_utils;
@@ -20,11 +20,13 @@ use crate::ln::onion_utils::{HTLCFailReason, INVALID_ONION_BLINDING};
 use crate::sign::{NodeSigner, Recipient};
 use crate::util::logger::Logger;
 
+#[allow(unused_imports)]
 use crate::prelude::*;
+
 use core::ops::Deref;
 
 /// Invalid inbound onion payment.
-#[derive(Debug)]
+#[derive(Clone, Debug, Hash, PartialEq, Eq)]
 pub struct InboundHTLCErr {
        /// BOLT 4 error code.
        pub err_code: u16,
@@ -73,7 +75,7 @@ pub(super) fn create_fwd_pending_htlc_info(
        };
 
        let (
-               short_channel_id, amt_to_forward, outgoing_cltv_value, inbound_blinding_point
+               short_channel_id, amt_to_forward, outgoing_cltv_value, intro_node_blinding_point
        ) = match hop_data {
                msgs::InboundOnionPayload::Forward { short_channel_id, amt_to_forward, outgoing_cltv_value } =>
                        (short_channel_id, amt_to_forward, outgoing_cltv_value, None),
@@ -91,7 +93,7 @@ pub(super) fn create_fwd_pending_htlc_info(
                                        err_data: vec![0; 32],
                                }
                        })?;
-                       (short_channel_id, amt_to_forward, outgoing_cltv_value, Some(intro_node_blinding_point))
+                       (short_channel_id, amt_to_forward, outgoing_cltv_value, intro_node_blinding_point)
                },
                msgs::InboundOnionPayload::Receive { .. } | msgs::InboundOnionPayload::BlindedReceive { .. } =>
                        return Err(InboundHTLCErr {
@@ -105,7 +107,13 @@ pub(super) fn create_fwd_pending_htlc_info(
                routing: PendingHTLCRouting::Forward {
                        onion_packet: outgoing_packet,
                        short_channel_id,
-                       blinded: inbound_blinding_point.map(|bp| BlindedForward { inbound_blinding_point: bp }),
+                       blinded: intro_node_blinding_point.or(msg.blinding_point)
+                               .map(|bp| BlindedForward {
+                                       inbound_blinding_point: bp,
+                                       failure: intro_node_blinding_point
+                                               .map(|_| BlindedFailure::FromIntroductionNode)
+                                               .unwrap_or(BlindedFailure::FromBlindedNode),
+                               }),
                },
                payment_hash: msg.payment_hash,
                incoming_shared_secret: shared_secret,
@@ -122,19 +130,23 @@ pub(super) fn create_recv_pending_htlc_info(
        counterparty_skimmed_fee_msat: Option<u64>, current_height: u32, accept_mpp_keysend: bool,
 ) -> Result<PendingHTLCInfo, InboundHTLCErr> {
        let (
-               payment_data, keysend_preimage, custom_tlvs, onion_amt_msat, outgoing_cltv_value,
-               payment_metadata, requires_blinded_error
+               payment_data, keysend_preimage, custom_tlvs, onion_amt_msat, onion_cltv_expiry,
+               payment_metadata, payment_context, requires_blinded_error
        ) = match hop_data {
                msgs::InboundOnionPayload::Receive {
-                       payment_data, keysend_preimage, custom_tlvs, amt_msat, outgoing_cltv_value, payment_metadata, ..
+                       payment_data, keysend_preimage, custom_tlvs, sender_intended_htlc_amt_msat,
+                       cltv_expiry_height, payment_metadata, ..
                } =>
-                       (payment_data, keysend_preimage, custom_tlvs, amt_msat, outgoing_cltv_value, payment_metadata,
-                        false),
+                       (payment_data, keysend_preimage, custom_tlvs, sender_intended_htlc_amt_msat,
+                        cltv_expiry_height, payment_metadata, None, false),
                msgs::InboundOnionPayload::BlindedReceive {
-                       amt_msat, total_msat, outgoing_cltv_value, payment_secret, intro_node_blinding_point,
-                       payment_constraints, ..
+                       sender_intended_htlc_amt_msat, total_msat, cltv_expiry_height, payment_secret,
+                       intro_node_blinding_point, payment_constraints, payment_context, keysend_preimage,
+                       custom_tlvs
                } => {
-                       check_blinded_payment_constraints(amt_msat, cltv_expiry, &payment_constraints)
+                       check_blinded_payment_constraints(
+                               sender_intended_htlc_amt_msat, cltv_expiry, &payment_constraints
+                       )
                                .map_err(|()| {
                                        InboundHTLCErr {
                                                err_code: INVALID_ONION_BLINDING,
@@ -143,7 +155,8 @@ pub(super) fn create_recv_pending_htlc_info(
                                        }
                                })?;
                        let payment_data = msgs::FinalOnionHopData { payment_secret, total_msat };
-                       (Some(payment_data), None, Vec::new(), amt_msat, outgoing_cltv_value, None,
+                       (Some(payment_data), keysend_preimage, custom_tlvs,
+                        sender_intended_htlc_amt_msat, cltv_expiry_height, None, Some(payment_context),
                         intro_node_blinding_point.is_none())
                }
                msgs::InboundOnionPayload::Forward { .. } => {
@@ -162,7 +175,7 @@ pub(super) fn create_recv_pending_htlc_info(
                }
        };
        // final_incorrect_cltv_expiry
-       if outgoing_cltv_value > cltv_expiry {
+       if onion_cltv_expiry > cltv_expiry {
                return Err(InboundHTLCErr {
                        msg: "Upstream node set CLTV to less than the CLTV set by the sender",
                        err_code: 18,
@@ -221,14 +234,16 @@ pub(super) fn create_recv_pending_htlc_info(
                        payment_data,
                        payment_preimage,
                        payment_metadata,
-                       incoming_cltv_expiry: outgoing_cltv_value,
+                       incoming_cltv_expiry: onion_cltv_expiry,
                        custom_tlvs,
+                       requires_blinded_error,
                }
        } else if let Some(data) = payment_data {
                PendingHTLCRouting::Receive {
                        payment_data: data,
                        payment_metadata,
-                       incoming_cltv_expiry: outgoing_cltv_value,
+                       payment_context,
+                       incoming_cltv_expiry: onion_cltv_expiry,
                        phantom_shared_secret,
                        custom_tlvs,
                        requires_blinded_error,
@@ -246,7 +261,7 @@ pub(super) fn create_recv_pending_htlc_info(
                incoming_shared_secret: shared_secret,
                incoming_amt_msat: Some(amt_msat),
                outgoing_amt_msat: onion_amt_msat,
-               outgoing_cltv_value,
+               outgoing_cltv_value: onion_cltv_expiry,
                skimmed_fee_msat: counterparty_skimmed_fee_msat,
        })
 }
@@ -489,8 +504,7 @@ mod tests {
        use bitcoin::hashes::Hash;
        use bitcoin::hashes::sha256::Hash as Sha256;
        use bitcoin::secp256k1::{PublicKey, Secp256k1, SecretKey};
-       use crate::ln::{PaymentPreimage, PaymentHash, PaymentSecret};
-       use crate::ln::ChannelId;
+       use crate::ln::types::{ChannelId, PaymentPreimage, PaymentHash, PaymentSecret};
        use crate::ln::channelmanager::RecipientOnionFields;
        use crate::ln::features::{ChannelFeatures, NodeFeatures};
        use crate::ln::msgs;
@@ -522,7 +536,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)
                ).unwrap();
 
                assert!(super::onion_utils::construct_onion_packet(
@@ -549,8 +563,8 @@ mod tests {
                };
 
                let (onion, amount_msat, cltv_expiry) = create_payment_onion(
-                       &secp_ctx, &path, &session_priv, total_amt_msat, recipient_onion, cur_height,
-                       &payment_hash, &Some(preimage), prng_seed
+                       &secp_ctx, &path, &session_priv, total_amt_msat, &recipient_onion,
+                       cur_height, &payment_hash, &Some(preimage), prng_seed
                ).unwrap();
 
                let msg = make_update_add_msg(amount_msat, cltv_expiry, payment_hash, onion);