Skip to content

Commit 61f7348

Browse files
committed
Add Bolt12CreationError error type
Introduce the `Bolt12CreationError` error type for handling BOLT12-related errors in the `ChannelManager`. This error type consolidates various variants, which were previously part of `Bolt12SemanticError`. Additionally, updated the relevant code to replace `Bolt12SemanticError` with `Bolt12CreationError` throughout the affected files. Note: The following commit will revert the changes in the `create_refund_builder` and `pay_for_offer` methods, switching back to `Bolt12SemanticError` temporarily. A future commit will introduce a `Bolt12RequestError` to handle these scenarios more accurately.
1 parent 2f029a9 commit 61f7348

File tree

3 files changed

+52
-33
lines changed

3 files changed

+52
-33
lines changed

lightning/src/ln/channelmanager.rs

Lines changed: 39 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1844,10 +1844,9 @@ where
18441844
///
18451845
/// ```
18461846
/// # use lightning::events::{Event, EventsProvider, PaymentPurpose};
1847-
/// # use lightning::ln::channelmanager::AChannelManager;
1848-
/// # use lightning::offers::parse::Bolt12SemanticError;
1847+
/// # use lightning::ln::channelmanager::{AChannelManager, Bolt12CreationError};
18491848
/// #
1850-
/// # fn example<T: AChannelManager>(channel_manager: T) -> Result<(), Bolt12SemanticError> {
1849+
/// # fn example<T: AChannelManager>(channel_manager: T) -> Result<(), Bolt12CreationError> {
18511850
/// # let channel_manager = channel_manager.get_cm();
18521851
/// # let absolute_expiry = None;
18531852
/// let offer = channel_manager
@@ -1947,13 +1946,12 @@ where
19471946
/// ```
19481947
/// # use core::time::Duration;
19491948
/// # use lightning::events::{Event, EventsProvider};
1950-
/// # use lightning::ln::channelmanager::{AChannelManager, PaymentId, RecentPaymentDetails, Retry};
1951-
/// # use lightning::offers::parse::Bolt12SemanticError;
1949+
/// # use lightning::ln::channelmanager::{AChannelManager, Bolt12CreationError, PaymentId, RecentPaymentDetails, Retry};
19521950
/// #
19531951
/// # fn example<T: AChannelManager>(
19541952
/// # channel_manager: T, amount_msats: u64, absolute_expiry: Duration, retry: Retry,
19551953
/// # max_total_routing_fee_msat: Option<u64>
1956-
/// # ) -> Result<(), Bolt12SemanticError> {
1954+
/// # ) -> Result<(), Bolt12CreationError> {
19571955
/// # let channel_manager = channel_manager.get_cm();
19581956
/// let payment_id = PaymentId([42; 32]);
19591957
/// let refund = channel_manager
@@ -2685,6 +2683,26 @@ pub enum RecentPaymentDetails {
26852683
},
26862684
}
26872685

