Skip to content

Commit 93644d2

Browse files
Include invoice_slot in OfferPathsRequest message
In the initially-merged version of the static invoice server protocol, the static invoice server would sometimes have to find a specific static invoice based on (recipient_id, invoice_slot) and sometimes based on (recipient_id, invoice_id). This made the API harder to use in terms of how the server would index into the KVStore. We'd like to transition to the server always finding a specific invoice based on (recipient_id, invoice_slot) and get rid of the invoice_id concept. Now that the invoice_slot is in the initial paths request, the server will be able to include the slot in the offer paths that they create in response, allowing the slot to be surfaced instead of the invoice_id when the invoice request comes in, in upcoming commits.
1 parent f0551f7 commit 93644d2

File tree

3 files changed

+26
-12
lines changed

3 files changed

+26
-12
lines changed

lightning/src/offers/async_receive_offer_cache.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -246,10 +246,11 @@ impl AsyncReceiveOfferCache {
246246
.ok_or(())
247247
}
248248

249-
/// Remove expired offers from the cache, returning whether new offers are needed.
249+
/// Remove expired offers from the cache, returning an index of the slot in the cache that needs a
250+
/// new offer, if any exist.
250251
pub(super) fn prune_expired_offers(
251252
&mut self, duration_since_epoch: Duration, force_reset_request_attempts: bool,
252-
) -> bool {
253+
) -> Option<usize> {
253254
// Remove expired offers from the cache.
254255
let mut offer_was_removed = false;
255256
for offer_opt in self.offers.iter_mut() {
@@ -268,8 +269,11 @@ impl AsyncReceiveOfferCache {
268269
self.reset_offer_paths_request_attempts()
269270
}
270271

271-
self.needs_new_offer_idx(duration_since_epoch).is_some()
272-
&& self.offer_paths_request_attempts < MAX_UPDATE_ATTEMPTS
272+
if self.offer_paths_request_attempts >= MAX_UPDATE_ATTEMPTS {
273+
return None;
274+
}
275+
276+
self.needs_new_offer_idx(duration_since_epoch)
273277
}
274278

275279
/// Returns whether the new paths we've just received from the static invoice server should be used

lightning/src/offers/flow.rs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1266,11 +1266,11 @@ where
12661266

12671267
// Update the cache to remove expired offers, and check to see whether we need new offers to be
12681268
// interactively built with the static invoice server.
1269-
let needs_new_offers =
1270-
cache.prune_expired_offers(duration_since_epoch, timer_tick_occurred);
1271-
if !needs_new_offers {
1272-
return Ok(());
1273-
}
1269+
let needs_new_offer_idx: u16 =
1270+
match cache.prune_expired_offers(duration_since_epoch, timer_tick_occurred) {
1271+
Some(idx) => idx.try_into().map_err(|_| ())?,
1272+
None => return Ok(()),
1273+
};
12741274

12751275
// If we need new offers, send out offer paths request messages to the static invoice server.
12761276
let context = MessageContext::AsyncPayments(AsyncPaymentsContext::OfferPaths {
@@ -1289,7 +1289,9 @@ where
12891289

12901290
let mut pending_async_payments_messages =
12911291
self.pending_async_payments_messages.lock().unwrap();
1292-
let message = AsyncPaymentsMessage::OfferPathsRequest(OfferPathsRequest {});
1292+
let message = AsyncPaymentsMessage::OfferPathsRequest(OfferPathsRequest {
1293+
invoice_slot: needs_new_offer_idx,
1294+
});
12931295
enqueue_onion_message_with_reply_paths(
12941296
message,
12951297
cache.paths_to_static_invoice_server(),

lightning/src/onion_message/async_payments.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,13 @@ pub enum AsyncPaymentsMessage {
131131
///
132132
/// [`Offer::paths`]: crate::offers::offer::Offer::paths
133133
#[derive(Clone, Debug)]
134-
pub struct OfferPathsRequest {}
134+
pub struct OfferPathsRequest {
135+
/// The "slot" in the static invoice server's database that this invoice should go into. This
136+
/// allows us as the recipient to replace a specific invoice that is stored by the server, which
137+
/// is useful for limiting the number of invoices stored by the server while also keeping all the
138+
/// invoices persisted with the server fresh.
139+
pub invoice_slot: u16,
140+
}
135141

136142
/// [`BlindedMessagePath`]s to be included in an async recipient's [`Offer::paths`], sent by a
137143
/// static invoice server in response to an [`OfferPathsRequest`].
@@ -233,7 +239,9 @@ impl OnionMessageContents for ReleaseHeldHtlc {
233239
}
234240
}
235241

236-
impl_writeable_tlv_based!(OfferPathsRequest, {});
242+
impl_writeable_tlv_based!(OfferPathsRequest, {
243+
(0, invoice_slot, required),
244+
});
237245

238246
impl_writeable_tlv_based!(OfferPaths, {
239247
(0, paths, required_vec),

0 commit comments

Comments
 (0)