Skip to content

Commit 20db51f

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 95a4644 commit 20db51f

File tree

3 files changed

+57
-1
lines changed

3 files changed

+57
-1
lines changed

lightning/src/ln/channelmanager.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13465,6 +13465,13 @@ where
1346513465
fn handle_static_invoice_persisted(
1346613466
&self, _message: StaticInvoicePersisted, _context: AsyncPaymentsContext,
1346713467
) {
13468+
#[cfg(async_payments)]
13469+
{
13470+
let should_persist = self.flow.handle_static_invoice_persisted(_context);
13471+
if should_persist {
13472+
let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(self);
13473+
}
13474+
}
1346813475
}
1346913476

1347013477
fn handle_held_htlc_available(

lightning/src/offers/async_receive_offer_cache.rs

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,11 @@ use crate::prelude::*;
2222
use crate::util::ser::{Readable, Writeable, Writer};
2323
use core::time::Duration;
2424

25+
#[cfg(async_payments)]
26+
use crate::blinded_path::message::AsyncPaymentsContext;
27+
2528
/// The status of this offer in the cache.
26-
#[derive(Clone)]
29+
#[derive(Clone, PartialEq)]
2730
enum OfferStatus {
2831
/// This offer has been returned to the user from the cache, so it needs to be stored until it
2932
/// expires and its invoice needs to be kept updated.
@@ -361,6 +364,42 @@ impl AsyncReceiveOfferCache {
361364
fn reset_offer_paths_request_attempts(&mut self) {
362365
self.offer_paths_request_attempts = 0;
363366
}
367+
368+
/// Should be called when we receive a [`StaticInvoicePersisted`] message from the static invoice
369+
/// server, which indicates that a new offer was persisted by the server and they are ready to
370+
/// serve the corresponding static invoice to payers on our behalf.
371+
///
372+
/// Returns a bool indicating whether an offer was added/updated and re-persistence of the cache
373+
/// is needed.
374+
pub(super) fn static_invoice_persisted(
375+
&mut self, context: AsyncPaymentsContext, duration_since_epoch: Duration,
376+
) -> bool {
377+
let offer_id = match context {
378+
AsyncPaymentsContext::StaticInvoicePersisted { path_absolute_expiry, offer_id } => {
379+
if duration_since_epoch > path_absolute_expiry {
380+
return false;
381+
}
382+
offer_id
383+
},
384+
_ => return false,
385+
};
386+
387+
let mut offers = self.offers.iter_mut();
388+
let offer_entry = offers.find(|o| o.as_ref().map_or(false, |o| o.offer.id() == offer_id));
389+
if let Some(Some(ref mut offer)) = offer_entry {
390+
if offer.status == OfferStatus::Used {
391+
// We succeeded in updating the invoice for a used offer, no re-persistence of the cache
392+
// needed
393+
return false;
394+
}
395+
396+
offer.status =
397+
OfferStatus::Ready { invoice_confirmed_persisted_at: duration_since_epoch };
398+
return true;
399+
}
400+
401+
false
402+
}
364403
}
365404

366405
impl Writeable for AsyncReceiveOfferCache {

lightning/src/offers/flow.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1342,6 +1342,16 @@ where
13421342
Ok((invoice, forward_invoice_request_path))
13431343
}
13441344

1345+
/// Handles an incoming [`StaticInvoicePersisted`] onion message from the static invoice server.
1346+
/// Returns a bool indicating whether the async receive offer cache needs to be re-persisted.
1347+
///
1348+
/// [`StaticInvoicePersisted`]: crate::onion_message::async_payments::StaticInvoicePersisted
1349+
#[cfg(async_payments)]
1350+
pub(crate) fn handle_static_invoice_persisted(&self, context: AsyncPaymentsContext) -> bool {
1351+
let mut cache = self.async_receive_offer_cache.lock().unwrap();
1352+
cache.static_invoice_persisted(context, self.duration_since_epoch())
1353+
}
1354+
13451355
/// Get the `AsyncReceiveOfferCache` for persistence.
13461356
pub(crate) fn writeable_async_receive_offer_cache(&self) -> impl Writeable + '_ {
13471357
&self.async_receive_offer_cache

0 commit comments

Comments
 (0)