Skip to content

Commit 952da4e

Browse files
committed
Add Bolt12CreationError error type to ChannelManager
Introduced the Bolt12CreationError error type for bolt12 errors that occur outside the builder. This error type is used in the ChannelManger functions. I moved, DuplicatePayment, and InsufficientLiquidity out of Bolt12SemanticsErrors into the new error type as well. Additionally, I updated the code to replace occurrences where we replaced Bolt12SemanticsErrors with the new Bolt12CreationError type throughout the relevant files.
1 parent 8551f5f commit 952da4e

File tree

3 files changed

+50
-34
lines changed

3 files changed

+50
-34
lines changed

lightning/src/ln/channelmanager.rs

Lines changed: 38 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1700,10 +1700,9 @@ where
17001700
///
17011701
/// ```
17021702
/// # use lightning::events::{Event, EventsProvider, PaymentPurpose};
1703-
/// # use lightning::ln::channelmanager::AChannelManager;
1704-
/// # use lightning::offers::parse::Bolt12SemanticError;
1703+
/// # use lightning::ln::channelmanager::{AChannelManager, Bolt12CreationError};
17051704
/// #
1706-
/// # fn example<T: AChannelManager>(channel_manager: T) -> Result<(), Bolt12SemanticError> {
1705+
/// # fn example<T: AChannelManager>(channel_manager: T) -> Result<(), Bolt12CreationError> {
17071706
/// # let channel_manager = channel_manager.get_cm();
17081707
/// # let absolute_expiry = None;
17091708
/// let offer = channel_manager
@@ -1805,13 +1804,12 @@ where
18051804
/// ```
18061805
/// # use core::time::Duration;
18071806
/// # use lightning::events::{Event, EventsProvider};
1808-
/// # use lightning::ln::channelmanager::{AChannelManager, PaymentId, RecentPaymentDetails, Retry};
1809-
/// # use lightning::offers::parse::Bolt12SemanticError;
1807+
/// # use lightning::ln::channelmanager::{AChannelManager, Bolt12CreationError, PaymentId, RecentPaymentDetails, Retry};
18101808
/// #
18111809
/// # fn example<T: AChannelManager>(
18121810
/// # channel_manager: T, amount_msats: u64, absolute_expiry: Duration, retry: Retry,
18131811
/// # max_total_routing_fee_msat: Option<u64>
1814-
/// # ) -> Result<(), Bolt12SemanticError> {
1812+
/// # ) -> Result<(), Bolt12CreationError> {
18151813
/// # let channel_manager = channel_manager.get_cm();
18161814
/// let payment_id = PaymentId([42; 32]);
18171815
/// let refund = channel_manager
@@ -2526,6 +2524,26 @@ pub enum RecentPaymentDetails {
25262524
},
25272525
}
25282526

