Skip to content

Commit 9f31819

Browse files
committed
Move create_static_invoice_builder to flow.rs
1 parent e812422 commit 9f31819

File tree

4 files changed

+106
-58
lines changed

4 files changed

+106
-58
lines changed

lightning/src/ln/async_payments_tests.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ fn create_static_invoice<T: secp256k1::Signing + secp256k1::Verification>(
5454
.unwrap();
5555
let offer = offer_builder.build().unwrap();
5656
let static_invoice = recipient
57-
.node
57+
.offers_handler
5858
.create_static_invoice_builder(&offer, offer_nonce, relative_expiry)
5959
.unwrap()
6060
.build_and_sign(&secp_ctx)
@@ -160,7 +160,7 @@ fn static_invoice_unknown_required_features() {
160160
.unwrap();
161161
let offer = offer_builder.build().unwrap();
162162
let static_invoice_unknown_req_features = nodes[2]
163-
.node
163+
.offers_handler
164164
.create_static_invoice_builder(&offer, nonce, None)
165165
.unwrap()
166166
.features_unchecked(Bolt12InvoiceFeatures::unknown())

lightning/src/ln/channelmanager.rs

Lines changed: 7 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -86,11 +86,8 @@ use crate::util::ser::{BigSize, FixedLengthReader, Readable, ReadableArgs, Maybe
8686
use crate::util::ser::TransactionU16LenLimited;
8787
use crate::util::logger::{Level, Logger, WithContext};
8888
use crate::util::errors::APIError;
89-
#[cfg(async_payments)] use {
90-
crate::blinded_path::payment::AsyncBolt12OfferContext,
91-
crate::offers::offer::Amount,
92-
crate::offers::static_invoice::{DEFAULT_RELATIVE_EXPIRY as STATIC_INVOICE_DEFAULT_RELATIVE_EXPIRY, StaticInvoice, StaticInvoiceBuilder},
93-
};
89+
#[cfg(async_payments)]
90+
use crate::offers::static_invoice::StaticInvoice;
9491

9592
#[cfg(feature = "dnssec")]
9693
use crate::blinded_path::message::DNSResolverContext;
@@ -9657,6 +9654,11 @@ where
96579654
payment_id, expiration, retry_strategy, max_total_routing_fee_msat, retryable_invoice_request,
96589655
)
96599656
}
9657+
9658+
#[cfg(not(feature = "std"))]
9659+
fn get_highest_seen_timestamp(&self) -> Duration {
9660+
Duration::from_secs(self.highest_seen_timestamp.load(Ordering::Acquire) as u64)
9661+
}
96609662
}
96619663

