Skip to content

Commit 316a0ce

Browse files
jkczyzclaude
andcommitted
Report the sending peer in Event::OnionMessageIntercepted
When the OnionMessenger intercepts an onion message to forward, it now reports which peer sent us the message via a new `prev_hop` field, so handlers can apply source-based policy when deciding whether to forward. `prev_hop` is `None` when the forward is enqueued by a message handler (the BOLT 12 static-invoice-server flow), which isn't given the sending node; otherwise it is the node we received the message from. Co-Authored-By: Claude <noreply@anthropic.com>
1 parent d1d963f commit 316a0ce

4 files changed

Lines changed: 39 additions & 23 deletions

File tree

lightning-tests/src/upgrade_downgrade_tests.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -761,7 +761,9 @@ fn test_onion_message_intercepted_upgrade_from_0_2() {
761761
let deserialized = <Event as MaybeReadable>::read(&mut reader).unwrap().unwrap();
762762

763763
match deserialized {
764-
Event::OnionMessageIntercepted { next_hop, message } => {
764+
Event::OnionMessageIntercepted { prev_hop, next_hop, message } => {
765+
// LDK 0.2 did not write a `prev_hop`, so it must default to `None`.
766+
assert_eq!(prev_hop, None);
765767
assert_eq!(next_hop, NextMessageHop::NodeId(pubkey));
766768
assert_eq!(message, dummy_onion_message());
767769
},
@@ -773,11 +775,14 @@ fn test_onion_message_intercepted_upgrade_from_0_2() {
773775
fn test_onion_message_intercepted_node_id_downgrade_to_0_2() {
774776
// Ensure that an `Event::OnionMessageIntercepted` with a `NodeId` next hop serialized by
775777
// the current version can be deserialized by LDK 0.2 (which expects `peer_node_id` in TLV
776-
// field 0).
778+
// field 0 and ignores the newer `prev_hop` in TLV field 3).
777779
let pubkey =
778780
PublicKey::from_secret_key(&Secp256k1::new(), &SecretKey::from_slice(&[42; 32]).unwrap());
781+
let prev_hop =
782+
PublicKey::from_secret_key(&Secp256k1::new(), &SecretKey::from_slice(&[43; 32]).unwrap());
779783

780784
let event = Event::OnionMessageIntercepted {
785+
prev_hop: Some(prev_hop),
781786
next_hop: NextMessageHop::NodeId(pubkey),
782787
message: dummy_onion_message(),
783788
};
@@ -802,6 +807,7 @@ fn test_onion_message_intercepted_scid_downgrade_to_0_2() {
802807
// serialized by the current version cannot be deserialized by LDK 0.2, since the
803808
// `peer_node_id` field (0) is not written for SCID variants and LDK 0.2 requires it.
804809
let event = Event::OnionMessageIntercepted {
810+
prev_hop: None,
805811
next_hop: NextMessageHop::ShortChannelId(42),
806812
message: dummy_onion_message(),
807813
};

lightning/src/events/mod.rs

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1856,6 +1856,12 @@ pub enum Event {
18561856
///
18571857
/// [`OnionMessenger::new_with_offline_peer_interception`]: crate::onion_message::messenger::OnionMessenger::new_with_offline_peer_interception
18581858
OnionMessageIntercepted {
1859+
/// The node id of the peer that sent the message, if known.
1860+
///
1861+
/// This is `None` when the forward is enqueued by a message handler (e.g. the BOLT 12
1862+
/// static-invoice-server flow), which isn't given the sending node. Otherwise it is the
1863+
/// node we received the message from.
1864+
prev_hop: Option<PublicKey>,
18591865
/// The next hop (offline peer or unknown SCID).
18601866
next_hop: NextMessageHop,
18611867
/// The onion message intended to be forwarded to the offline peer or via the unknown
@@ -2441,25 +2447,20 @@ impl Writeable for Event {
24412447
35u8.write(writer)?;
24422448
// Never write ConnectionNeeded events as buffered onion messages aren't serialized.
24432449
},
2444-
&Event::OnionMessageIntercepted { ref next_hop, ref message } => {
2450+
&Event::OnionMessageIntercepted { ref prev_hop, ref next_hop, ref message } => {
24452451
37u8.write(writer)?;
2446-
match next_hop {
2447-
NextMessageHop::NodeId(peer_node_id) => {
2448-
// If we have the node_id, we keep writing it for backwards compatibility.
2449-
write_tlv_fields!(writer, {
2450-
(0, peer_node_id, required),
2451-
(1, next_hop, required),
2452-
(2, message, required),
2453-
});
2454-
},
2455-
NextMessageHop::ShortChannelId(_) => {
2456-
write_tlv_fields!(writer, {
2457-
// 0 used to be peer_node_id in LDK v0.2 and prior.
2458-
(1, next_hop, required),
2459-
(2, message, required),
2460-
});
2461-
},
2462-
}
2452+
// 0 used to be peer_node_id in LDK v0.2 and prior; we keep writing it when the next
2453+
// hop is a node id for backwards compatibility.
2454+
let legacy_peer_node_id = match next_hop {
2455+
NextMessageHop::NodeId(node_id) => Some(node_id),
2456+
NextMessageHop::ShortChannelId(_) => None,
2457+
};
2458+
write_tlv_fields!(writer, {
2459+
(0, legacy_peer_node_id, option),
2460+
(1, next_hop, required),
2461+
(2, message, required),
2462+
(3, prev_hop, option),
2463+
});
24632464
},
24642465
&Event::OnionMessagePeerConnected { ref peer_node_id } => {
24652466
39u8.write(writer)?;
@@ -3090,12 +3091,14 @@ impl MaybeReadable for Event {
30903091
(0, peer_node_id, option),
30913092
(1, next_hop, option),
30923093
(2, message, required),
3094+
(3, prev_hop, option),
30933095
});
30943096

30953097
let next_hop = next_hop
30963098
.or(peer_node_id.map(NextMessageHop::NodeId))
30973099
.ok_or(msgs::DecodeError::InvalidValue)?;
30983100
Ok(Some(Event::OnionMessageIntercepted {
3101+
prev_hop,
30993102
next_hop,
31003103
message: message.0.unwrap(),
31013104
}))

lightning/src/onion_message/functional_tests.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1154,7 +1154,8 @@ fn intercept_offline_peer_oms() {
11541154
let mut events = release_events(&nodes[1]);
11551155
assert_eq!(events.len(), 1);
11561156
let onion_message = match events.remove(0) {
1157-
Event::OnionMessageIntercepted { next_hop, message } => {
1157+
Event::OnionMessageIntercepted { prev_hop, next_hop, message } => {
1158+
assert_eq!(prev_hop, Some(nodes[0].node_id));
11581159
if let NextMessageHop::NodeId(peer_node_id) = next_hop {
11591160
assert_eq!(peer_node_id, final_node_vec[0].node_id);
11601161
message
@@ -1240,7 +1241,8 @@ fn intercept_unknown_scid_oms() {
12401241
let mut events = release_events(&nodes[1]);
12411242
assert_eq!(events.len(), 1);
12421243
let onion_message = match events.remove(0) {
1243-
Event::OnionMessageIntercepted { next_hop, message } => {
1244+
Event::OnionMessageIntercepted { prev_hop, next_hop, message } => {
1245+
assert_eq!(prev_hop, Some(nodes[0].node_id));
12441246
if let NextMessageHop::ShortChannelId(intercepted_scid) = next_hop {
12451247
assert_eq!(intercepted_scid, scid);
12461248
message

lightning/src/onion_message/messenger.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1556,6 +1556,7 @@ impl<
15561556

15571557
let result = if is_forward {
15581558
self.enqueue_forwarded_onion_message(
1559+
None,
15591560
NextMessageHop::NodeId(first_node_id),
15601561
onion_message,
15611562
log_suffix,
@@ -1671,7 +1672,8 @@ impl<
16711672
}
16721673

16731674
fn enqueue_forwarded_onion_message(
1674-
&self, next_hop: NextMessageHop, onion_message: OnionMessage, log_suffix: fmt::Arguments,
1675+
&self, prev_hop: Option<PublicKey>, next_hop: NextMessageHop, onion_message: OnionMessage,
1676+
log_suffix: fmt::Arguments,
16751677
) -> Result<(), SendError> {
16761678
let next_node_id = match next_hop {
16771679
NextMessageHop::NodeId(pubkey) => pubkey,
@@ -1686,6 +1688,7 @@ impl<
16861688
log_suffix
16871689
);
16881690
self.enqueue_intercepted_event(Event::OnionMessageIntercepted {
1691+
prev_hop,
16891692
next_hop,
16901693
message: onion_message,
16911694
});
@@ -1734,6 +1737,7 @@ impl<
17341737
log_suffix
17351738
);
17361739
self.enqueue_intercepted_event(Event::OnionMessageIntercepted {
1740+
prev_hop,
17371741
next_hop,
17381742
message: onion_message,
17391743
});
@@ -2315,6 +2319,7 @@ impl<
23152319
},
23162320
Ok(PeeledOnion::Forward(next_hop, onion_message)) => {
23172321
let _ = self.enqueue_forwarded_onion_message(
2322+
Some(peer_node_id),
23182323
next_hop,
23192324
onion_message,
23202325
format_args!("when forwarding peeled onion message from {}", peer_node_id),

0 commit comments

Comments
 (0)