diff --git a/lightning/src/ln/channelmanager.rs b/lightning/src/ln/channelmanager.rs index 7bcc34dc8a6..87de881f262 100644 --- a/lightning/src/ln/channelmanager.rs +++ b/lightning/src/ln/channelmanager.rs @@ -1759,13 +1759,13 @@ where /// ``` /// # use core::time::Duration; /// # use lightning::events::{Event, EventsProvider}; -/// # use lightning::ln::channelmanager::{AChannelManager, PaymentId, RecentPaymentDetails, Retry}; +/// # use lightning::ln::channelmanager::{AChannelManager, Bolt12CreationError, PaymentId, RecentPaymentDetails, Retry}; /// # use lightning::offers::parse::Bolt12SemanticError; /// # /// # fn example( /// # channel_manager: T, amount_msats: u64, absolute_expiry: Duration, retry: Retry, /// # max_total_routing_fee_msat: Option -/// # ) -> Result<(), Bolt12SemanticError> { +/// # ) -> Result<(), Bolt12CreationError> { /// # let channel_manager = channel_manager.get_cm(); /// let payment_id = PaymentId([42; 32]); /// let refund = channel_manager @@ -2477,6 +2477,26 @@ pub enum RecentPaymentDetails { }, } +/// Error during creation and handling of BOLT 12 related payments. +#[derive(Debug, Clone, PartialEq)] +pub enum Bolt12CreationError { + /// Error from BOLT 12 semantic checks. + Bolt12SendingError(Bolt12SemanticError), + /// The payment id for a refund or request is already in use. + DuplicatePaymentId, + /// There is insufficient liquidity to complete the payment. + InsufficientLiquidity, + /// Failed to create a blinded path. + FailedToCreateBlindedPath +} + +impl From for Bolt12CreationError { + fn from(err: Bolt12SemanticError) -> Self { + Bolt12CreationError::Bolt12SendingError(err) + } +} + + /// Route hints used in constructing invoices for [phantom node payents]. /// /// [phantom node payments]: crate::sign::PhantomKeysManager @@ -8726,7 +8746,7 @@ macro_rules! create_refund_builder { ($self: ident, $builder: ty) => { pub fn create_refund_builder( &$self, amount_msats: u64, absolute_expiry: Duration, payment_id: PaymentId, retry_strategy: Retry, max_total_routing_fee_msat: Option - ) -> Result<$builder, Bolt12SemanticError> { + ) -> Result<$builder, Bolt12CreationError> { let node_id = $self.get_our_node_id(); let expanded_key = &$self.inbound_payment_key; let entropy = &*$self.entropy_source; @@ -8751,7 +8771,7 @@ macro_rules! create_refund_builder { ($self: ident, $builder: ty) => { .add_new_awaiting_invoice( payment_id, expiration, retry_strategy, max_total_routing_fee_msat, ) - .map_err(|_| Bolt12SemanticError::DuplicatePaymentId)?; + .map_err(|_| Bolt12CreationError::DuplicatePaymentId)?; Ok(builder.into()) } @@ -8842,7 +8862,7 @@ where &self, offer: &Offer, quantity: Option, amount_msats: Option, payer_note: Option, payment_id: PaymentId, retry_strategy: Retry, max_total_routing_fee_msat: Option - ) -> Result<(), Bolt12SemanticError> { + ) -> Result<(), Bolt12CreationError> { let expanded_key = &self.inbound_payment_key; let entropy = &*self.entropy_source; let secp_ctx = &self.secp_ctx; @@ -8878,7 +8898,7 @@ where if let Some(amount) = total_amount_msats { if amount > total_liquidity { log_error!(self.logger, "Insufficient liquidity for payment with payment id: {}", payment_id); - return Err(Bolt12SemanticError::InsufficientLiquidity); + return Err(Bolt12CreationError::InsufficientLiquidity); } } @@ -8892,7 +8912,7 @@ where .add_new_awaiting_invoice( payment_id, expiration, retry_strategy, max_total_routing_fee_msat ) - .map_err(|_| Bolt12SemanticError::DuplicatePaymentId)?; + .map_err(|_| Bolt12CreationError::DuplicatePaymentId)?; let mut pending_offers_messages = self.pending_offers_messages.lock().unwrap(); if !offer.paths().is_empty() { @@ -8919,7 +8939,7 @@ where } } else { debug_assert!(false); - return Err(Bolt12SemanticError::MissingSigningPubkey); + return Err(Bolt12CreationError::Bolt12SendingError(Bolt12SemanticError::MissingSigningPubkey)); } Ok(()) diff --git a/lightning/src/ln/offers_tests.rs b/lightning/src/ln/offers_tests.rs index 1f33a9a2460..84177dd124f 100644 --- a/lightning/src/ln/offers_tests.rs +++ b/lightning/src/ln/offers_tests.rs @@ -46,7 +46,7 @@ use core::time::Duration; use crate::blinded_path::{BlindedPath, IntroductionNode}; use crate::blinded_path::payment::{Bolt12OfferContext, Bolt12RefundContext, PaymentContext}; use crate::events::{Event, MessageSendEventsProvider, PaymentPurpose}; -use crate::ln::channelmanager::{Bolt12PaymentError, MAX_SHORT_LIVED_RELATIVE_EXPIRY, PaymentId, RecentPaymentDetails, Retry, self}; +use crate::ln::channelmanager::{Bolt12CreationError, Bolt12PaymentError, MAX_SHORT_LIVED_RELATIVE_EXPIRY, PaymentId, RecentPaymentDetails, Retry, self}; use crate::ln::functional_test_utils::*; use crate::ln::msgs::{ChannelMessageHandler, Init, NodeAnnouncement, OnionMessage, OnionMessageHandler, RoutingMessageHandler, SocketAddress, UnsignedGossipMessage, UnsignedNodeAnnouncement}; use crate::ln::outbound_payment::IDEMPOTENCY_TIMEOUT_TICKS; @@ -1276,7 +1276,7 @@ fn fails_creating_or_paying_for_offer_without_connected_peers() { match david.node.pay_for_offer(&offer, None, None, None, payment_id, Retry::Attempts(0), None) { Ok(_) => panic!("Expected error"), - Err(e) => assert_eq!(e, Bolt12SemanticError::MissingPaths), + Err(e) => assert_eq!(e, Bolt12CreationError::Bolt12SendingError(Bolt12SemanticError::MissingPaths)), } assert!(nodes[0].node.list_recent_payments().is_empty()); @@ -1334,7 +1334,7 @@ fn fails_creating_refund_or_sending_invoice_without_connected_peers() { 10_000_000, absolute_expiry, payment_id, Retry::Attempts(0), None ) { Ok(_) => panic!("Expected error"), - Err(e) => assert_eq!(e, Bolt12SemanticError::MissingPaths), + Err(e) => assert_eq!(e, Bolt12CreationError::Bolt12SendingError(Bolt12SemanticError::MissingPaths)), } let mut args = ReconnectArgs::new(charlie, david); @@ -1380,7 +1380,7 @@ fn fails_creating_invoice_request_for_unsupported_chain() { let payment_id = PaymentId([1; 32]); match bob.node.pay_for_offer(&offer, None, None, None, payment_id, Retry::Attempts(0), None) { Ok(_) => panic!("Expected error"), - Err(e) => assert_eq!(e, Bolt12SemanticError::UnsupportedChain), + Err(e) => assert_eq!(e, Bolt12CreationError::Bolt12SendingError(Bolt12SemanticError::UnsupportedChain)), } } @@ -1440,7 +1440,7 @@ fn fails_creating_invoice_request_without_blinded_reply_path() { match david.node.pay_for_offer(&offer, None, None, None, payment_id, Retry::Attempts(0), None) { Ok(_) => panic!("Expected error"), - Err(e) => assert_eq!(e, Bolt12SemanticError::MissingPaths), + Err(e) => assert_eq!(e, Bolt12CreationError::Bolt12SendingError(Bolt12SemanticError::MissingPaths)), } assert!(nodes[0].node.list_recent_payments().is_empty()); @@ -1480,7 +1480,7 @@ fn fails_creating_invoice_request_with_duplicate_payment_id() { match david.node.pay_for_offer(&offer, None, None, None, payment_id, Retry::Attempts(0), None) { Ok(_) => panic!("Expected error"), - Err(e) => assert_eq!(e, Bolt12SemanticError::DuplicatePaymentId), + Err(e) => assert_eq!(e, Bolt12CreationError::DuplicatePaymentId), } expect_recent_payment!(david, RecentPaymentDetails::AwaitingInvoice, payment_id); @@ -1508,7 +1508,7 @@ fn fails_creating_refund_with_duplicate_payment_id() { 10_000, absolute_expiry, payment_id, Retry::Attempts(0), None ) { Ok(_) => panic!("Expected error"), - Err(e) => assert_eq!(e, Bolt12SemanticError::DuplicatePaymentId), + Err(e) => assert_eq!(e, Bolt12CreationError::DuplicatePaymentId), } expect_recent_payment!(nodes[0], RecentPaymentDetails::AwaitingInvoice, payment_id); @@ -1753,7 +1753,7 @@ fn test_insufficient_liquidity_for_bolt12_offer() { match result { Ok(_) => panic!("Expected error with insufficient liquidity."), Err(e) => { - assert_eq!(e, Bolt12SemanticError::InsufficientLiquidity); + assert_eq!(e, Bolt12CreationError::InsufficientLiquidity); } } } diff --git a/lightning/src/offers/parse.rs b/lightning/src/offers/parse.rs index 00181d1ef27..8ed40c3026f 100644 --- a/lightning/src/offers/parse.rs +++ b/lightning/src/offers/parse.rs @@ -177,8 +177,6 @@ pub enum Bolt12SemanticError { MissingPayerMetadata, /// A payer id was expected but was missing. MissingPayerId, - /// The payment id for a refund or request is already in use. - DuplicatePaymentId, /// Blinded paths were expected but were missing. MissingPaths, /// Blinded paths were provided but were not expected. @@ -193,8 +191,6 @@ pub enum Bolt12SemanticError { UnexpectedPaymentHash, /// A signature was expected but was missing. MissingSignature, - /// There is insufficient liquidity to complete the payment. - InsufficientLiquidity, } impl From for Bolt12ParseError {