Skip to content

Commit 3e461a8

Browse files
f always have new offer ready
1 parent d5570e5 commit 3e461a8

File tree

1 file changed

+23
-25
lines changed

1 file changed

+23
-25
lines changed

lightning/src/offers/async_receive_offer_cache.rs

Lines changed: 23 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -142,24 +142,21 @@ impl AsyncReceiveOfferCache {
142142
// The target number of offers we want to have cached at any given time, to mitigate too much
143143
// reuse of the same offer.
144144
#[cfg(async_payments)]
145-
const NUM_CACHED_OFFERS_TARGET: usize = 3;
145+
const MAX_CACHED_OFFERS_TARGET: usize = 10;
146+
147+
///
148+
#[cfg(async_payments)]
149+
const UNUSED_OFFERS_TARGET: u8 = 3;
146150

147151
// The max number of times we'll attempt to request offer paths or attempt to refresh a static
148152
// invoice before giving up.
149153
#[cfg(async_payments)]
150154
const MAX_UPDATE_ATTEMPTS: u8 = 3;
151155

152-
// If we run out of attempts to request offer paths from the static invoice server, we'll stop
153-
// sending requests for some time. After this amount of time has passed, more requests are allowed
154-
// to be sent out.
155-
#[cfg(async_payments)]
156-
const PATHS_REQUESTS_RESET_INTERVAL: Duration = Duration::from_secs(3 * 60 * 60);
157-
158-
// If an offer is 90% of the way through its lifespan, it's expiring soon. This allows us to be
159-
// flexible for various offer lifespans, i.e. an offer that lasts 10 days expires soon after 9 days
160-
// and an offer that lasts 10 years expires soon after 9 years.
156+
// If an offer is more than 2 hours old, go ahead and refresh it because we always want to have the
157+
// freshest offer possible when a user goes to retrieve a cached offer.
161158
#[cfg(async_payments)]
162-
const OFFER_EXPIRES_SOON_THRESHOLD_PERCENT: u64 = 90;
159+
const OFFER_REFRESH_THRESHOLD: Duration = Duration::from_secs(2 * 60 * 60);
163160

164161
#[cfg(async_payments)]
165162
impl AsyncReceiveOfferCache {
@@ -190,25 +187,26 @@ impl AsyncReceiveOfferCache {
190187

191188
/// Returns a bool indicating whether new offers are needed in the cache.
192189
fn needs_new_offers(&self, duration_since_epoch: Duration) -> bool {
193-
// If we have fewer than NUM_CACHED_OFFERS_TARGET offers that aren't expiring soon, indicate
194-
// that new offers should be interactively built.
195-
let num_unexpiring_offers = self
190+
// We always want to have the freshest offer possible when a user goes to retrieve a cached
191+
// offer, so if we either don't have enough offers or we have a replaceable offer that is at
192+
// least a few hours old, then attempt to build a new one.
193+
let cached_offers_target =
194+
core::cmp::min(self.max_invoices_stored_by_server, MAX_CACHED_OFFERS_TARGET);
195+
if self.offers.len() < cached_offers_target {
196+
return true;
197+
}
198+
199+
let num_unused_offers_needing_replacement = self
196200
.offers
197201
.iter()
202+
.filter(|offer| !matches!(offer.status, OfferStatus::Used))
203+
.filter(|offer| !matches!(offer.status, OfferStatus::PendingInvoicePersist))
198204
.filter(|offer| {
199-
let offer_absolute_expiry = offer.offer.absolute_expiry().unwrap_or(Duration::MAX);
200-
let offer_created_at = offer.offer_created_at;
201-
let offer_lifespan =
202-
offer_absolute_expiry.saturating_sub(offer_created_at).as_secs();
203-
let elapsed = duration_since_epoch.saturating_sub(offer_created_at).as_secs();
204-
205-
// If an offer is in the last 10% of its lifespan, it's expiring soon.
206-
elapsed.saturating_mul(100)
207-
< offer_lifespan.saturating_mul(OFFER_EXPIRES_SOON_THRESHOLD_PERCENT)
205+
offer.offer_created_at
206+
< duration_since_epoch.saturating_sub(OFFER_REFRESH_THRESHOLD)
208207
})
209208
.count();
210-
211-
num_unexpiring_offers < NUM_CACHED_OFFERS_TARGET
209+
num_unused_offers_needing_replacement < UNUSED_OFFERS_TARGET
212210
}
213211

214212
// Indicates that onion messages requesting new offer paths have been sent to the static invoice

0 commit comments

Comments
 (0)