2527+
/// Error during creation and handling of BOLT 12 related payments.
2528+
#[derive(Debug, Clone, PartialEq)]
2529+
pub enum Bolt12CreationError {
2530+
/// Error from BOLT 12 semantic checks.
2531+
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,
2536+
/// Failed to create a blinded path.
2537+
BlindedPathCreationFailed,
2538+
}
2539+
2540+
impl From<Bolt12SemanticError> for Bolt12CreationError {
2541+
fn from(err: Bolt12SemanticError) -> Self {
2542+
Bolt12CreationError::InvalidSemantics(err)
2543+
}
2544+
}
2545+
2546+
25292547
/// Route hints used in constructing invoices for [phantom node payents].
25302548
///
25312549
/// [phantom node payments]: crate::sign::PhantomKeysManager
@@ -8801,7 +8819,7 @@ macro_rules! create_offer_builder { ($self: ident, $builder: ty) => {
88018819
/// [`InvoiceRequest`]: crate::offers::invoice_request::InvoiceRequest
88028820
pub fn create_offer_builder(
88038821
&$self, absolute_expiry: Option<Duration>
8804-
) -> Result<$builder, Bolt12SemanticError> {
8822+
) -> Result<$builder, Bolt12CreationError> {
88058823
let node_id = $self.get_our_node_id();
88068824
let expanded_key = &$self.inbound_payment_key;
88078825
let entropy = &*$self.entropy_source;
@@ -8811,7 +8829,7 @@ macro_rules! create_offer_builder { ($self: ident, $builder: ty) => {
88118829
let context = OffersContext::InvoiceRequest { nonce };
88128830
let path = $self.create_blinded_paths_using_absolute_expiry(context, absolute_expiry)
88138831
.and_then(|paths| paths.into_iter().next().ok_or(()))
8814-
.map_err(|_| Bolt12SemanticError::MissingPaths)?;
8832+
.map_err(|_| Bolt12CreationError::BlindedPathCreationFailed)?;
88158833
let builder = OfferBuilder::deriving_signing_pubkey(node_id, expanded_key, nonce, secp_ctx)
88168834
.chain_hash($self.chain_hash)
88178835
.path(path);
@@ -8874,7 +8892,7 @@ macro_rules! create_refund_builder { ($self: ident, $builder: ty) => {
88748892
pub fn create_refund_builder(
88758893
&$self, amount_msats: u64, absolute_expiry: Duration, payment_id: PaymentId,
88768894
retry_strategy: Retry, max_total_routing_fee_msat: Option<u64>
8877-
) -> Result<$builder, Bolt12SemanticError> {
8895+
) -> Result<$builder, Bolt12CreationError> {
88788896
let node_id = $self.get_our_node_id();
88798897
let expanded_key = &$self.inbound_payment_key;
88808898
let entropy = &*$self.entropy_source;
@@ -8884,7 +8902,7 @@ macro_rules! create_refund_builder { ($self: ident, $builder: ty) => {
88848902
let context = OffersContext::OutboundPayment { payment_id, nonce };
88858903
let path = $self.create_blinded_paths_using_absolute_expiry(context, Some(absolute_expiry))
88868904
.and_then(|paths| paths.into_iter().next().ok_or(()))
8887-
.map_err(|_| Bolt12SemanticError::MissingPaths)?;
8905+
.map_err(|_| Bolt12CreationError::BlindedPathCreationFailed)?;
88888906

88898907
let builder = RefundBuilder::deriving_payer_id(
88908908
node_id, expanded_key, nonce, secp_ctx, amount_msats, payment_id
@@ -8900,7 +8918,7 @@ macro_rules! create_refund_builder { ($self: ident, $builder: ty) => {
89008918
.add_new_awaiting_invoice(
89018919
payment_id, expiration, retry_strategy, max_total_routing_fee_msat,
89028920
)
8903-
.map_err(|_| Bolt12SemanticError::DuplicatePaymentId)?;
8921+
.map_err(|_| Bolt12CreationError::DuplicatePaymentId)?;
89048922

89058923
Ok(builder.into())
89068924
}
@@ -8991,7 +9009,7 @@ where
89919009
&self, offer: &Offer, quantity: Option<u64>, amount_msats: Option<u64>,
89929010
payer_note: Option<String>, payment_id: PaymentId, retry_strategy: Retry,
89939011
max_total_routing_fee_msat: Option<u64>
8994-
) -> Result<(), Bolt12SemanticError> {
9012+
) -> Result<(), Bolt12CreationError> {
89959013
let expanded_key = &self.inbound_payment_key;
89969014
let entropy = &*self.entropy_source;
89979015
let secp_ctx = &self.secp_ctx;
@@ -9018,7 +9036,7 @@ where
90189036

90199037
let context = OffersContext::OutboundPayment { payment_id, nonce };
90209038
let reply_paths = self.create_blinded_paths(context)
9021-
.map_err(|_| Bolt12SemanticError::MissingPaths)?;
9039+
.map_err(|_| Bolt12CreationError::BlindedPathCreationFailed)?;
90229040

90239041
let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(self);
90249042

@@ -9027,7 +9045,7 @@ where
90279045
.add_new_awaiting_invoice(
90289046
payment_id, expiration, retry_strategy, max_total_routing_fee_msat
90299047
)
9030-
.map_err(|_| Bolt12SemanticError::DuplicatePaymentId)?;
9048+
.map_err(|_| Bolt12CreationError::DuplicatePaymentId)?;
90319049

90329050
let mut pending_offers_messages = self.pending_offers_messages.lock().unwrap();
90339051
if !offer.paths().is_empty() {
@@ -9054,7 +9072,7 @@ where
90549072
}
90559073
} else {
90569074
debug_assert!(false);
9057-
return Err(Bolt12SemanticError::MissingSigningPubkey);
9075+
return Err(Bolt12CreationError::InvalidSemantics(Bolt12SemanticError::MissingSigningPubkey));
90589076
}
90599077

90609078
Ok(())
@@ -9084,7 +9102,7 @@ where
90849102
/// [`Bolt12Invoice`]: crate::offers::invoice::Bolt12Invoice
90859103
pub fn request_refund_payment(
90869104
&self, refund: &Refund
9087-
) -> Result<Bolt12Invoice, Bolt12SemanticError> {
9105+
) -> Result<Bolt12Invoice, Bolt12CreationError> {
90889106
let expanded_key = &self.inbound_payment_key;
90899107
let entropy = &*self.entropy_source;
90909108
let secp_ctx = &self.secp_ctx;
@@ -9093,7 +9111,7 @@ where
90939111
let relative_expiry = DEFAULT_RELATIVE_EXPIRY.as_secs() as u32;
90949112

90959113
if refund.chain() != self.chain_hash {
9096-
return Err(Bolt12SemanticError::UnsupportedChain);
9114+
return Err(Bolt12CreationError::InvalidSemantics(Bolt12SemanticError::UnsupportedChain));
90979115
}
90989116

90999117
let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(self);
@@ -9104,7 +9122,7 @@ where
91049122
let payment_paths = self.create_blinded_payment_paths(
91059123
amount_msats, payment_secret, payment_context
91069124
)
9107-
.map_err(|_| Bolt12SemanticError::MissingPaths)?;
9125+
.map_err(|_| Bolt12CreationError::BlindedPathCreationFailed)?;
91089126

91099127
#[cfg(feature = "std")]
91109128
let builder = refund.respond_using_derived_keys(
@@ -9121,7 +9139,7 @@ where
91219139
let builder: InvoiceBuilder<DerivedSigningPubkey> = builder.into();
91229140
let invoice = builder.allow_mpp().build_and_sign(secp_ctx)?;
91239141
let reply_paths = self.create_blinded_paths(OffersContext::Unknown {})
9124-
.map_err(|_| Bolt12SemanticError::MissingPaths)?;
9142+
.map_err(|_| Bolt12CreationError::BlindedPathCreationFailed)?;
91259143

91269144
let mut pending_offers_messages = self.pending_offers_messages.lock().unwrap();
91279145
if refund.paths().is_empty() {
@@ -9150,7 +9168,7 @@ where
91509168

91519169
Ok(invoice)
91529170
},
9153-
Err(()) => Err(Bolt12SemanticError::InvalidAmount),
9171+
Err(()) => Err(Bolt12CreationError::InvalidSemantics(Bolt12SemanticError::InvalidAmount)),
91549172
}
91559173
}
91569174

lightning/src/ln/offers_tests.rs

Lines changed: 12 additions & 12 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::{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};
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;
@@ -1600,7 +1600,7 @@ fn fails_creating_or_paying_for_offer_without_connected_peers() {
16001600
let absolute_expiry = alice.node.duration_since_epoch() + MAX_SHORT_LIVED_RELATIVE_EXPIRY;
16011601
match alice.node.create_offer_builder(Some(absolute_expiry)) {
16021602
Ok(_) => panic!("Expected error"),
1603-
Err(e) => assert_eq!(e, Bolt12SemanticError::MissingPaths),
1603+
Err(e) => assert_eq!(e, Bolt12CreationError::BlindedPathCreationFailed),
16041604
}
16051605

16061606
let mut args = ReconnectArgs::new(alice, bob);
@@ -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, Bolt12SemanticError::MissingPaths),
1619+
Err(e) => assert_eq!(e, Bolt12CreationError::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, Bolt12SemanticError::MissingPaths),
1677+
Err(e) => assert_eq!(e, Bolt12CreationError::BlindedPathCreationFailed),
16781678
}
16791679

16801680
let mut args = ReconnectArgs::new(charlie, david);
@@ -1688,7 +1688,7 @@ fn fails_creating_refund_or_sending_invoice_without_connected_peers() {
16881688

16891689
match alice.node.request_refund_payment(&refund) {
16901690
Ok(_) => panic!("Expected error"),
1691-
Err(e) => assert_eq!(e, Bolt12SemanticError::MissingPaths),
1691+
Err(e) => assert_eq!(e, Bolt12CreationError::BlindedPathCreationFailed),
16921692
}
16931693

16941694
let mut args = ReconnectArgs::new(alice, bob);
@@ -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, Bolt12SemanticError::UnsupportedChain),
1723+
Err(e) => assert_eq!(e, Bolt12CreationError::InvalidSemantics(Bolt12SemanticError::UnsupportedChain)),
17241724
}
17251725
}
17261726

@@ -1747,7 +1747,7 @@ fn fails_sending_invoice_with_unsupported_chain_for_refund() {
17471747

17481748
match alice.node.request_refund_payment(&refund) {
17491749
Ok(_) => panic!("Expected error"),
1750-
Err(e) => assert_eq!(e, Bolt12SemanticError::UnsupportedChain),
1750+
Err(e) => assert_eq!(e, Bolt12CreationError::InvalidSemantics(Bolt12SemanticError::UnsupportedChain)),
17511751
}
17521752
}
17531753

@@ -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, Bolt12SemanticError::MissingPaths),
1783+
Err(e) => assert_eq!(e, Bolt12CreationError::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, Bolt12SemanticError::DuplicatePaymentId),
1823+
Err(e) => assert_eq!(e, Bolt12CreationError::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, Bolt12SemanticError::DuplicatePaymentId),
1851+
Err(e) => assert_eq!(e, Bolt12CreationError::DuplicatePaymentId),
18521852
}
18531853

18541854
expect_recent_payment!(nodes[0], RecentPaymentDetails::AwaitingInvoice, payment_id);
@@ -1970,7 +1970,7 @@ fn fails_sending_invoice_without_blinded_payment_paths_for_refund() {
19701970

19711971
match alice.node.request_refund_payment(&refund) {
19721972
Ok(_) => panic!("Expected error"),
1973-
Err(e) => assert_eq!(e, Bolt12SemanticError::MissingPaths),
1973+
Err(e) => assert_eq!(e, Bolt12CreationError::BlindedPathCreationFailed),
19741974
}
19751975
}
19761976

@@ -2065,4 +2065,4 @@ fn fails_paying_invoice_more_than_once() {
20652065

20662066
let invoice_error = extract_invoice_error(alice, &onion_message);
20672067
assert_eq!(invoice_error, InvoiceError::from_string("DuplicateInvoice".to_string()));
2068-
}
2068+
}

lightning/src/offers/parse.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -177,8 +177,6 @@ pub enum Bolt12SemanticError {
177177
MissingPayerMetadata,
178178
/// A payer id was expected but was missing.
179179
MissingPayerId,
180-
/// The payment id for a refund or request is already in use.
181-
DuplicatePaymentId,
182180
/// Blinded paths were expected but were missing.
183181
MissingPaths,
184182
/// Blinded paths were provided but were not expected.

0 commit comments

Comments
 (0)