96629664
/// Defines the maximum number of [`OffersMessage`] including different reply paths to be sent
@@ -9678,55 +9680,6 @@ where
96789680
MR::Target: MessageRouter,
96799681
L::Target: Logger,
96809682
{
9681-
/// Creates a [`StaticInvoiceBuilder`] from the corresponding [`Offer`] and [`Nonce`] that were
9682-
/// created via [`create_async_receive_offer_builder`]. If `relative_expiry` is unset, the
9683-
/// invoice's expiry will default to [`STATIC_INVOICE_DEFAULT_RELATIVE_EXPIRY`].
9684-
///
9685-
/// [`create_async_receive_offer_builder`]: crate::offers::flow::create_async_receive_offer_builder
9686-
#[cfg(async_payments)]
9687-
pub fn create_static_invoice_builder<'a>(
9688-
&self, offer: &'a Offer, offer_nonce: Nonce, relative_expiry: Option<Duration>
9689-
) -> Result<StaticInvoiceBuilder<'a>, Bolt12SemanticError> {
9690-
let expanded_key = &self.inbound_payment_key;
9691-
let entropy = &*self.entropy_source;
9692-
let secp_ctx = &self.secp_ctx;
9693-
9694-
let payment_context = PaymentContext::AsyncBolt12Offer(
9695-
AsyncBolt12OfferContext { offer_nonce }
9696-
);
9697-
let amount_msat = offer.amount().and_then(|amount| {
9698-
match amount {
9699-
Amount::Bitcoin { amount_msats } => Some(amount_msats),
9700-
Amount::Currency { .. } => None
9701-
}
9702-
});
9703-
9704-
let relative_expiry = relative_expiry.unwrap_or(STATIC_INVOICE_DEFAULT_RELATIVE_EXPIRY);
9705-
let relative_expiry_secs: u32 = relative_expiry.as_secs().try_into().unwrap_or(u32::MAX);
9706-
9707-
let created_at = self.duration_since_epoch();
9708-
let payment_secret = inbound_payment::create_for_spontaneous_payment(
9709-
&self.inbound_payment_key, amount_msat, relative_expiry_secs, created_at.as_secs(), None
9710-
).map_err(|()| Bolt12SemanticError::InvalidAmount)?;
9711-
9712-
let payment_paths = self.create_blinded_payment_paths(
9713-
amount_msat, payment_secret, payment_context, relative_expiry_secs
9714-
).map_err(|()| Bolt12SemanticError::MissingPaths)?;
9715-
9716-
let nonce = Nonce::from_entropy_source(entropy);
9717-
let hmac = signer::hmac_for_held_htlc_available_context(nonce, expanded_key);
9718-
let context = MessageContext::AsyncPayments(
9719-
AsyncPaymentsContext::InboundPayment { nonce, hmac }
9720-
);
9721-
let async_receive_message_paths = self.create_blinded_paths(context)
9722-
.map_err(|()| Bolt12SemanticError::MissingPaths)?;
9723-
9724-
StaticInvoiceBuilder::for_offer_using_derived_keys(
9725-
offer, payment_paths, async_receive_message_paths, created_at, expanded_key,
9726-
offer_nonce, secp_ctx
9727-
).map(|inv| inv.allow_mpp().relative_expiry(relative_expiry_secs))
9728-
}
9729-
97309683
/// Pays for an [`Offer`] using the given parameters by creating an [`InvoiceRequest`] and
97319684
/// enqueuing it to be sent via an onion message. [`ChannelManager`] will pay the actual
97329685
/// [`Bolt12Invoice`] once it is received.

lightning/src/ln/inbound_payment.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ pub fn create_from_hash(keys: &ExpandedKey, min_value_msat: Option<u64>, payment
194194
}
195195

196196
#[cfg(async_payments)]
197-
pub(super) fn create_for_spontaneous_payment(
197+
pub(crate) fn create_for_spontaneous_payment(
198198
keys: &ExpandedKey, min_value_msat: Option<u64>, invoice_expiry_delta_secs: u32,
199199
current_time: u64, min_final_cltv_expiry_delta: Option<u16>
200200
) -> Result<PaymentSecret, ()> {

lightning/src/offers/flow.rs

Lines changed: 96 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,16 @@ use crate::sign::EntropySource;
4444
use crate::util::logger::{Logger, WithContext};
4545

4646
#[cfg(async_payments)]
47-
use crate::offers::static_invoice::StaticInvoice;
47+
use {
48+
crate::blinded_path::message::AsyncPaymentsContext,
49+
crate::blinded_path::payment::AsyncBolt12OfferContext,
50+
crate::offers::offer::{Amount, Offer},
51+
crate::offers::signer,
52+
crate::offers::static_invoice::{
53+
StaticInvoice, StaticInvoiceBuilder,
54+
DEFAULT_RELATIVE_EXPIRY as STATIC_INVOICE_DEFAULT_RELATIVE_EXPIRY,
55+
},
56+
};
4857

4958
#[cfg(not(c_bindings))]
5059
use crate::offers::offer::DerivedMetadata;
@@ -181,6 +190,10 @@ pub trait OffersMessageCommons {
181190
max_total_routing_fee_msat: Option<u64>,
182191
retryable_invoice_request: Option<RetryableInvoiceRequest>,
183192
) -> Result<(), ()>;
193+
194+
#[cfg(not(feature = "std"))]
195+
/// Get the approximate current time using the highest seen timestamp
196+
fn get_highest_seen_timestamp(&self) -> Duration;
184197
}
185198

186199
/// A trivial trait which describes any [`OffersMessageFlow`].
@@ -476,6 +489,24 @@ where
476489
}
477490
}
478491

