Skip to content

Commit e20e52c

Browse files
Mark offer as ready on StaticInvoicePersisted onion message
As an async recipient, we need to interactively build a static invoice that an always-online node will serve on our behalf. Once this invoice is built and persisted by the static invoice server, they will send us a confirmation onion message. At this time, mark the corresponding pending offer as ready to receive async payments.
1 parent 1cb0087 commit e20e52c

File tree

3 files changed

+54
-1
lines changed

3 files changed

+54
-1
lines changed

lightning/src/ln/channelmanager.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13080,6 +13080,13 @@ where
1308013080
fn handle_static_invoice_persisted(
1308113081
&self, _message: StaticInvoicePersisted, _context: AsyncPaymentsContext,
1308213082
) {
13083+
#[cfg(async_payments)]
13084+
{
13085+
let should_persist = self.flow.handle_static_invoice_persisted(_context);
13086+
if should_persist {
13087+
let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(self);
13088+
}
13089+
}
1308313090
}
1308413091

1308513092
fn handle_held_htlc_available(

lightning/src/offers/async_receive_offer_cache.rs

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ use crate::util::ser::{Readable, Writeable, Writer};
2323
use core::time::Duration;
2424

2525
/// The status of this offer in the cache.
26-
#[derive(Clone)]
26+
#[derive(Clone, PartialEq)]
2727
enum OfferStatus {
2828
/// This offer has been returned to the user from the cache, so it needs to be stored until it
2929
/// expires and its invoice needs to be kept updated.
@@ -363,6 +363,30 @@ impl AsyncReceiveOfferCache {
363363
fn reset_offer_paths_request_attempts(&mut self) {
364364
self.offer_paths_request_attempts = 0;
365365
}
366+
367+
/// Should be called when we receive a [`StaticInvoicePersisted`] message from the static invoice
368+
/// server, which indicates that a new offer was persisted by the server and they are ready to
369+
/// serve the corresponding static invoice to payers on our behalf.
370+
///
371+
/// Returns a bool indicating whether an offer was added/updated and re-persistence of the cache
372+
/// is needed.
373+
pub(super) fn static_invoice_persisted(
374+
&mut self, offer_slot: u8, duration_since_epoch: Duration,
375+
) -> bool {
376+
if let Some(Some(ref mut offer)) = self.offers.get_mut(offer_slot as usize) {
377+
if offer.status == OfferStatus::Used {
378+
// We succeeded in updating the invoice for a used offer, no re-persistence of the cache
379+
// needed
380+
return false;
381+
}
382+
383+
offer.status =
384+
OfferStatus::Ready { invoice_confirmed_persisted_at: duration_since_epoch };
385+
return true;
386+
}
387+
388+
false
389+
}
366390
}
367391

368392
impl Writeable for AsyncReceiveOfferCache {

lightning/src/offers/flow.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1344,6 +1344,28 @@ where
13441344
Ok((invoice, forward_invoice_request_path))
13451345
}
13461346

1347+
/// Handles an incoming [`StaticInvoicePersisted`] onion message from the static invoice server.
1348+
/// Returns a bool indicating whether the async receive offer cache needs to be re-persisted.
1349+
///
1350+
/// [`StaticInvoicePersisted`]: crate::onion_message::async_payments::StaticInvoicePersisted
1351+
#[cfg(async_payments)]
1352+
pub(crate) fn handle_static_invoice_persisted(&self, context: AsyncPaymentsContext) -> bool {
1353+
let duration_since_epoch = self.duration_since_epoch();
1354+
1355+
let confirmed_offer_slot = match context {
1356+
AsyncPaymentsContext::StaticInvoicePersisted { path_absolute_expiry, offer_slot } => {
1357+
if duration_since_epoch > path_absolute_expiry {
1358+
return false;
1359+
}
1360+
offer_slot
1361+
},
1362+
_ => return false,
1363+
};
1364+
1365+
let mut cache = self.async_receive_offer_cache.lock().unwrap();
1366+
cache.static_invoice_persisted(confirmed_offer_slot, duration_since_epoch)
1367+
}
1368+
13471369
/// Get the `AsyncReceiveOfferCache` for persistence.
13481370
pub(crate) fn writeable_async_receive_offer_cache(&self) -> impl Writeable + '_ {
13491371
&self.async_receive_offer_cache

0 commit comments

Comments
 (0)