Skip to content

Commit 2054075

Browse files
Test offline peer onion message interception.
1 parent ae758da commit 2054075

File tree

1 file changed

+96
-6
lines changed

1 file changed

+96
-6
lines changed

lightning/src/onion_message/functional_tests.rs

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

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

6475
impl OffersMessageHandler for TestOffersMessageHandler {
@@ -164,15 +175,20 @@ fn create_nodes(num_messengers: u8) -> Vec<MessengerNode> {
164175

165176
struct MessengerCfg {
166177
secret_override: Option<SecretKey>,
178+
intercept_offline_peer_oms: bool,
167179
}
168180
impl MessengerCfg {
169181
fn new() -> Self {
170-
Self { secret_override: None }
182+
Self { secret_override: None, intercept_offline_peer_oms: false }
171183
}
172184
fn with_node_secret(mut self, secret: SecretKey) -> Self {
173185
self.secret_override = Some(secret);
174186
self
175187
}
188+
fn with_offline_peer_interception(mut self) -> Self {
189+
self.intercept_offline_peer_oms = true;
190+
self
191+
}
176192
}
177193

178194
fn create_nodes_using_cfgs(cfgs: Vec<MessengerCfg>) -> Vec<MessengerNode> {
@@ -196,14 +212,24 @@ fn create_nodes_using_cfgs(cfgs: Vec<MessengerCfg>) -> Vec<MessengerNode> {
196212
);
197213
let offers_message_handler = Arc::new(TestOffersMessageHandler {});
198214
let custom_message_handler = Arc::new(TestCustomMessageHandler::new());
215+
let messenger = if cfg.intercept_offline_peer_oms {
216+
OnionMessenger::new_with_offline_peer_interception(
217+
entropy_source.clone(), node_signer.clone(), logger.clone(),
218+
node_id_lookup, message_router, offers_message_handler,
219+
custom_message_handler.clone()
220+
)
221+
} else {
222+
OnionMessenger::new(
223+
entropy_source.clone(), node_signer.clone(), logger.clone(),
224+
node_id_lookup, message_router, offers_message_handler,
225+
custom_message_handler.clone()
226+
)
227+
};
199228
nodes.push(MessengerNode {
200229
privkey: secret_key,
201230
node_id: node_signer.get_node_id(Recipient::Node).unwrap(),
202-
entropy_source: entropy_source.clone(),
203-
messenger: OnionMessenger::new(
204-
entropy_source, node_signer, logger.clone(), node_id_lookup, message_router,
205-
offers_message_handler, custom_message_handler.clone()
206-
),
231+
entropy_source,
232+
messenger,
207233
custom_message_handler,
208234
gossip_sync: gossip_sync.clone(),
209235
});
@@ -552,6 +578,70 @@ fn drops_buffered_messages_waiting_for_peer_connection() {
552578
assert!(nodes[0].messenger.next_onion_message_for_peer(nodes[1].node_id).is_none());
553579
}
554580

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

0 commit comments

Comments
 (0)