Add PaymentContext to payment::ReceiveTlvs
[rust-lightning] / lightning / src / ln / channelmanager.rs
index fa8a0b2163d2ffcb828d34c07675f8ee823e9e99..6a33b2d54bc32b9506bf38d4f50f6a09535d1de8 100644 (file)
@@ -31,8 +31,8 @@ use bitcoin::secp256k1::{SecretKey,PublicKey};
 use bitcoin::secp256k1::Secp256k1;
 use bitcoin::{secp256k1, Sequence};
 
-use crate::blinded_path::BlindedPath;
-use crate::blinded_path::payment::{PaymentConstraints, ReceiveTlvs};
+use crate::blinded_path::{BlindedPath, NodeIdLookUp};
+use crate::blinded_path::payment::{PaymentConstraints, PaymentContext, ReceiveTlvs};
 use crate::chain;
 use crate::chain::{Confirm, ChannelMonitorUpdateStatus, Watch, BestBlock};
 use crate::chain::chaininterface::{BroadcasterInterface, ConfirmationTarget, FeeEstimator, LowerBoundedFeeEstimator};
@@ -61,7 +61,6 @@ use crate::ln::wire::Encode;
 use crate::offers::invoice::{BlindedPayInfo, Bolt12Invoice, DEFAULT_RELATIVE_EXPIRY, DerivedSigningPubkey, ExplicitSigningPubkey, InvoiceBuilder, UnsignedBolt12Invoice};
 use crate::offers::invoice_error::InvoiceError;
 use crate::offers::invoice_request::{DerivedPayerId, InvoiceRequestBuilder};
-use crate::offers::merkle::SignError;
 use crate::offers::offer::{Offer, OfferBuilder};
 use crate::offers::parse::Bolt12SemanticError;
 use crate::offers::refund::{Refund, RefundBuilder};
@@ -1695,15 +1694,20 @@ where
 /// #
 /// # fn example<T: AChannelManager>(channel_manager: T, refund: &Refund) {
 /// # let channel_manager = channel_manager.get_cm();
-/// match channel_manager.request_refund_payment(refund) {
-///     Ok(()) => println!("Requesting payment for refund"),
-///     Err(e) => println!("Unable to request payment for refund: {:?}", e),
-/// }
+/// let known_payment_hash = match channel_manager.request_refund_payment(refund) {
+///     Ok(invoice) => {
+///         let payment_hash = invoice.payment_hash();
+///         println!("Requesting refund payment {}", payment_hash);
+///         payment_hash
+///     },
+///     Err(e) => panic!("Unable to request payment for refund: {:?}", e),
+/// };
 ///
 /// // On the event processing thread
 /// channel_manager.process_pending_events(&|event| match event {
 ///     Event::PaymentClaimable { payment_hash, purpose, .. } => match purpose {
 ///            PaymentPurpose::InvoicePayment { payment_preimage: Some(payment_preimage), .. } => {
+///             assert_eq!(payment_hash, known_payment_hash);
 ///             println!("Claiming payment {}", payment_hash);
 ///             channel_manager.claim_funds(payment_preimage);
 ///         },
@@ -1714,6 +1718,7 @@ where
 /// #         _ => {},
 ///     },
 ///     Event::PaymentClaimed { payment_hash, amount_msat, .. } => {
+///         assert_eq!(payment_hash, known_payment_hash);
 ///         println!("Claimed {} msats", amount_msat);
 ///     },
 ///     // ...
@@ -8775,7 +8780,7 @@ where
        ///
        /// The resulting invoice uses a [`PaymentHash`] recognized by the [`ChannelManager`] and a
        /// [`BlindedPath`] containing the [`PaymentSecret`] needed to reconstruct the corresponding
-       /// [`PaymentPreimage`].
+       /// [`PaymentPreimage`]. It is returned purely for informational purposes.
        ///
        /// # Limitations
        ///
@@ -8792,7 +8797,9 @@ where
        ///   the invoice.
        ///
        /// [`Bolt12Invoice`]: crate::offers::invoice::Bolt12Invoice
