Skip to content

Commit d20de39

Browse files
committed
Add InvoiceRequestTlvStream::paths
Instead of reusing OfferTlvStream::paths, add a dedicated paths TLV to InvoiceRequestTlvStream such that it can be used in Refund. This allows for an Offer without a signing_pubkey and still be able to differentiate whether an invoice is for an offer or a refund.
1 parent 178f947 commit d20de39

File tree

4 files changed

+36
-14
lines changed

4 files changed

+36
-14
lines changed

lightning/src/offers/invoice.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1645,6 +1645,7 @@ mod tests {
16451645
quantity: None,
16461646
payer_id: Some(&payer_pubkey()),
16471647
payer_note: None,
1648+
paths: None,
16481649
},
16491650
InvoiceTlvStreamRef {
16501651
paths: Some(Iterable(payment_paths.iter().map(|(_, path)| path))),
@@ -1737,6 +1738,7 @@ mod tests {
17371738
quantity: None,
17381739
payer_id: Some(&payer_pubkey()),
17391740
payer_note: None,
1741+
paths: None,
17401742
},
17411743
InvoiceTlvStreamRef {
17421744
paths: Some(Iterable(payment_paths.iter().map(|(_, path)| path))),

lightning/src/offers/invoice_request.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -961,6 +961,7 @@ impl InvoiceRequestContentsWithoutPayerId {
961961
quantity: self.quantity,
962962
payer_id: None,
963963
payer_note: self.payer_note.as_ref(),
964+
paths: None,
964965
};
965966

966967
(payer, offer, invoice_request)
@@ -1000,6 +1001,7 @@ tlv_stream!(InvoiceRequestTlvStream, InvoiceRequestTlvStreamRef, INVOICE_REQUEST
10001001
(86, quantity: (u64, HighZeroBytesDroppedBigSize)),
10011002
(INVOICE_REQUEST_PAYER_ID_TYPE, payer_id: PublicKey),
10021003
(89, payer_note: (String, WithoutLength)),
1004+
(90, paths: (Vec<BlindedPath>, WithoutLength)),
10031005
});
10041006

10051007
type FullInvoiceRequestTlvStream =
@@ -1082,7 +1084,9 @@ impl TryFrom<PartialInvoiceRequestTlvStream> for InvoiceRequestContents {
10821084
let (
10831085
PayerTlvStream { metadata },
10841086
offer_tlv_stream,
1085-
InvoiceRequestTlvStream { chain, amount, features, quantity, payer_id, payer_note },
1087+
InvoiceRequestTlvStream {
1088+
chain, amount, features, quantity, payer_id, payer_note, paths,
1089+
},
10861090
) = tlv_stream;
10871091

10881092
let payer = match metadata {
@@ -1109,6 +1113,10 @@ impl TryFrom<PartialInvoiceRequestTlvStream> for InvoiceRequestContents {
11091113
Some(payer_id) => payer_id,
11101114
};
11111115

1116+
if paths.is_some() {
1117+
return Err(Bolt12SemanticError::UnexpectedPaths);
1118+
}
1119+
11121120
Ok(InvoiceRequestContents {
11131121
inner: InvoiceRequestContentsWithoutPayerId {
11141122
payer, offer, chain, amount_msats: amount, features, quantity, payer_note,
@@ -1300,6 +1308,7 @@ mod tests {
13001308
quantity: None,
13011309
payer_id: Some(&payer_pubkey()),
13021310
payer_note: None,
1311+
paths: None,
13031312
},
13041313
SignatureTlvStreamRef { signature: Some(&invoice_request.signature()) },
13051314
),

lightning/src/offers/parse.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,8 @@ pub enum Bolt12SemanticError {
183183
DuplicatePaymentId,
184184
/// Blinded paths were expected but were missing.
185185
MissingPaths,
186+
/// Blinded paths were provided but were not expected.
187+
UnexpectedPaths,
186188
/// The blinded payinfo given does not match the number of blinded path hops.
187189
InvalidPayInfo,
188190
/// An invoice creation time was expected but was missing.

lightning/src/offers/refund.rs

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -170,8 +170,8 @@ macro_rules! refund_explicit_metadata_builder_methods { () => {
170170
Ok(Self {
171171
refund: RefundContents {
172172
payer: PayerContents(metadata), description, absolute_expiry: None, issuer: None,
173-
paths: None, chain: None, amount_msats, features: InvoiceRequestFeatures::empty(),
174-
quantity: None, payer_id, payer_note: None,
173+
chain: None, amount_msats, features: InvoiceRequestFeatures::empty(),
174+
quantity: None, payer_id, payer_note: None, paths: None,
175175
},
176176
secp_ctx: None,
177177
})
@@ -209,8 +209,8 @@ macro_rules! refund_builder_methods { (
209209
Ok(Self {
210210
refund: RefundContents {
211211
payer: PayerContents(metadata), description, absolute_expiry: None, issuer: None,
212-
paths: None, chain: None, amount_msats, features: InvoiceRequestFeatures::empty(),
213-
quantity: None, payer_id: node_id, payer_note: None,
212+
chain: None, amount_msats, features: InvoiceRequestFeatures::empty(),
213+
quantity: None, payer_id: node_id, payer_note: None, paths: None,
214214
},
215215
secp_ctx: Some(secp_ctx),
216216
})
@@ -410,14 +410,14 @@ pub(super) struct RefundContents {
410410
description: String,
411411
absolute_expiry: Option<Duration>,
412412
issuer: Option<String>,
413-
paths: Option<Vec<BlindedPath>>,
414413
// invoice_request fields
415414
chain: Option<ChainHash>,
416415
amount_msats: u64,
417416
features: InvoiceRequestFeatures,
418417
quantity: Option<u64>,
419418
payer_id: PublicKey,
420419
payer_note: Option<String>,
420+
paths: Option<Vec<BlindedPath>>,
421421
}
422422

423423
impl Refund {
@@ -734,7 +734,7 @@ impl RefundContents {
734734
description: Some(&self.description),
735735
features: None,
736736
absolute_expiry: self.absolute_expiry.map(|duration| duration.as_secs()),
737-
paths: self.paths.as_ref(),
737+
paths: None,
738738
issuer: self.issuer.as_ref(),
739739
quantity_max: None,
740740
node_id: None,
@@ -752,6 +752,7 @@ impl RefundContents {
752752
quantity: self.quantity,
753753
payer_id: Some(&self.payer_id),
754754
payer_note: self.payer_note.as_ref(),
755+
paths: self.paths.as_ref(),
755756
};
756757

757758
(payer, offer, invoice_request)
@@ -820,9 +821,12 @@ impl TryFrom<RefundTlvStream> for RefundContents {
820821
PayerTlvStream { metadata: payer_metadata },
821822
OfferTlvStream {
822823
chains, metadata, currency, amount: offer_amount, description,
823-
features: offer_features, absolute_expiry, paths, issuer, quantity_max, node_id,
824+
features: offer_features, absolute_expiry, paths: offer_paths, issuer, quantity_max,
825+
node_id,
826+
},
827+
InvoiceRequestTlvStream {
828+
chain, amount, features, quantity, payer_id, payer_note, paths
824829
},
825-
InvoiceRequestTlvStream { chain, amount, features, quantity, payer_id, payer_note },
826830
) = tlv_stream;
827831

828832
let payer = match payer_metadata {
@@ -853,6 +857,10 @@ impl TryFrom<RefundTlvStream> for RefundContents {
853857

854858
let absolute_expiry = absolute_expiry.map(Duration::from_secs);
855859

860+
if offer_paths.is_some() {
861+
return Err(Bolt12SemanticError::UnexpectedPaths);
862+
}
863+
856864
if quantity_max.is_some() {
857865
return Err(Bolt12SemanticError::UnexpectedQuantity);
858866
}
@@ -877,8 +885,8 @@ impl TryFrom<RefundTlvStream> for RefundContents {
877885
};
878886

879887
Ok(RefundContents {
880-
payer, description, absolute_expiry, issuer, paths, chain, amount_msats, features,
881-
quantity, payer_id, payer_note,
888+
payer, description, absolute_expiry, issuer, chain, amount_msats, features, quantity,
889+
payer_id, payer_note, paths,
882890
})
883891
}
884892
}
@@ -980,6 +988,7 @@ mod tests {
980988
quantity: None,
981989
payer_id: Some(&payer_pubkey()),
982990
payer_note: None,
991+
paths: None,
983992
},
984993
),
985994
);
@@ -1173,12 +1182,12 @@ mod tests {
11731182
.path(paths[1].clone())
11741183
.build()
11751184
.unwrap();
1176-
let (_, offer_tlv_stream, invoice_request_tlv_stream) = refund.as_tlv_stream();
1177-
assert_eq!(refund.paths(), paths.as_slice());
1185+
let (_, _, invoice_request_tlv_stream) = refund.as_tlv_stream();
11781186
assert_eq!(refund.payer_id(), pubkey(42));
1187+
assert_eq!(refund.paths(), paths.as_slice());
11791188
assert_ne!(pubkey(42), pubkey(44));
1180-
assert_eq!(offer_tlv_stream.paths, Some(&paths));
11811189
assert_eq!(invoice_request_tlv_stream.payer_id, Some(&pubkey(42)));
1190+
assert_eq!(invoice_request_tlv_stream.paths, Some(&paths));
11821191
}
11831192

11841193
#[test]

0 commit comments

Comments
 (0)