Skip to content

Commit f6079a8

Browse files
Test offline peer onion message interception.
1 parent e5ec13d commit f6079a8

File tree

1 file changed

+94
-6
lines changed

1 file changed

+94
-6
lines changed

lightning/src/onion_message/functional_tests.rs

Lines changed: 94 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,17 @@ struct MessengerNode {
5858
>>
5959
}
6060

61+
impl Drop for MessengerNode {
62+
fn drop(&mut self) {
63+
#[cfg(feature = "std")] {
64+
if std::thread::panicking() {
65+
return;
66+
}
67+
}
68+
assert!(release_events(self).is_empty());
69+
}
70+
}
71+
6172
struct TestOffersMessageHandler {}
6273

6374
impl OffersMessageHandler for TestOffersMessageHandler {
@@ -163,15 +174,20 @@ fn create_nodes(num_messengers: u8) -> Vec<MessengerNode> {
163174

164175
struct MessengerCfg {
165176
secret_override: Option<SecretKey>,
177+
intercept_offline_peer_oms: bool,
166178
}
167179
impl MessengerCfg {
168180
fn new() -> Self {
169-
Self { secret_override: None }
181+
Self { secret_override: None, intercept_offline_peer_oms: false }
170182
}
171183
fn with_node_secret(mut self, secret: SecretKey) -> Self {
172184
self.secret_override = Some(secret);
173185
self
174186
}
187+
fn with_offline_peer_interception(mut self) -> Self {
188+
self.intercept_offline_peer_oms = true;
189+
self
190+
}
175191
}
176192

177193
fn create_nodes_using_cfgs(cfgs: Vec<MessengerCfg>) -> Vec<MessengerNode> {
@@ -194,14 +210,22 @@ fn create_nodes_using_cfgs(cfgs: Vec<MessengerCfg>) -> Vec<MessengerNode> {
194210
);
195211
let offers_message_handler = Arc::new(TestOffersMessageHandler {});
196212
let custom_message_handler = Arc::new(TestCustomMessageHandler::new());
213+
let messenger = if cfg.intercept_offline_peer_oms {
214+
OnionMessenger::new_with_offline_peer_interception(
215+
entropy_source.clone(), node_signer.clone(), logger.clone(), message_router,
216+
offers_message_handler, custom_message_handler.clone()
217+
)
218+
} else {
219+
OnionMessenger::new(
220+
entropy_source.clone(), node_signer.clone(), logger.clone(), message_router,
221+
offers_message_handler, custom_message_handler.clone()
222+
)
223+
};
197224
nodes.push(MessengerNode {
198225
privkey: secret_key,
199226
node_id: node_signer.get_node_id(Recipient::Node).unwrap(),
200-
entropy_source: entropy_source.clone(),
201-
messenger: OnionMessenger::new(
202-
entropy_source, node_signer, logger.clone(), message_router,
203-
offers_message_handler, custom_message_handler.clone()
204-
),
227+
entropy_source,
228+
messenger,
205229
custom_message_handler,
206230
gossip_sync: gossip_sync.clone(),
207231
});
@@ -550,6 +574,70 @@ fn drops_buffered_messages_waiting_for_peer_connection() {
550574
assert!(nodes[0].messenger.next_onion_message_for_peer(nodes[1].node_id).is_none());
551575
}
552576

577+
#[test]
578+
fn intercept_offline_peer_oms() {
579+
// Ensure that if OnionMessenger is initialized with
580+
// new_with_offline_peer_interception, we will intercept OMs for offline
581+
// peers, generate the right events, and forward OMs when they are re-injected
582+
// by the user.
583+
let node_cfgs = vec![MessengerCfg::new(), MessengerCfg::new().with_offline_peer_interception(), MessengerCfg::new()];
584+
let mut nodes = create_nodes_using_cfgs(node_cfgs);
585+
586+
let peer_conn_evs = release_events(&nodes[1]);
587+
assert_eq!(peer_conn_evs.len(), 2);
588+
for (i, ev) in peer_conn_evs.iter().enumerate() {
589+
match ev {
590+
Event::OnionMessagePeerConnected { peer_node_id } => {
591+
let node_idx = if i == 0 { 0 } else { 2 };
592+
assert_eq!(peer_node_id, &nodes[node_idx].node_id);
593+
},
594+
_ => panic!()
595+
}
596+
}
597+
598+
let message = TestCustomMessage::Response;
599+
let secp_ctx = Secp256k1::new();
600+
let blinded_path = BlindedPath::new_for_message(
601+
&[nodes[1].node_id, nodes[2].node_id], &*nodes[2].entropy_source, &secp_ctx
602+
).unwrap();
603+
let destination = Destination::BlindedPath(blinded_path);
604+
605+
// Disconnect the peers to ensure we intercept the OM.
606+
disconnect_peers(&nodes[1], &nodes[2]);
607+
nodes[0].messenger.send_onion_message(message, destination, None).unwrap();
608+
let mut final_node_vec = nodes.split_off(2);
609+
pass_along_path(&nodes);
610+
611+
let mut events = release_events(&nodes[1]);
612+
assert_eq!(events.len(), 1);
613+
let onion_message = match events.remove(0) {
614+
Event::OnionMessageForOfflinePeer { peer_node_id, message } => {
615+
assert_eq!(peer_node_id, final_node_vec[0].node_id);
616+
message
617+
},
618+
_ => panic!()
619+
};
620+
621+
// Ensure that we'll refuse to forward the re-injected OM until after the
622+
// outbound peer comes back online.
623+
let err = nodes[1].messenger.forward_onion_message(onion_message.clone(), &final_node_vec[0].node_id).unwrap_err();
624+
assert_eq!(err, SendError::InvalidFirstHop(final_node_vec[0].node_id));
625+
626+
connect_peers(&nodes[1], &final_node_vec[0]);
627+
let peer_conn_ev = release_events(&nodes[1]);
628+
assert_eq!(peer_conn_ev.len(), 1);
629+
match peer_conn_ev[0] {
630+
Event::OnionMessagePeerConnected { peer_node_id } => {
631+
assert_eq!(peer_node_id, final_node_vec[0].node_id);
632+
},
633+
_ => panic!()
634+
}
635+
636+
nodes[1].messenger.forward_onion_message(onion_message, &final_node_vec[0].node_id).unwrap();
637+
final_node_vec[0].custom_message_handler.expect_message(TestCustomMessage::Response);
638+
pass_along_path(&vec![nodes.remove(1), final_node_vec.remove(0)]);
639+
}
640+
553641
#[test]
554642
fn spec_test_vector() {
555643
let node_cfgs = [

0 commit comments

Comments
 (0)