Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 38 additions & 1 deletion lightning/src/offers/static_invoice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -408,7 +408,7 @@ impl StaticInvoice {
/// Whether the [`Offer`] that this invoice is based on is expired.
#[cfg(feature = "std")]
pub fn is_offer_expired(&self) -> bool {
self.contents.is_expired()
self.contents.is_offer_expired()
}

/// Whether the [`Offer`] that this invoice is based on is expired, given the current time as
Expand Down Expand Up @@ -1003,6 +1003,43 @@ mod tests {
}
}

#[cfg(feature = "std")]
#[test]
fn is_offer_expired_does_not_check_invoice_expiry() {
// Regression test: `StaticInvoice::is_offer_expired` must reflect the offer's expiry,
// not the invoice's own expiry. Build an invoice whose offer has no absolute expiry
// (so the offer never expires) but whose own `created_at + relative_expiry` lies in
// the past (so the invoice itself is expired).
let node_id = recipient_pubkey();
let payment_paths = payment_paths();
let expanded_key = ExpandedKey::new([42; 32]);
let entropy = FixedEntropy {};
let nonce = Nonce::from_entropy_source(&entropy);
let secp_ctx = Secp256k1::new();

let offer = OfferBuilder::deriving_signing_pubkey(node_id, &expanded_key, nonce, &secp_ctx)
.path(blinded_path())
.build()
.unwrap();

let invoice = StaticInvoiceBuilder::for_offer_using_derived_keys(
&offer,
payment_paths.clone(),
vec![blinded_path()],
Duration::from_secs(0),
&expanded_key,
nonce,
&secp_ctx,
)
.unwrap()
.relative_expiry(1)
.build_and_sign(&secp_ctx)
.unwrap();

assert!(invoice.is_expired());
assert!(!invoice.is_offer_expired());
}

#[test]
fn builds_invoice_from_offer_using_derived_key() {
let node_id = recipient_pubkey();
Expand Down
Loading