2686+
/// Error during creation and handling of BOLT 12 related payments.
2687+
#[derive(Debug, Clone, PartialEq)]
2688+
pub enum Bolt12CreationError {
2689+
/// Error from BOLT 12 semantic checks.
2690+
InvalidSemantics(Bolt12SemanticError),
2691+
/// The payment id for a refund or request is already in use.
2692+
DuplicatePaymentId,
2693+
/// There is insufficient liquidity to complete the payment.
2694+
InsufficientLiquidity,
2695+
/// Failed to create a blinded path.
2696+
BlindedPathCreationFailed,
2697+
}
2698+
2699+
impl From<Bolt12SemanticError> for Bolt12CreationError {
2700+
fn from(err: Bolt12SemanticError) -> Self {
2701+
Bolt12CreationError::InvalidSemantics(err)
2702+
}
2703+
}
2704+
2705+
26882706
/// Route hints used in constructing invoices for [phantom node payents].
26892707
///
26902708
/// [phantom node payments]: crate::sign::PhantomKeysManager
@@ -9114,7 +9132,7 @@ macro_rules! create_offer_builder { ($self: ident, $builder: ty) => {
91149132
/// [`InvoiceRequest`]: crate::offers::invoice_request::InvoiceRequest
91159133
pub fn create_offer_builder(
91169134
&$self, absolute_expiry: Option<Duration>
9117-
) -> Result<$builder, Bolt12SemanticError> {
9135+
) -> Result<$builder, Bolt12CreationError> {
91189136
let node_id = $self.get_our_node_id();
91199137
let expanded_key = &$self.inbound_payment_key;
91209138
let entropy = &*$self.entropy_source;
@@ -9124,7 +9142,7 @@ macro_rules! create_offer_builder { ($self: ident, $builder: ty) => {
91249142
let context = OffersContext::InvoiceRequest { nonce };
91259143
let path = $self.create_blinded_paths_using_absolute_expiry(context, absolute_expiry)
91269144
.and_then(|paths| paths.into_iter().next().ok_or(()))
9127-
.map_err(|_| Bolt12SemanticError::MissingPaths)?;
9145+
.map_err(|()| Bolt12CreationError::BlindedPathCreationFailed)?;
91289146
let builder = OfferBuilder::deriving_signing_pubkey(node_id, expanded_key, nonce, secp_ctx)
91299147
.chain_hash($self.chain_hash)
91309148
.path(path);
@@ -9187,7 +9205,7 @@ macro_rules! create_refund_builder { ($self: ident, $builder: ty) => {
91879205
pub fn create_refund_builder(
91889206
&$self, amount_msats: u64, absolute_expiry: Duration, payment_id: PaymentId,
91899207
retry_strategy: Retry, max_total_routing_fee_msat: Option<u64>
9190-
) -> Result<$builder, Bolt12SemanticError> {
9208+
) -> Result<$builder, Bolt12CreationError> {
91919209
let node_id = $self.get_our_node_id();
91929210
let expanded_key = &$self.inbound_payment_key;
91939211
let entropy = &*$self.entropy_source;
@@ -9197,7 +9215,7 @@ macro_rules! create_refund_builder { ($self: ident, $builder: ty) => {
91979215
let context = OffersContext::OutboundPayment { payment_id, nonce, hmac: None };
91989216
let path = $self.create_blinded_paths_using_absolute_expiry(context, Some(absolute_expiry))
91999217
.and_then(|paths| paths.into_iter().next().ok_or(()))
9200-
.map_err(|_| Bolt12SemanticError::MissingPaths)?;
9218+
.map_err(|()| Bolt12CreationError::BlindedPathCreationFailed)?;
92019219

92029220
let builder = RefundBuilder::deriving_signing_pubkey(
92039221
node_id, expanded_key, nonce, secp_ctx, amount_msats, payment_id
@@ -9213,7 +9231,7 @@ macro_rules! create_refund_builder { ($self: ident, $builder: ty) => {
92139231
.add_new_awaiting_invoice(
92149232
payment_id, expiration, retry_strategy, max_total_routing_fee_msat, None,
92159233
)
9216-
.map_err(|_| Bolt12SemanticError::DuplicatePaymentId)?;
9234+
.map_err(|()| Bolt12CreationError::DuplicatePaymentId)?;
92179235

92189236
Ok(builder.into())
92199237
}
@@ -9305,7 +9323,7 @@ where
93059323
&self, offer: &Offer, quantity: Option<u64>, amount_msats: Option<u64>,
93069324
payer_note: Option<String>, payment_id: PaymentId, retry_strategy: Retry,
93079325
max_total_routing_fee_msat: Option<u64>
9308-
) -> Result<(), Bolt12SemanticError> {
9326+
) -> Result<(), Bolt12CreationError> {
93099327
let expanded_key = &self.inbound_payment_key;
93109328
let entropy = &*self.entropy_source;
93119329
let secp_ctx = &self.secp_ctx;
@@ -9335,7 +9353,7 @@ where
93359353
OffersContext::OutboundPayment { payment_id, nonce, hmac: Some(hmac) }
93369354
);
93379355
let reply_paths = self.create_blinded_paths(context)
9338-
.map_err(|_| Bolt12SemanticError::MissingPaths)?;
9356+
.map_err(|()| Bolt12CreationError::BlindedPathCreationFailed)?;
93399357

93409358
let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(self);
93419359

@@ -9349,9 +9367,10 @@ where
93499367
payment_id, expiration, retry_strategy, max_total_routing_fee_msat,
93509368
Some(retryable_invoice_request)
93519369
)
9352-
.map_err(|_| Bolt12SemanticError::DuplicatePaymentId)?;
9370+
.map_err(|()| Bolt12CreationError::DuplicatePaymentId)?;
93539371

9354-
self.enqueue_invoice_request(invoice_request, reply_paths)
9372+
self.enqueue_invoice_request(invoice_request, reply_paths)?;
9373+
Ok(())
93559374
}
93569375

93579376
fn enqueue_invoice_request(
@@ -9414,7 +9433,7 @@ where
94149433
/// [`Bolt12Invoice`]: crate::offers::invoice::Bolt12Invoice
94159434
pub fn request_refund_payment(
94169435
&self, refund: &Refund
9417-
) -> Result<Bolt12Invoice, Bolt12SemanticError> {
9436+
) -> Result<Bolt12Invoice, Bolt12CreationError> {
94189437
let expanded_key = &self.inbound_payment_key;
94199438
let entropy = &*self.entropy_source;
94209439
let secp_ctx = &self.secp_ctx;
@@ -9423,7 +9442,7 @@ where
94239442
let relative_expiry = DEFAULT_RELATIVE_EXPIRY.as_secs() as u32;
94249443

94259444
if refund.chain() != self.chain_hash {
9426-
return Err(Bolt12SemanticError::UnsupportedChain);
9445+
return Err(Bolt12CreationError::InvalidSemantics(Bolt12SemanticError::UnsupportedChain));
94279446
}
94289447

94299448
let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(self);
@@ -9434,7 +9453,7 @@ where
94349453
let payment_paths = self.create_blinded_payment_paths(
94359454
amount_msats, payment_secret, payment_context
94369455
)
9437-
.map_err(|_| Bolt12SemanticError::MissingPaths)?;
9456+
.map_err(|()| Bolt12CreationError::BlindedPathCreationFailed)?;
94389457

94399458
#[cfg(feature = "std")]
94409459
let builder = refund.respond_using_derived_keys(
@@ -9457,7 +9476,7 @@ where
94579476
payment_hash: invoice.payment_hash(), nonce, hmac
94589477
});
94599478
let reply_paths = self.create_blinded_paths(context)
9460-
.map_err(|_| Bolt12SemanticError::MissingPaths)?;
9479+
.map_err(|()| Bolt12CreationError::BlindedPathCreationFailed)?;
94619480

94629481
let mut pending_offers_messages = self.pending_offers_messages.lock().unwrap();
94639482
if refund.paths().is_empty() {
@@ -9486,7 +9505,7 @@ where
94869505

94879506
Ok(invoice)
94889507
},
9489-
Err(()) => Err(Bolt12SemanticError::InvalidAmount),
9508+
Err(()) => Err(Bolt12CreationError::InvalidSemantics(Bolt12SemanticError::InvalidAmount)),
94909509
}
94919510
}
94929511

lightning/src/ln/offers_tests.rs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ use crate::blinded_path::message::BlindedMessagePath;
4848
use crate::blinded_path::payment::{Bolt12OfferContext, Bolt12RefundContext, PaymentContext};
4949
use crate::blinded_path::message::{MessageContext, OffersContext};
5050
use crate::events::{ClosureReason, Event, MessageSendEventsProvider, PaymentFailureReason, PaymentPurpose};
51-
use crate::ln::channelmanager::{Bolt12PaymentError, MAX_SHORT_LIVED_RELATIVE_EXPIRY, PaymentId, RecentPaymentDetails, Retry, self};
51+
use crate::ln::channelmanager::{Bolt12CreationError, Bolt12PaymentError, MAX_SHORT_LIVED_RELATIVE_EXPIRY, PaymentId, RecentPaymentDetails, Retry, self};
5252
use crate::ln::features::Bolt12InvoiceFeatures;
5353
use crate::ln::functional_test_utils::*;
5454
use crate::ln::inbound_payment::ExpandedKey;
@@ -1681,7 +1681,7 @@ fn fails_creating_or_paying_for_offer_without_connected_peers() {
16811681
let absolute_expiry = alice.node.duration_since_epoch() + MAX_SHORT_LIVED_RELATIVE_EXPIRY;
16821682
match alice.node.create_offer_builder(Some(absolute_expiry)) {
16831683
Ok(_) => panic!("Expected error"),
1684-
Err(e) => assert_eq!(e, Bolt12SemanticError::MissingPaths),
1684+
Err(e) => assert_eq!(e, Bolt12CreationError::BlindedPathCreationFailed),
16851685
}
16861686

16871687
let mut args = ReconnectArgs::new(alice, bob);
@@ -1697,7 +1697,7 @@ fn fails_creating_or_paying_for_offer_without_connected_peers() {
16971697

16981698
match david.node.pay_for_offer(&offer, None, None, None, payment_id, Retry::Attempts(0), None) {
16991699
Ok(_) => panic!("Expected error"),
1700-
Err(e) => assert_eq!(e, Bolt12SemanticError::MissingPaths),
1700+
Err(e) => assert_eq!(e, Bolt12CreationError::BlindedPathCreationFailed),
17011701
}
17021702

17031703
assert!(nodes[0].node.list_recent_payments().is_empty());
@@ -1755,7 +1755,7 @@ fn fails_creating_refund_or_sending_invoice_without_connected_peers() {
17551755
10_000_000, absolute_expiry, payment_id, Retry::Attempts(0), None
17561756
) {
17571757
Ok(_) => panic!("Expected error"),
1758-
Err(e) => assert_eq!(e, Bolt12SemanticError::MissingPaths),
1758+
Err(e) => assert_eq!(e, Bolt12CreationError::BlindedPathCreationFailed),
17591759
}
17601760

17611761
let mut args = ReconnectArgs::new(charlie, david);
@@ -1769,7 +1769,7 @@ fn fails_creating_refund_or_sending_invoice_without_connected_peers() {
17691769

17701770
match alice.node.request_refund_payment(&refund) {
17711771
Ok(_) => panic!("Expected error"),
1772-
Err(e) => assert_eq!(e, Bolt12SemanticError::MissingPaths),
1772+
Err(e) => assert_eq!(e, Bolt12CreationError::BlindedPathCreationFailed),
17731773
}
17741774

17751775
let mut args = ReconnectArgs::new(alice, bob);
@@ -1801,7 +1801,7 @@ fn fails_creating_invoice_request_for_unsupported_chain() {
18011801
let payment_id = PaymentId([1; 32]);
18021802
match bob.node.pay_for_offer(&offer, None, None, None, payment_id, Retry::Attempts(0), None) {
18031803
Ok(_) => panic!("Expected error"),
1804-
Err(e) => assert_eq!(e, Bolt12SemanticError::UnsupportedChain),
1804+
Err(e) => assert_eq!(e, Bolt12CreationError::InvalidSemantics(Bolt12SemanticError::UnsupportedChain)),
18051805
}
18061806
}
18071807

@@ -1828,7 +1828,7 @@ fn fails_sending_invoice_with_unsupported_chain_for_refund() {
18281828

18291829
match alice.node.request_refund_payment(&refund) {
18301830
Ok(_) => panic!("Expected error"),
1831-
Err(e) => assert_eq!(e, Bolt12SemanticError::UnsupportedChain),
1831+
Err(e) => assert_eq!(e, Bolt12CreationError::InvalidSemantics(Bolt12SemanticError::UnsupportedChain)),
18321832
}
18331833
}
18341834

@@ -1860,7 +1860,7 @@ fn fails_creating_invoice_request_without_blinded_reply_path() {
18601860

18611861
match david.node.pay_for_offer(&offer, None, None, None, payment_id, Retry::Attempts(0), None) {
18621862
Ok(_) => panic!("Expected error"),
1863-
Err(e) => assert_eq!(e, Bolt12SemanticError::MissingPaths),
1863+
Err(e) => assert_eq!(e, Bolt12CreationError::BlindedPathCreationFailed),
18641864
}
18651865

18661866
assert!(nodes[0].node.list_recent_payments().is_empty());
@@ -1900,7 +1900,7 @@ fn fails_creating_invoice_request_with_duplicate_payment_id() {
19001900

19011901
match david.node.pay_for_offer(&offer, None, None, None, payment_id, Retry::Attempts(0), None) {
19021902
Ok(_) => panic!("Expected error"),
1903-
Err(e) => assert_eq!(e, Bolt12SemanticError::DuplicatePaymentId),
1903+
Err(e) => assert_eq!(e, Bolt12CreationError::DuplicatePaymentId),
19041904
}
19051905

19061906
expect_recent_payment!(david, RecentPaymentDetails::AwaitingInvoice, payment_id);
@@ -1928,7 +1928,7 @@ fn fails_creating_refund_with_duplicate_payment_id() {
19281928
10_000, absolute_expiry, payment_id, Retry::Attempts(0), None
19291929
) {
19301930
Ok(_) => panic!("Expected error"),
1931-
Err(e) => assert_eq!(e, Bolt12SemanticError::DuplicatePaymentId),
1931+
Err(e) => assert_eq!(e, Bolt12CreationError::DuplicatePaymentId),
19321932
}
19331933

19341934
expect_recent_payment!(nodes[0], RecentPaymentDetails::AwaitingInvoice, payment_id);
@@ -2051,7 +2051,7 @@ fn fails_sending_invoice_without_blinded_payment_paths_for_refund() {
20512051

20522052
match alice.node.request_refund_payment(&refund) {
20532053
Ok(_) => panic!("Expected error"),
2054-
Err(e) => assert_eq!(e, Bolt12SemanticError::MissingPaths),
2054+
Err(e) => assert_eq!(e, Bolt12CreationError::BlindedPathCreationFailed),
20552055
}
20562056
}
20572057

lightning/src/offers/parse.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -178,8 +178,8 @@ pub enum Bolt12SemanticError {
178178
MissingPayerMetadata,
179179
/// A payer signing pubkey was expected but was missing.
180180
MissingPayerSigningPubkey,
181-
/// The payment id for a refund or request is already in use.
182-
DuplicatePaymentId,
181+
/// A payer id was expected but was missing.
182+
MissingPayerId,
183183
/// Blinded paths were expected but were missing.
184184
MissingPaths,
185185
/// Blinded paths were provided but were not expected.

0 commit comments

Comments
 (0)