Skip to content

Commit 95baf3f

Browse files
committed
Test pending connection onion message buffering
Add tests for onion message buffering checking that messages are cleared upon disconnection and timed out after MAX_TIMER_TICKS. Also, checks that ConnectionNeeded events are generated.
1 parent af6f8ba commit 95baf3f

File tree

2 files changed

+91
-8
lines changed

2 files changed

+91
-8
lines changed

lightning/src/onion_message/functional_tests.rs

Lines changed: 89 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,9 @@
1010
//! Onion message testing and test utilities live here.
1111
1212
use crate::blinded_path::BlindedPath;
13+
use crate::events::{Event, EventsProvider};
1314
use crate::ln::features::InitFeatures;
14-
use crate::ln::msgs::{self, DecodeError, OnionMessageHandler};
15+
use crate::ln::msgs::{self, DecodeError, OnionMessageHandler, SocketAddress};
1516
use crate::sign::{NodeSigner, Recipient};
1617
use crate::util::ser::{FixedLengthReader, LengthReadable, Writeable, Writer};
1718
use crate::util::test_utils;
@@ -49,7 +50,7 @@ impl MessageRouter for TestMessageRouter {
4950
Ok(OnionMessagePath {
5051
intermediate_nodes: vec![],
5152
destination,
52-
addresses: None,
53+
addresses: Some(vec![SocketAddress::TcpIpV4 { addr: [127, 0, 0, 1], port: 1000 }]),
5354
})
5455
}
5556
}
@@ -179,15 +180,30 @@ fn create_nodes_using_secrets(secrets: Vec<SecretKey>) -> Vec<MessengerNode> {
179180
});
180181
}
181182
for i in 0..nodes.len() - 1 {
182-
let mut features = InitFeatures::empty();
183-
features.set_onion_messages_optional();
184-
let init_msg = msgs::Init { features, networks: None, remote_network_address: None };
185-
nodes[i].messenger.peer_connected(&nodes[i + 1].node_id, &init_msg.clone(), true).unwrap();
186-
nodes[i + 1].messenger.peer_connected(&nodes[i].node_id, &init_msg.clone(), false).unwrap();
183+
connect_peers(&nodes[i], &nodes[i + 1]);
187184
}
188185
nodes
189186
}
190187

