Skip to content

Commit 3cfb24d

Browse files
InvoiceTlvStream{Ref}: add message_paths field
Will be used in static invoices. Also test that we'll fail to decode if these paths are included in single-use BOLT 12 invoices.
1 parent 922fd60 commit 3cfb24d

File tree

1 file changed

+39
-1
lines changed

1 file changed

+39
-1
lines changed

lightning/src/offers/invoice.rs

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1102,6 +1102,7 @@ impl InvoiceFields {
11021102
fallbacks: self.fallbacks.as_ref(),
11031103
features,
11041104
node_id: Some(&self.signing_pubkey),
1105+
message_paths: None,
11051106
}
11061107
}
11071108
}
@@ -1162,6 +1163,8 @@ tlv_stream!(InvoiceTlvStream, InvoiceTlvStreamRef, 160..240, {
11621163
(172, fallbacks: (Vec<FallbackAddress>, WithoutLength)),
11631164
(174, features: (Bolt12InvoiceFeatures, WithoutLength)),
11641165
(176, node_id: PublicKey),
1166+
// Only present in `StaticInvoice`s.
1167+
(238, message_paths: (Vec<BlindedPath>, WithoutLength)),
11651168
});
11661169

11671170
pub(super) type BlindedPathIter<'a> = core::iter::Map<
@@ -1299,10 +1302,12 @@ impl TryFrom<PartialInvoiceTlvStream> for InvoiceContents {
12991302
invoice_request_tlv_stream,
13001303
InvoiceTlvStream {
13011304
paths, blindedpay, created_at, relative_expiry, payment_hash, amount, fallbacks,
1302-
features, node_id,
1305+
features, node_id, message_paths,
13031306
},
13041307
) = tlv_stream;
13051308

1309+
if message_paths.is_some() { return Err(Bolt12SemanticError::UnexpectedPaths) }
1310+
13061311
let payment_paths = construct_payment_paths(blindedpay, paths)?;
13071312

13081313
let created_at = match created_at {
@@ -1568,6 +1573,7 @@ mod tests {
15681573
fallbacks: None,
15691574
features: None,
15701575
node_id: Some(&recipient_pubkey()),
1576+
message_paths: None,
15711577
},
15721578
SignatureTlvStreamRef { signature: Some(&invoice.signature()) },
15731579
),
@@ -1659,6 +1665,7 @@ mod tests {
16591665
fallbacks: None,
16601666
features: None,
16611667
node_id: Some(&recipient_pubkey()),
1668+
message_paths: None,
16621669
},
16631670
SignatureTlvStreamRef { signature: Some(&invoice.signature()) },
16641671
),
@@ -2429,4 +2436,35 @@ mod tests {
24292436
Err(e) => assert_eq!(e, Bolt12ParseError::Decode(DecodeError::InvalidValue)),
24302437
}
24312438
}
2439+
2440+
#[test]
2441+
fn fails_parsing_invoice_with_message_paths() {
2442+
let invoice = OfferBuilder::new(recipient_pubkey())
2443+
.amount_msats(1000)
2444+
.build().unwrap()
2445+
.request_invoice(vec![1; 32], payer_pubkey()).unwrap()
2446+
.build().unwrap()
2447+
.sign(payer_sign).unwrap()
2448+
.respond_with_no_std(payment_paths(), payment_hash(), now()).unwrap()
2449+
.build().unwrap()
2450+
.sign(recipient_sign).unwrap();
2451+
2452+
let blinded_path = BlindedPath {
2453+
introduction_node: IntroductionNode::NodeId(pubkey(40)),
2454+
blinding_point: pubkey(41),
2455+
blinded_hops: vec![
2456+
BlindedHop { blinded_node_id: pubkey(42), encrypted_payload: vec![0; 43] },
2457+
BlindedHop { blinded_node_id: pubkey(43), encrypted_payload: vec![0; 44] },
2458+
],
2459+
};
2460+
2461+
let mut tlv_stream = invoice.as_tlv_stream();
2462+
let message_paths = vec![blinded_path];
2463+
tlv_stream.3.message_paths = Some(&message_paths);
2464+
2465+
match Bolt12Invoice::try_from(tlv_stream.to_bytes()) {
2466+
Ok(_) => panic!("expected error"),
2467+
Err(e) => assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::UnexpectedPaths)),
2468+
}
2469+
}
24322470
}

0 commit comments

Comments
 (0)