Skip to content

Commit 9cb38d8

Browse files
committed
Add a Bolt12RequestError error type
Introduces the Bolt12RequestError error type, to manage errors related to BOLT12 payment/refund requests. The variants include InvalidSemantics, DuplicatePaymentId, InsufficientLiquidity, and BlindedPathCreationFailed. Additionally, I implemented the From trait conversions to facilitate the integration of Bolt12RequestError with existing error types.
1 parent 998b2d1 commit 9cb38d8

File tree

2 files changed

+46
-22
lines changed

2 files changed

+46
-22
lines changed

lightning/src/ln/channelmanager.rs

Lines changed: 38 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1804,12 +1804,12 @@ where
18041804
/// ```
18051805
/// # use core::time::Duration;
18061806
/// # use lightning::events::{Event, EventsProvider};
1807-
/// # use lightning::ln::channelmanager::{AChannelManager, Bolt12CreationError, PaymentId, RecentPaymentDetails, Retry};
1807+
/// # use lightning::ln::channelmanager::{AChannelManager, Bolt12RequestError, PaymentId, RecentPaymentDetails, Retry};
18081808
/// #
18091809
/// # fn example<T: AChannelManager>(
18101810
/// # channel_manager: T, amount_msats: u64, absolute_expiry: Duration, retry: Retry,
18111811
/// # max_total_routing_fee_msat: Option<u64>
1812-
/// # ) -> Result<(), Bolt12CreationError> {
1812+
/// # ) -> Result<(), Bolt12RequestError> {
18131813
/// # let channel_manager = channel_manager.get_cm();
18141814
/// let payment_id = PaymentId([42; 32]);
18151815
/// let refund = channel_manager
@@ -2529,10 +2529,6 @@ pub enum RecentPaymentDetails {
25292529
pub enum Bolt12CreationError {
25302530
/// Error from BOLT 12 semantic checks.
25312531
InvalidSemantics(Bolt12SemanticError),
2532-
/// The payment id for a refund or request is already in use.
2533-
DuplicatePaymentId,
2534-
/// There is insufficient liquidity to complete the payment.
2535-
InsufficientLiquidity,
25362532
/// Failed to create a blinded path.
25372533
BlindedPathCreationFailed,
25382534
}
@@ -2543,6 +2539,34 @@ impl From<Bolt12SemanticError> for Bolt12CreationError {
25432539
}
25442540
}
25452541

2542+
/// Error during requesting a BOLT 12 related payment.
2543+
#[derive(Debug, Clone, PartialEq)]
2544+
pub enum Bolt12RequestError {
2545+
/// Error from BOLT 12 semantic checks.
2546+
InvalidSemantics(Bolt12SemanticError),
2547+
/// The payment id for a refund or request is already in use.
2548+
DuplicatePaymentId,
2549+
/// There is insufficient liquidity to complete the payment.
2550+
InsufficientLiquidity,
2551+
/// Failed to create a blinded path.
2552+
BlindedPathCreationFailed,
2553+
2554+
}
2555+
2556+
impl From<Bolt12SemanticError> for Bolt12RequestError {
2557+
fn from(err: Bolt12SemanticError) -> Self {
2558+
Bolt12RequestError::InvalidSemantics(err)
2559+
}
2560+
}
2561+
2562+
impl From<Bolt12CreationError> for Bolt12RequestError {
2563+
fn from(err: Bolt12CreationError) -> Self {
2564+
match err {
2565+
Bolt12CreationError::InvalidSemantics(semantic_err) => Bolt12RequestError::InvalidSemantics(semantic_err),
2566+
Bolt12CreationError::BlindedPathCreationFailed => Bolt12RequestError::BlindedPathCreationFailed,
2567+
}
2568+
}
2569+
}
25462570