-       pub fn request_refund_payment(&self, refund: &Refund) -> Result<(), Bolt12SemanticError> {
+       pub fn request_refund_payment(
+               &self, refund: &Refund
+       ) -> Result<Bolt12Invoice, Bolt12SemanticError> {
                let expanded_key = &self.inbound_payment_key;
                let entropy = &*self.entropy_source;
                let secp_ctx = &self.secp_ctx;
@@ -8831,7 +8838,7 @@ where
                                let mut pending_offers_messages = self.pending_offers_messages.lock().unwrap();
                                if refund.paths().is_empty() {
                                        let message = new_pending_onion_message(
-                                               OffersMessage::Invoice(invoice),
+                                               OffersMessage::Invoice(invoice.clone()),
                                                Destination::Node(refund.payer_id()),
                                                Some(reply_path),
                                        );
@@ -8847,7 +8854,7 @@ where
                                        }
                                }
 
-                               Ok(())
+                               Ok(invoice)
                        },
                        Err(()) => Err(Bolt12SemanticError::InvalidAmount),
                }
@@ -8988,6 +8995,7 @@ where
                                max_cltv_expiry,
                                htlc_minimum_msat: 1,
                        },
+                       payment_context: PaymentContext::unknown(),
                };
                self.router.create_blinded_payment_paths(
                        payee_node_id, first_hops, payee_tlvs, amount_msats, secp_ctx
@@ -10356,7 +10364,7 @@ where
                                        self.highest_seen_timestamp.load(Ordering::Acquire) as u64
                                );
 