188+
fn connect_peers(node_a: &MessengerNode, node_b: &MessengerNode) {
189+
let mut features = InitFeatures::empty();
190+
features.set_onion_messages_optional();
191+
let init_msg = msgs::Init { features, networks: None, remote_network_address: None };
192+
node_a.messenger.peer_connected(&node_b.node_id, &init_msg.clone(), true).unwrap();
193+
node_b.messenger.peer_connected(&node_a.node_id, &init_msg.clone(), false).unwrap();
194+
}
195+
196+
fn disconnect_peers(node_a: &MessengerNode, node_b: &MessengerNode) {
197+
node_a.messenger.peer_disconnected(&node_b.node_id);
198+
node_b.messenger.peer_disconnected(&node_a.node_id);
199+
}
200+
201+
fn release_events(node: &MessengerNode) -> Vec<Event> {
202+
let events = core::cell::RefCell::new(Vec::new());
203+
node.messenger.process_pending_events(&|e| events.borrow_mut().push(e));
204+
events.into_inner()
205+
}
206+
191207
fn pass_along_path(path: &Vec<MessengerNode>) {
192208
let mut prev_node = &path[0];
193209
for node in path.into_iter().skip(1) {
@@ -458,6 +474,72 @@ fn many_hops() {
458474
pass_along_path(&nodes);
459475
}
460476

477+
#[test]
478+
fn requests_peer_connection_for_buffered_messages() {
479+
let nodes = create_nodes(3);
480+
let message = TestCustomMessage::Request;
481+
let secp_ctx = Secp256k1::new();
482+
let blinded_path = BlindedPath::new_for_message(
483+
&[nodes[1].node_id, nodes[2].node_id], &*nodes[0].entropy_source, &secp_ctx
484+
).unwrap();
485+
let destination = Destination::BlindedPath(blinded_path);
486+
487+
// Buffer an onion message for a connected peer
488+
nodes[0].messenger.send_onion_message(message.clone(), destination.clone(), None).unwrap();
489+
assert!(release_events(&nodes[0]).is_empty());
490+
assert!(nodes[0].messenger.next_onion_message_for_peer(nodes[1].node_id).is_some());
491+
assert!(nodes[0].messenger.next_onion_message_for_peer(nodes[1].node_id).is_none());
492+
493+
// Buffer an onion message for a disconnected peer
494+
disconnect_peers(&nodes[0], &nodes[1]);
495+
assert!(nodes[0].messenger.next_onion_message_for_peer(nodes[1].node_id).is_none());
496+
nodes[0].messenger.send_onion_message(message, destination, None).unwrap();
497+
498+
// Check that a ConnectionNeeded event for the peer is provided
499+
let events = release_events(&nodes[0]);
500+
assert_eq!(events.len(), 1);
501+
match &events[0] {
502+
Event::ConnectionNeeded { node_id, .. } => assert_eq!(*node_id, nodes[1].node_id),
503+
e => panic!("Unexpected event: {:?}", e),
504+
}
505+
506+
// Release the buffered onion message when reconnected
507+
connect_peers(&nodes[0], &nodes[1]);
508+
assert!(nodes[0].messenger.next_onion_message_for_peer(nodes[1].node_id).is_some());
509+
assert!(nodes[0].messenger.next_onion_message_for_peer(nodes[1].node_id).is_none());
510+
}
511+
512+
#[test]
513+
fn drops_buffered_messages_waiting_for_peer_connection() {
514+
let nodes = create_nodes(3);
515+
let message = TestCustomMessage::Request;
516+
let secp_ctx = Secp256k1::new();
517+
let blinded_path = BlindedPath::new_for_message(
518+
&[nodes[1].node_id, nodes[2].node_id], &*nodes[0].entropy_source, &secp_ctx
519+
).unwrap();
520+
let destination = Destination::BlindedPath(blinded_path);
521+
522+
// Buffer an onion message for a disconnected peer
523+
disconnect_peers(&nodes[0], &nodes[1]);
524+
nodes[0].messenger.send_onion_message(message, destination, None).unwrap();
525+
526+
// Release the event so the timer can start ticking
527+
let events = release_events(&nodes[0]);
528+
assert_eq!(events.len(), 1);
529+
match &events[0] {
530+
Event::ConnectionNeeded { node_id, .. } => assert_eq!(*node_id, nodes[1].node_id),
531+
e => panic!("Unexpected event: {:?}", e),
532+
}
533+
534+
// Drop buffered messages for a disconnected peer after some timer ticks
535+
use crate::onion_message::messenger::MAX_TIMER_TICKS;
536+
for _ in 0..=MAX_TIMER_TICKS {
537+
nodes[0].messenger.timer_tick_occurred();
538+
}
539+
connect_peers(&nodes[0], &nodes[1]);
540+
assert!(nodes[0].messenger.next_onion_message_for_peer(nodes[1].node_id).is_none());
541+
}
542+
461543
#[test]
462544
fn spec_test_vector() {
463545
let secret_keys = [

lightning/src/onion_message/messenger.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ use crate::io;
4040
use crate::sync::{Arc, Mutex};
4141
use crate::prelude::*;
4242

43+
pub(super) const MAX_TIMER_TICKS: usize = 2;
44+
4345
/// A sender, receiver and forwarder of [`OnionMessage`]s.
4446
///
4547
/// # Handling Messages
@@ -876,7 +878,6 @@ where
876878
}
877879

878880
fn timer_tick_occurred(&self) {
879-
const MAX_TIMER_TICKS: usize = 2;
880881
let mut message_buffers = self.message_buffers.lock().unwrap();
881882

882883
// Drop any pending recipients since the last call to avoid retaining buffered messages for

0 commit comments

Comments
 (0)