492+
impl<ES: Deref, OMC: Deref, L: Deref> OffersMessageFlow<ES, OMC, L>
493+
where
494+
ES::Target: EntropySource,
495+
OMC::Target: OffersMessageCommons,
496+
L::Target: Logger,
497+
{
498+
pub(crate) fn duration_since_epoch(&self) -> Duration {
499+
#[cfg(not(feature = "std"))]
500+
let now = self.commons.get_highest_seen_timestamp();
501+
#[cfg(feature = "std")]
502+
let now = std::time::SystemTime::now()
503+
.duration_since(std::time::SystemTime::UNIX_EPOCH)
504+
.expect("SystemTime::now() should come after SystemTime::UNIX_EPOCH");
505+
506+
now
507+
}
508+
}
509+
479510
impl<ES: Deref, OMC: Deref, L: Deref> OffersMessageHandler for OffersMessageFlow<ES, OMC, L>
480511
where
481512
ES::Target: EntropySource,
@@ -955,4 +986,68 @@ where
955986

956987
Ok((builder.into(), nonce))
957988
}
989+
990+
/// Creates a [`StaticInvoiceBuilder`] from the corresponding [`Offer`] and [`Nonce`] that were
991+
/// created via [`create_async_receive_offer_builder`]. If `relative_expiry` is unset, the
992+
/// invoice's expiry will default to [`STATIC_INVOICE_DEFAULT_RELATIVE_EXPIRY`].
993+
///
994+
/// [`create_async_receive_offer_builder`]: crate::offers::flow::create_async_receive_offer_builder
995+
#[cfg(async_payments)]
996+
pub fn create_static_invoice_builder<'a>(
997+
&self, offer: &'a Offer, offer_nonce: Nonce, relative_expiry: Option<Duration>,
998+
) -> Result<StaticInvoiceBuilder<'a>, Bolt12SemanticError> {
999+
let expanded_key = &self.inbound_payment_key;
1000+
let entropy = &*self.entropy_source;
1001+
let secp_ctx = &self.secp_ctx;
1002+
1003+
let payment_context =
1004+
PaymentContext::AsyncBolt12Offer(AsyncBolt12OfferContext { offer_nonce });
1005+
let amount_msat = offer.amount().and_then(|amount| match amount {
1006+
Amount::Bitcoin { amount_msats } => Some(amount_msats),
1007+
Amount::Currency { .. } => None,
1008+
});
1009+
1010+
let relative_expiry = relative_expiry.unwrap_or(STATIC_INVOICE_DEFAULT_RELATIVE_EXPIRY);
1011+
let relative_expiry_secs: u32 = relative_expiry.as_secs().try_into().unwrap_or(u32::MAX);
1012+
1013+
let created_at = self.duration_since_epoch();
1014+
let payment_secret = inbound_payment::create_for_spontaneous_payment(
1015+
&self.inbound_payment_key,
1016+
amount_msat,
1017+
relative_expiry_secs,
1018+
created_at.as_secs(),
1019+
None,
1020+
)
1021+
.map_err(|()| Bolt12SemanticError::InvalidAmount)?;
1022+
1023+
let payment_paths = self
1024+
.commons
1025+
.create_blinded_payment_paths(
1026+
amount_msat,
1027+
payment_secret,
1028+
payment_context,
1029+
relative_expiry_secs,
1030+
)
1031+
.map_err(|()| Bolt12SemanticError::MissingPaths)?;
1032+
1033+
let nonce = Nonce::from_entropy_source(entropy);
1034+
let hmac = signer::hmac_for_held_htlc_available_context(nonce, expanded_key);
1035+
let context =
1036+
MessageContext::AsyncPayments(AsyncPaymentsContext::InboundPayment { nonce, hmac });
1037+
let async_receive_message_paths = self
1038+
.commons
1039+
.create_blinded_paths(context)
1040+
.map_err(|()| Bolt12SemanticError::MissingPaths)?;
1041+
1042+
StaticInvoiceBuilder::for_offer_using_derived_keys(
1043+
offer,
1044+
payment_paths,
1045+
async_receive_message_paths,
1046+
created_at,
1047+
expanded_key,
1048+
offer_nonce,
1049+
secp_ctx,
1050+
)
1051+
.map(|inv| inv.allow_mpp().relative_expiry(relative_expiry_secs))
1052+
}
9581053
}

0 commit comments

Comments
 (0)