-                               if invoice_request.keys.is_some() {
+                               let response = if invoice_request.keys.is_some() {
                                        #[cfg(feature = "std")]
                                        let builder = invoice_request.respond_using_derived_keys(
                                                payment_paths, payment_hash
@@ -10365,12 +10373,10 @@ where
                                        let builder = invoice_request.respond_using_derived_keys_no_std(
                                                payment_paths, payment_hash, created_at
                                        );
-                                       let builder: Result<InvoiceBuilder<DerivedSigningPubkey>, _> =
-                                               builder.map(|b| b.into());
-                                       match builder.and_then(|b| b.allow_mpp().build_and_sign(secp_ctx)) {
-                                               Ok(invoice) => Some(OffersMessage::Invoice(invoice)),
-                                               Err(error) => Some(OffersMessage::InvoiceError(error.into())),
-                                       }
+                                       builder
+                                               .map(InvoiceBuilder::<DerivedSigningPubkey>::from)
+                                               .and_then(|builder| builder.allow_mpp().build_and_sign(secp_ctx))
+                                               .map_err(InvoiceError::from)
                                } else {
                                        #[cfg(feature = "std")]
                                        let builder = invoice_request.respond_with(payment_paths, payment_hash);
@@ -10378,47 +10384,46 @@ where
                                        let builder = invoice_request.respond_with_no_std(
                                                payment_paths, payment_hash, created_at
                                        );
-                                       let builder: Result<InvoiceBuilder<ExplicitSigningPubkey>, _> =
-                                               builder.map(|b| b.into());
-                                       let response = builder.and_then(|builder| builder.allow_mpp().build())
-                                               .map_err(|e| OffersMessage::InvoiceError(e.into()))
+                                       builder
+                                               .map(InvoiceBuilder::<ExplicitSigningPubkey>::from)
+                                               .and_then(|builder| builder.allow_mpp().build())
+                                               .map_err(InvoiceError::from)
                                                .and_then(|invoice| {
                                                        #[cfg(c_bindings)]
                                                        let mut invoice = invoice;
-                                                       match invoice.sign(|invoice: &UnsignedBolt12Invoice|
-                                                               self.node_signer.sign_bolt12_invoice(invoice)
-                                                       ) {
-                                                               Ok(invoice) => Ok(OffersMessage::Invoice(invoice)),
-                                                               Err(SignError::Signing) => Err(OffersMessage::InvoiceError(
-                                                                               InvoiceError::from_string("Failed signing invoice".to_string())
-                                                               )),
-                                                               Err(SignError::Verification(_)) => Err(OffersMessage::InvoiceError(
-                                                                               InvoiceError::from_string("Failed invoice signature verification".to_string())
-                                                               )),
-                                                       }
-                                               });
-                                       match response {
-                                               Ok(invoice) => Some(invoice),
-                                               Err(error) => Some(error),
-                                       }
+                                                       invoice
+                                                               .sign(|invoice: &UnsignedBolt12Invoice|
+                                                                       self.node_signer.sign_bolt12_invoice(invoice)
+                                                               )
+                                                               .map_err(InvoiceError::from)
+                                               })
+                               };
+
+                               match response {
+                                       Ok(invoice) => Some(OffersMessage::Invoice(invoice)),
+                                       Err(error) => Some(OffersMessage::InvoiceError(error.into())),
                                }
                        },
                        OffersMessage::Invoice(invoice) => {
-                               match invoice.verify(expanded_key, secp_ctx) {
-                                       Err(()) => {
-                                               Some(OffersMessage::InvoiceError(InvoiceError::from_string("Unrecognized invoice".to_owned())))
-                                       },
-                                       Ok(_) if invoice.invoice_features().requires_unknown_bits_from(&self.bolt12_invoice_features()) => {
-                                               Some(OffersMessage::InvoiceError(Bolt12SemanticError::UnknownRequiredFeatures.into()))
-                                       },
-                                       Ok(payment_id) => {
-                                               if let Err(e) = self.send_payment_for_bolt12_invoice(&invoice, payment_id) {
-                                                       log_trace!(self.logger, "Failed paying invoice: {:?}", e);
-                                                       Some(OffersMessage::InvoiceError(InvoiceError::from_string(format!("{:?}", e))))
+                               let response = invoice
+                                       .verify(expanded_key, secp_ctx)
+                                       .map_err(|()| InvoiceError::from_string("Unrecognized invoice".to_owned()))
+                                       .and_then(|payment_id| {
+                                               let features = self.bolt12_invoice_features();
+                                               if invoice.invoice_features().requires_unknown_bits_from(&features) {
+                                                       Err(InvoiceError::from(Bolt12SemanticError::UnknownRequiredFeatures))
                                                } else {
-                                                       None
+                                                       self.send_payment_for_bolt12_invoice(&invoice, payment_id)
+                                                               .map_err(|e| {
+                                                                       log_trace!(self.logger, "Failed paying invoice: {:?}", e);
+                                                                       InvoiceError::from_string(format!("{:?}", e))
+                                                               })
                                                }
-                                       },
+                                       });
+
+                               match response {
+                                       Ok(()) => None,
+                                       Err(e) => Some(OffersMessage::InvoiceError(e)),
                                }
                        },
                        OffersMessage::InvoiceError(invoice_error) => {
@@ -10433,6 +10438,23 @@ where
        }
 }
 
+impl<M: Deref, T: Deref, ES: Deref, NS: Deref, SP: Deref, F: Deref, R: Deref, L: Deref>
+NodeIdLookUp for ChannelManager<M, T, ES, NS, SP, F, R, L>
+where
+       M::Target: chain::Watch<<SP::Target as SignerProvider>::EcdsaSigner>,
+       T::Target: BroadcasterInterface,
+       ES::Target: EntropySource,
+       NS::Target: NodeSigner,
+       SP::Target: SignerProvider,
+       F::Target: FeeEstimator,
+       R::Target: Router,
+       L::Target: Logger,
+{
+       fn next_node_id(&self, short_channel_id: u64) -> Option<PublicKey> {
+               self.short_to_chan_info.read().unwrap().get(&short_channel_id).map(|(pubkey, _)| *pubkey)
+       }
+}
+
 /// Fetches the set of [`NodeFeatures`] flags that are provided by or required by
 /// [`ChannelManager`].
 pub(crate) fn provided_node_features(config: &UserConfig) -> NodeFeatures {