25472571
/// Route hints used in constructing invoices for [phantom node payents].
25482572
///
@@ -8897,7 +8921,7 @@ macro_rules! create_refund_builder { ($self: ident, $builder: ty) => {
88978921
pub fn create_refund_builder(
88988922
&$self, amount_msats: u64, absolute_expiry: Duration, payment_id: PaymentId,
88998923
retry_strategy: Retry, max_total_routing_fee_msat: Option<u64>
8900-
) -> Result<$builder, Bolt12CreationError> {
8924+
) -> Result<$builder, Bolt12RequestError> {
89018925
let node_id = $self.get_our_node_id();
89028926
let expanded_key = &$self.inbound_payment_key;
89038927
let entropy = &*$self.entropy_source;
@@ -8907,12 +8931,12 @@ macro_rules! create_refund_builder { ($self: ident, $builder: ty) => {
89078931
let context = OffersContext::OutboundPayment { payment_id, nonce };
89088932
let path = $self.create_blinded_paths_using_absolute_expiry(context, Some(absolute_expiry))
89098933
.and_then(|paths| paths.into_iter().next().ok_or(()))
8910-
.map_err(|_| Bolt12CreationError::BlindedPathCreationFailed)?;
8934+
.map_err(|_| Bolt12RequestError::BlindedPathCreationFailed)?;
89118935

89128936
let total_liquidity: u64 = $self.list_channels().iter().filter(|channel| channel.is_usable).map(|channel| channel.next_outbound_htlc_limit_msat).sum();
89138937
if amount_msats > total_liquidity {
89148938
log_error!($self.logger, "Insufficient liquidity for payment with payment id: {}", payment_id);
8915-
return Err(Bolt12CreationError::InsufficientLiquidity);
8939+
return Err(Bolt12RequestError::InsufficientLiquidity);
89168940
}
89178941

89188942
let builder = RefundBuilder::deriving_payer_id(
@@ -8929,7 +8953,7 @@ macro_rules! create_refund_builder { ($self: ident, $builder: ty) => {
89298953
.add_new_awaiting_invoice(
89308954
payment_id, expiration, retry_strategy, max_total_routing_fee_msat,
89318955
)
8932-
.map_err(|_| Bolt12CreationError::DuplicatePaymentId)?;
8956+
.map_err(|_| Bolt12RequestError::DuplicatePaymentId)?;
89338957

89348958
Ok(builder.into())
89358959
}
@@ -9020,7 +9044,7 @@ where
90209044
&self, offer: &Offer, quantity: Option<u64>, amount_msats: Option<u64>,
90219045
payer_note: Option<String>, payment_id: PaymentId, retry_strategy: Retry,
90229046
max_total_routing_fee_msat: Option<u64>
9023-
) -> Result<(), Bolt12CreationError> {
9047+
) -> Result<(), Bolt12RequestError> {
90249048
let expanded_key = &self.inbound_payment_key;
90259049
let entropy = &*self.entropy_source;
90269050
let secp_ctx = &self.secp_ctx;
@@ -9061,7 +9085,7 @@ where
90619085
if let Some(amount) = total_amount_msats {
90629086
if amount > total_liquidity {
90639087
log_error!(self.logger, "Insufficient liquidity for payment with payment id: {}", payment_id);
9064-
return Err(Bolt12CreationError::InsufficientLiquidity);
9088+
return Err(Bolt12RequestError::InsufficientLiquidity);
90659089
}
90669090
}
90679091

@@ -9072,7 +9096,7 @@ where
90729096
.add_new_awaiting_invoice(
90739097
payment_id, expiration, retry_strategy, max_total_routing_fee_msat
90749098
)
9075-
.map_err(|_| Bolt12CreationError::DuplicatePaymentId)?;
9099+
.map_err(|_| Bolt12RequestError::DuplicatePaymentId)?;
90769100

90779101
let mut pending_offers_messages = self.pending_offers_messages.lock().unwrap();
90789102
if !offer.paths().is_empty() {
@@ -9099,7 +9123,7 @@ where
90999123
}
91009124
} else {
91019125
debug_assert!(false);
9102-
return Err(Bolt12CreationError::InvalidSemantics(Bolt12SemanticError::MissingSigningPubkey));
9126+
return Err(Bolt12RequestError::InvalidSemantics(Bolt12SemanticError::MissingSigningPubkey));
91039127
}
91049128

91059129
Ok(())

lightning/src/ln/offers_tests.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ use core::time::Duration;
4646
use crate::blinded_path::{BlindedPath, IntroductionNode};
4747
use crate::blinded_path::payment::{Bolt12OfferContext, Bolt12RefundContext, PaymentContext};
4848
use crate::events::{Event, MessageSendEventsProvider, PaymentPurpose};
49-
use crate::ln::channelmanager::{Bolt12CreationError, Bolt12PaymentError, MAX_SHORT_LIVED_RELATIVE_EXPIRY, PaymentId, RecentPaymentDetails, Retry, self};
49+
use crate::ln::channelmanager::{Bolt12CreationError, Bolt12PaymentError, MAX_SHORT_LIVED_RELATIVE_EXPIRY, PaymentId, RecentPaymentDetails, Retry, self, Bolt12RequestError};
5050
use crate::ln::functional_test_utils::*;
5151
use crate::ln::msgs::{ChannelMessageHandler, Init, NodeAnnouncement, OnionMessage, OnionMessageHandler, RoutingMessageHandler, SocketAddress, UnsignedGossipMessage, UnsignedNodeAnnouncement};
5252
use crate::ln::outbound_payment::IDEMPOTENCY_TIMEOUT_TICKS;
@@ -1616,7 +1616,7 @@ fn fails_creating_or_paying_for_offer_without_connected_peers() {
16161616

16171617
match david.node.pay_for_offer(&offer, None, None, None, payment_id, Retry::Attempts(0), None) {
16181618
Ok(_) => panic!("Expected error"),
1619-
Err(e) => assert_eq!(e, Bolt12CreationError::BlindedPathCreationFailed),
1619+
Err(e) => assert_eq!(e, Bolt12RequestError::BlindedPathCreationFailed),
16201620
}
16211621

16221622
assert!(nodes[0].node.list_recent_payments().is_empty());
@@ -1674,7 +1674,7 @@ fn fails_creating_refund_or_sending_invoice_without_connected_peers() {
16741674
10_000_000, absolute_expiry, payment_id, Retry::Attempts(0), None
16751675
) {
16761676
Ok(_) => panic!("Expected error"),
1677-
Err(e) => assert_eq!(e, Bolt12CreationError::BlindedPathCreationFailed),
1677+
Err(e) => assert_eq!(e, Bolt12RequestError::BlindedPathCreationFailed),
16781678
}
16791679

16801680
let mut args = ReconnectArgs::new(charlie, david);
@@ -1720,7 +1720,7 @@ fn fails_creating_invoice_request_for_unsupported_chain() {
17201720
let payment_id = PaymentId([1; 32]);
17211721
match bob.node.pay_for_offer(&offer, None, None, None, payment_id, Retry::Attempts(0), None) {
17221722
Ok(_) => panic!("Expected error"),
1723-
Err(e) => assert_eq!(e, Bolt12CreationError::InvalidSemantics(Bolt12SemanticError::UnsupportedChain)),
1723+
Err(e) => assert_eq!(e, Bolt12RequestError::InvalidSemantics(Bolt12SemanticError::UnsupportedChain)),
17241724
}
17251725
}
17261726

@@ -1780,7 +1780,7 @@ fn fails_creating_invoice_request_without_blinded_reply_path() {
17801780

17811781
match david.node.pay_for_offer(&offer, None, None, None, payment_id, Retry::Attempts(0), None) {
17821782
Ok(_) => panic!("Expected error"),
1783-
Err(e) => assert_eq!(e, Bolt12CreationError::BlindedPathCreationFailed),
1783+
Err(e) => assert_eq!(e, Bolt12RequestError::BlindedPathCreationFailed),
17841784
}
17851785

17861786
assert!(nodes[0].node.list_recent_payments().is_empty());
@@ -1820,7 +1820,7 @@ fn fails_creating_invoice_request_with_duplicate_payment_id() {
18201820

18211821
match david.node.pay_for_offer(&offer, None, None, None, payment_id, Retry::Attempts(0), None) {
18221822
Ok(_) => panic!("Expected error"),
1823-
Err(e) => assert_eq!(e, Bolt12CreationError::DuplicatePaymentId),
1823+
Err(e) => assert_eq!(e, Bolt12RequestError::DuplicatePaymentId),
18241824
}
18251825

18261826
expect_recent_payment!(david, RecentPaymentDetails::AwaitingInvoice, payment_id);
@@ -1848,7 +1848,7 @@ fn fails_creating_refund_with_duplicate_payment_id() {
18481848
10_000, absolute_expiry, payment_id, Retry::Attempts(0), None
18491849
) {
18501850
Ok(_) => panic!("Expected error"),
1851-
Err(e) => assert_eq!(e, Bolt12CreationError::DuplicatePaymentId),
1851+
Err(e) => assert_eq!(e, Bolt12RequestError::DuplicatePaymentId),
18521852
}
18531853

18541854
expect_recent_payment!(nodes[0], RecentPaymentDetails::AwaitingInvoice, payment_id);
@@ -2093,7 +2093,7 @@ fn fails_paying_offer_with_insufficient_liquidity() {
20932093
match result {
20942094
Ok(_) => panic!("Expected error with insufficient liquidity."),
20952095
Err(e) => {
2096-
assert_eq!(e, Bolt12CreationError::InsufficientLiquidity);
2096+
assert_eq!(e, Bolt12RequestError::InsufficientLiquidity);
20972097
}
20982098
}
20992099
}

0 commit comments

Comments
 (0)