Skip to content

Commit d2b1fb1

Browse files
committed
Allow parsing Offer without signing_pubkey
If an offer has at least one path, it may omit the signing pubkey and use the blinded node id of the last hop of a path to sign an invoice. Allow parsing such offers but not yet creating them.
1 parent d6bc0cf commit d2b1fb1

File tree

1 file changed

+31
-5
lines changed

1 file changed

+31
-5
lines changed

lightning/src/offers/offer.rs

+31-5
Original file line numberDiff line numberDiff line change
@@ -436,6 +436,12 @@ macro_rules! offer_builder_test_methods { (
436436
$return_value
437437
}
438438

439+
#[cfg_attr(c_bindings, allow(dead_code))]
440+
pub(crate) fn clear_signing_pubkey($($self_mut)* $self: $self_type) -> $return_type {
441+
$self.offer.signing_pubkey = None;
442+
$return_value
443+
}
444+
439445
#[cfg_attr(c_bindings, allow(dead_code))]
440446
pub(super) fn build_unchecked($self: $self_type) -> Offer {
441447
$self.build_without_checks()
@@ -1093,9 +1099,10 @@ impl TryFrom<OfferTlvStream> for OfferContents {
10931099
Some(n) => Quantity::Bounded(NonZeroU64::new(n).unwrap()),
10941100
};
10951101

1096-
let signing_pubkey = match node_id {
1097-
None => return Err(Bolt12SemanticError::MissingSigningPubkey),
1098-
Some(node_id) => Some(node_id),
1102+
let (signing_pubkey, paths) = match (node_id, paths) {
1103+
(None, None) => return Err(Bolt12SemanticError::MissingSigningPubkey),
1104+
(_, Some(paths)) if paths.is_empty() => return Err(Bolt12SemanticError::MissingPaths),
1105+
(node_id, paths) => (node_id, paths),
10991106
};
11001107

11011108
Ok(OfferContents {
@@ -1662,12 +1669,31 @@ mod tests {
16621669
panic!("error parsing offer: {:?}", e);
16631670
}
16641671

1672+
let offer = OfferBuilder::new("foo".into(), pubkey(42))
1673+
.path(BlindedPath {
1674+
introduction_node: IntroductionNode::NodeId(pubkey(40)),
1675+
blinding_point: pubkey(41),
1676+
blinded_hops: vec![
1677+
BlindedHop { blinded_node_id: pubkey(43), encrypted_payload: vec![0; 43] },
1678+
BlindedHop { blinded_node_id: pubkey(44), encrypted_payload: vec![0; 44] },
1679+
],
1680+
})
1681+
.clear_signing_pubkey()
1682+
.build()
1683+
.unwrap();
1684+
if let Err(e) = offer.to_string().parse::<Offer>() {
1685+
panic!("error parsing offer: {:?}", e);
1686+
}
1687+
16651688
let mut builder = OfferBuilder::new("foo".into(), pubkey(42));
16661689
builder.offer.paths = Some(vec![]);
16671690

16681691
let offer = builder.build().unwrap();
1669-
if let Err(e) = offer.to_string().parse::<Offer>() {
1670-
panic!("error parsing offer: {:?}", e);
1692+
match offer.to_string().parse::<Offer>() {
1693+
Ok(_) => panic!("expected error"),
1694+
Err(e) => {
1695+
assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::MissingPaths));
1696+
},
16711697
}
16721698
}
16731699

0 commit comments

Comments
 (0)