|  | 
| 10 | 10 | //! Onion message testing and test utilities live here. | 
| 11 | 11 | 
 | 
| 12 | 12 | use crate::blinded_path::BlindedPath; | 
|  | 13 | +use crate::events::{Event, EventsProvider}; | 
| 13 | 14 | use crate::ln::features::InitFeatures; | 
| 14 |  | -use crate::ln::msgs::{self, DecodeError, OnionMessageHandler}; | 
|  | 15 | +use crate::ln::msgs::{self, DecodeError, OnionMessageHandler, SocketAddress}; | 
| 15 | 16 | use crate::sign::{NodeSigner, Recipient}; | 
| 16 | 17 | use crate::util::ser::{FixedLengthReader, LengthReadable, Writeable, Writer}; | 
| 17 | 18 | use crate::util::test_utils; | 
| @@ -49,7 +50,7 @@ impl MessageRouter for TestMessageRouter { | 
| 49 | 50 | 		Ok(OnionMessagePath { | 
| 50 | 51 | 			intermediate_nodes: vec![], | 
| 51 | 52 | 			destination, | 
| 52 |  | -			addresses: None, | 
|  | 53 | +			addresses: Some(vec![SocketAddress::TcpIpV4 { addr: [127, 0, 0, 1], port: 1000 }]), | 
| 53 | 54 | 		}) | 
| 54 | 55 | 	} | 
| 55 | 56 | } | 
| @@ -179,15 +180,30 @@ fn create_nodes_using_secrets(secrets: Vec<SecretKey>) -> Vec<MessengerNode> { | 
| 179 | 180 | 		}); | 
| 180 | 181 | 	} | 
| 181 | 182 | 	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]); | 
| 187 | 184 | 	} | 
| 188 | 185 | 	nodes | 
| 189 | 186 | } | 
| 190 | 187 | 
 | 
|  | 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 | + | 
| 191 | 207 | fn pass_along_path(path: &Vec<MessengerNode>) { | 
| 192 | 208 | 	let mut prev_node = &path[0]; | 
| 193 | 209 | 	for node in path.into_iter().skip(1) { | 
| @@ -458,6 +474,72 @@ fn many_hops() { | 
| 458 | 474 | 	pass_along_path(&nodes); | 
| 459 | 475 | } | 
| 460 | 476 | 
 | 
|  | 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 | + | 
| 461 | 543 | #[test] | 
| 462 | 544 | fn spec_test_vector() { | 
| 463 | 545 | 	let secret_keys = [ | 
|  | 
0 commit comments