diff --git a/lightning/src/onion_message/functional_tests.rs b/lightning/src/onion_message/functional_tests.rs index 57a7bc8afd5..10c5bea86f7 100644 --- a/lightning/src/onion_message/functional_tests.rs +++ b/lightning/src/onion_message/functional_tests.rs @@ -9,24 +9,32 @@ //! Onion message testing and test utilities live here. +use super::async_payments::{AsyncPaymentsMessageHandler, HeldHtlcAvailable, ReleaseHeldHtlc}; +use super::dns_resolution::{ + DNSResolverMessage, DNSResolverMessageHandler, DNSSECProof, DNSSECQuery, +}; +use super::messenger::{ + CustomOnionMessageHandler, DefaultMessageRouter, Destination, MessageSendInstructions, + OnionMessagePath, OnionMessenger, Responder, ResponseInstruction, SendError, SendSuccess, +}; +use super::offers::{OffersMessage, OffersMessageHandler}; +use super::packet::{OnionMessageContents, Packet}; +use crate::blinded_path::message::{ + AsyncPaymentsContext, BlindedMessagePath, DNSResolverContext, MessageContext, + MessageForwardNode, OffersContext, +}; use crate::blinded_path::EmptyNodeIdLookUp; -use crate::blinded_path::message::{AsyncPaymentsContext, BlindedMessagePath, DNSResolverContext, MessageForwardNode, MessageContext, OffersContext}; use crate::events::{Event, EventsProvider}; -use crate::types::features::{ChannelFeatures, InitFeatures}; use crate::ln::msgs::{self, DecodeError, OnionMessageHandler}; use crate::routing::gossip::{NetworkGraph, P2PGossipSync}; use crate::routing::test_utils::{add_channel, add_or_update_node}; use crate::sign::{NodeSigner, Recipient}; +use crate::types::features::{ChannelFeatures, InitFeatures}; use crate::util::ser::{FixedLengthReader, LengthReadable, Writeable, Writer}; use crate::util::test_utils; -use super::async_payments::{AsyncPaymentsMessageHandler, HeldHtlcAvailable, ReleaseHeldHtlc}; -use super::dns_resolution::{DNSResolverMessageHandler, DNSResolverMessage, DNSSECProof, DNSSECQuery}; -use super::messenger::{CustomOnionMessageHandler, DefaultMessageRouter, Destination, OnionMessagePath, OnionMessenger, Responder, ResponseInstruction, MessageSendInstructions, SendError, SendSuccess}; -use super::offers::{OffersMessage, OffersMessageHandler}; -use super::packet::{OnionMessageContents, Packet}; -use bitcoin::network::Network; use bitcoin::hex::FromHex; +use bitcoin::network::Network; use bitcoin::secp256k1::{All, PublicKey, Secp256k1, SecretKey}; use crate::io; @@ -46,22 +54,26 @@ struct MessengerNode { Arc, Arc, Arc, - Arc>>, - Arc, - Arc - >>, + Arc< + DefaultMessageRouter< + Arc>>, + Arc, + Arc, + >, + >, Arc, Arc, Arc, - Arc + Arc, >, custom_message_handler: Arc, - gossip_sync: Arc>>, - Arc, - Arc - >> + gossip_sync: Arc< + P2PGossipSync< + Arc>>, + Arc, + Arc, + >, + >, } impl Drop for MessengerNode { @@ -76,7 +88,10 @@ impl Drop for MessengerNode { struct TestOffersMessageHandler {} impl OffersMessageHandler for TestOffersMessageHandler { - fn handle_message(&self, _message: OffersMessage, _context: Option, _responder: Option) -> Option<(OffersMessage, ResponseInstruction)> { + fn handle_message( + &self, _message: OffersMessage, _context: Option, + _responder: Option, + ) -> Option<(OffersMessage, ResponseInstruction)> { None } } @@ -156,21 +171,17 @@ impl TestCustomMessageHandler { } fn expect_message(&self, message: TestCustomMessage) { - self.expectations.lock().unwrap().push_back( - OnHandleCustomMessage { - expect: message, - include_reply_path: false, - } - ); + self.expectations + .lock() + .unwrap() + .push_back(OnHandleCustomMessage { expect: message, include_reply_path: false }); } fn expect_message_and_response(&self, message: TestCustomMessage) { - self.expectations.lock().unwrap().push_back( - OnHandleCustomMessage { - expect: message, - include_reply_path: true, - } - ); + self.expectations + .lock() + .unwrap() + .push_back(OnHandleCustomMessage { expect: message, include_reply_path: true }); } fn get_next_expectation(&self) -> OnHandleCustomMessage { @@ -189,7 +200,9 @@ impl Drop for TestCustomMessageHandler { impl CustomOnionMessageHandler for TestCustomMessageHandler { type CustomMessage = TestCustomMessage; - fn handle_custom_message(&self, msg: Self::CustomMessage, context: Option>, responder: Option) -> Option<(Self::CustomMessage, ResponseInstruction)> { + fn handle_custom_message( + &self, msg: Self::CustomMessage, context: Option>, responder: Option, + ) -> Option<(Self::CustomMessage, ResponseInstruction)> { let expectation = self.get_next_expectation(); assert_eq!(msg, expectation.expect); @@ -204,14 +217,22 @@ impl CustomOnionMessageHandler for TestCustomMessageHandler { } match responder { - Some(responder) if expectation.include_reply_path => { - Some((response, responder.respond_with_reply_path(MessageContext::Custom(context.unwrap_or_else(Vec::new))))) - }, + Some(responder) if expectation.include_reply_path => Some(( + response, + responder.respond_with_reply_path(MessageContext::Custom( + context.unwrap_or_else(Vec::new), + )), + )), Some(responder) => Some((response, responder.respond())), - None => None + None => None, } } - fn read_custom_message(&self, message_type: u64, buffer: &mut R) -> Result, DecodeError> where Self: Sized { + fn read_custom_message( + &self, message_type: u64, buffer: &mut R, + ) -> Result, DecodeError> + where + Self: Sized, + { match message_type { CUSTOM_PING_MESSAGE_TYPE => { let buf = read_to_end(buffer)?; @@ -226,16 +247,15 @@ impl CustomOnionMessageHandler for TestCustomMessageHandler { _ => Ok(None), } } - fn release_pending_custom_messages(&self) -> Vec<(Self::CustomMessage, MessageSendInstructions)> { + fn release_pending_custom_messages( + &self, + ) -> Vec<(Self::CustomMessage, MessageSendInstructions)> { vec![] } } fn create_nodes(num_messengers: u8) -> Vec { - let cfgs = (1..=num_messengers) - .into_iter() - .map(|_| MessengerCfg::new()) - .collect(); + let cfgs = (1..=num_messengers).into_iter().map(|_| MessengerCfg::new()).collect(); create_nodes_using_cfgs(cfgs) } @@ -260,38 +280,46 @@ impl MessengerCfg { fn create_nodes_using_cfgs(cfgs: Vec) -> Vec { let gossip_logger = Arc::new(test_utils::TestLogger::with_id("gossip".to_string())); let network_graph = Arc::new(NetworkGraph::new(Network::Testnet, gossip_logger.clone())); - let gossip_sync = Arc::new( - P2PGossipSync::new(network_graph.clone(), None, gossip_logger) - ); + let gossip_sync = Arc::new(P2PGossipSync::new(network_graph.clone(), None, gossip_logger)); let mut nodes = Vec::new(); for (i, cfg) in cfgs.into_iter().enumerate() { - let secret_key = cfg.secret_override.unwrap_or(SecretKey::from_slice(&[(i + 1) as u8; 32]).unwrap()); + let secret_key = + cfg.secret_override.unwrap_or(SecretKey::from_slice(&[(i + 1) as u8; 32]).unwrap()); let logger = Arc::new(test_utils::TestLogger::with_id(format!("node {}", i))); let seed = [i as u8; 32]; let entropy_source = Arc::new(test_utils::TestKeysInterface::new(&seed, Network::Testnet)); let node_signer = Arc::new(test_utils::TestNodeSigner::new(secret_key)); let node_id_lookup = Arc::new(EmptyNodeIdLookUp {}); - let message_router = Arc::new( - DefaultMessageRouter::new(network_graph.clone(), entropy_source.clone()) - ); + let message_router = + Arc::new(DefaultMessageRouter::new(network_graph.clone(), entropy_source.clone())); let offers_message_handler = Arc::new(TestOffersMessageHandler {}); let async_payments_message_handler = Arc::new(TestAsyncPaymentsMessageHandler {}); let dns_resolver_message_handler = Arc::new(TestDNSResolverMessageHandler {}); let custom_message_handler = Arc::new(TestCustomMessageHandler::new()); let messenger = if cfg.intercept_offline_peer_oms { OnionMessenger::new_with_offline_peer_interception( - entropy_source.clone(), node_signer.clone(), logger.clone(), - node_id_lookup, message_router, offers_message_handler, - async_payments_message_handler, dns_resolver_message_handler, + entropy_source.clone(), + node_signer.clone(), + logger.clone(), + node_id_lookup, + message_router, + offers_message_handler, + async_payments_message_handler, + dns_resolver_message_handler, custom_message_handler.clone(), ) } else { OnionMessenger::new( - entropy_source.clone(), node_signer.clone(), logger.clone(), - node_id_lookup, message_router, offers_message_handler, - async_payments_message_handler, dns_resolver_message_handler, + entropy_source.clone(), + node_signer.clone(), + logger.clone(), + node_id_lookup, + message_router, + offers_message_handler, + async_payments_message_handler, + dns_resolver_message_handler, custom_message_handler.clone(), ) }; @@ -330,7 +358,8 @@ fn release_events(node: &MessengerNode) -> Vec { } fn add_channel_to_graph( - node_a: &MessengerNode, node_b: &MessengerNode, secp_ctx: &Secp256k1, short_channel_id: u64 + node_a: &MessengerNode, node_b: &MessengerNode, secp_ctx: &Secp256k1, + short_channel_id: u64, ) { let gossip_sync = node_a.gossip_sync.deref(); let privkey_a = &node_a.privkey; @@ -347,7 +376,7 @@ fn pass_along_path(path: &Vec) { let mut prev_node = &path[0]; for node in path.into_iter().skip(1) { let events = prev_node.messenger.release_pending_msgs(); - let onion_msg = { + let onion_msg = { let msgs = events.get(&node.node_id).unwrap(); assert_eq!(msgs.len(), 1); msgs[0].clone() @@ -392,7 +421,14 @@ fn one_blinded_hop() { let secp_ctx = Secp256k1::new(); let context = MessageContext::Custom(Vec::new()); - let blinded_path = BlindedMessagePath::new(&[], nodes[1].node_id, context, &*nodes[1].entropy_source, &secp_ctx).unwrap(); + let blinded_path = BlindedMessagePath::new( + &[], + nodes[1].node_id, + context, + &*nodes[1].entropy_source, + &secp_ctx, + ) + .unwrap(); let destination = Destination::BlindedPath(blinded_path); let instructions = MessageSendInstructions::WithoutReplyPath { destination }; nodes[0].messenger.send_onion_message(test_msg, instructions).unwrap(); @@ -406,9 +442,17 @@ fn two_unblinded_two_blinded() { let test_msg = TestCustomMessage::Pong; let secp_ctx = Secp256k1::new(); - let intermediate_nodes = [MessageForwardNode { node_id: nodes[3].node_id, short_channel_id: None }]; + let intermediate_nodes = + [MessageForwardNode { node_id: nodes[3].node_id, short_channel_id: None }]; let context = MessageContext::Custom(Vec::new()); - let blinded_path = BlindedMessagePath::new(&intermediate_nodes, nodes[4].node_id, context, &*nodes[4].entropy_source, &secp_ctx).unwrap(); + let blinded_path = BlindedMessagePath::new( + &intermediate_nodes, + nodes[4].node_id, + context, + &*nodes[4].entropy_source, + &secp_ctx, + ) + .unwrap(); let path = OnionMessagePath { intermediate_nodes: vec![nodes[1].node_id, nodes[2].node_id], destination: Destination::BlindedPath(blinded_path), @@ -431,7 +475,14 @@ fn three_blinded_hops() { MessageForwardNode { node_id: nodes[2].node_id, short_channel_id: None }, ]; let context = MessageContext::Custom(Vec::new()); - let blinded_path = BlindedMessagePath::new(&intermediate_nodes, nodes[3].node_id, context, &*nodes[3].entropy_source, &secp_ctx).unwrap(); + let blinded_path = BlindedMessagePath::new( + &intermediate_nodes, + nodes[3].node_id, + context, + &*nodes[3].entropy_source, + &secp_ctx, + ) + .unwrap(); let destination = Destination::BlindedPath(blinded_path); let instructions = MessageSendInstructions::WithoutReplyPath { destination }; @@ -455,14 +506,22 @@ fn async_response_over_one_blinded_hop() { // 3. Simulate the creation of a Blinded Reply path provided by Bob. let secp_ctx = Secp256k1::new(); let context = MessageContext::Custom(Vec::new()); - let reply_path = BlindedMessagePath::new(&[], nodes[1].node_id, context, &*nodes[1].entropy_source, &secp_ctx).unwrap(); + let reply_path = BlindedMessagePath::new( + &[], + nodes[1].node_id, + context, + &*nodes[1].entropy_source, + &secp_ctx, + ) + .unwrap(); // 4. Create a responder using the reply path for Alice. let responder = Some(Responder::new(reply_path)); // 5. Expect Alice to receive the message and create a response instruction for it. alice.custom_message_handler.expect_message(message.clone()); - let response_instruction = nodes[0].custom_message_handler.handle_custom_message(message, None, responder); + let response_instruction = + nodes[0].custom_message_handler.handle_custom_message(message, None, responder); // 6. Simulate Alice asynchronously responding back to Bob with a response. let (msg, instructions) = response_instruction.unwrap(); @@ -492,12 +551,15 @@ fn async_response_with_reply_path_succeeds() { // Alice receives a message from Bob with an added reply_path for responding back. let message = TestCustomMessage::Ping; let context = MessageContext::Custom(Vec::new()); - let reply_path = BlindedMessagePath::new(&[], bob.node_id, context, &*bob.entropy_source, &secp_ctx).unwrap(); + let reply_path = + BlindedMessagePath::new(&[], bob.node_id, context, &*bob.entropy_source, &secp_ctx) + .unwrap(); // Alice asynchronously responds to Bob, expecting a response back from him. let responder = Responder::new(reply_path); alice.custom_message_handler.expect_message_and_response(message.clone()); - let response_instruction = alice.custom_message_handler.handle_custom_message(message, None, Some(responder)); + let response_instruction = + alice.custom_message_handler.handle_custom_message(message, None, Some(responder)); let (msg, instructions) = response_instruction.unwrap(); assert_eq!( @@ -530,14 +592,17 @@ fn async_response_with_reply_path_fails() { // Alice receives a message from Bob with an added reply_path for responding back. let message = TestCustomMessage::Ping; let context = MessageContext::Custom(Vec::new()); - let reply_path = BlindedMessagePath::new(&[], bob.node_id, context, &*bob.entropy_source, &secp_ctx).unwrap(); + let reply_path = + BlindedMessagePath::new(&[], bob.node_id, context, &*bob.entropy_source, &secp_ctx) + .unwrap(); // Alice tries to asynchronously respond to Bob, but fails because the nodes are unannounced and // disconnected. Thus, a reply path could no be created for the response. disconnect_peers(alice, bob); let responder = Responder::new(reply_path); alice.custom_message_handler.expect_message_and_response(message.clone()); - let response_instruction = alice.custom_message_handler.handle_custom_message(message, None, Some(responder)); + let response_instruction = + alice.custom_message_handler.handle_custom_message(message, None, Some(responder)); let (msg, instructions) = response_instruction.unwrap(); assert_eq!( @@ -576,7 +641,14 @@ fn we_are_intro_node() { MessageForwardNode { node_id: nodes[1].node_id, short_channel_id: None }, ]; let context = MessageContext::Custom(Vec::new()); - let blinded_path = BlindedMessagePath::new(&intermediate_nodes, nodes[2].node_id, context, &*nodes[2].entropy_source, &secp_ctx).unwrap(); + let blinded_path = BlindedMessagePath::new( + &intermediate_nodes, + nodes[2].node_id, + context, + &*nodes[2].entropy_source, + &secp_ctx, + ) + .unwrap(); let destination = Destination::BlindedPath(blinded_path); let instructions = MessageSendInstructions::WithoutReplyPath { destination }; @@ -585,9 +657,17 @@ fn we_are_intro_node() { pass_along_path(&nodes); // Try with a two-hop blinded path where we are the introduction node. - let intermediate_nodes = [MessageForwardNode { node_id: nodes[0].node_id, short_channel_id: None }]; + let intermediate_nodes = + [MessageForwardNode { node_id: nodes[0].node_id, short_channel_id: None }]; let context = MessageContext::Custom(Vec::new()); - let blinded_path = BlindedMessagePath::new(&intermediate_nodes, nodes[1].node_id, context, &*nodes[1].entropy_source, &secp_ctx).unwrap(); + let blinded_path = BlindedMessagePath::new( + &intermediate_nodes, + nodes[1].node_id, + context, + &*nodes[1].entropy_source, + &secp_ctx, + ) + .unwrap(); let destination = Destination::BlindedPath(blinded_path); let instructions = MessageSendInstructions::WithoutReplyPath { destination }; @@ -604,9 +684,17 @@ fn invalid_blinded_path_error() { let test_msg = TestCustomMessage::Pong; let secp_ctx = Secp256k1::new(); - let intermediate_nodes = [MessageForwardNode { node_id: nodes[1].node_id, short_channel_id: None }]; + let intermediate_nodes = + [MessageForwardNode { node_id: nodes[1].node_id, short_channel_id: None }]; let context = MessageContext::Custom(Vec::new()); - let mut blinded_path = BlindedMessagePath::new(&intermediate_nodes, nodes[2].node_id, context, &*nodes[2].entropy_source, &secp_ctx).unwrap(); + let mut blinded_path = BlindedMessagePath::new( + &intermediate_nodes, + nodes[2].node_id, + context, + &*nodes[2].entropy_source, + &secp_ctx, + ) + .unwrap(); blinded_path.clear_blinded_hops(); let destination = Destination::BlindedPath(blinded_path); let instructions = MessageSendInstructions::WithoutReplyPath { destination }; @@ -632,8 +720,18 @@ fn reply_path() { MessageForwardNode { node_id: nodes[1].node_id, short_channel_id: None }, ]; let context = MessageContext::Custom(Vec::new()); - let reply_path = BlindedMessagePath::new(&intermediate_nodes, nodes[0].node_id, context, &*nodes[0].entropy_source, &secp_ctx).unwrap(); - nodes[0].messenger.send_onion_message_using_path(path, test_msg.clone(), Some(reply_path)).unwrap(); + let reply_path = BlindedMessagePath::new( + &intermediate_nodes, + nodes[0].node_id, + context, + &*nodes[0].entropy_source, + &secp_ctx, + ) + .unwrap(); + nodes[0] + .messenger + .send_onion_message_using_path(path, test_msg.clone(), Some(reply_path)) + .unwrap(); nodes[3].custom_message_handler.expect_message(TestCustomMessage::Ping); pass_along_path(&nodes); // Make sure the last node successfully decoded the reply path. @@ -647,14 +745,28 @@ fn reply_path() { MessageForwardNode { node_id: nodes[2].node_id, short_channel_id: None }, ]; let context = MessageContext::Custom(Vec::new()); - let blinded_path = BlindedMessagePath::new(&intermediate_nodes, nodes[3].node_id, context, &*nodes[3].entropy_source, &secp_ctx).unwrap(); + let blinded_path = BlindedMessagePath::new( + &intermediate_nodes, + nodes[3].node_id, + context, + &*nodes[3].entropy_source, + &secp_ctx, + ) + .unwrap(); let destination = Destination::BlindedPath(blinded_path); let intermediate_nodes = [ MessageForwardNode { node_id: nodes[2].node_id, short_channel_id: None }, MessageForwardNode { node_id: nodes[1].node_id, short_channel_id: None }, ]; let context = MessageContext::Custom(Vec::new()); - let reply_path = BlindedMessagePath::new(&intermediate_nodes, nodes[0].node_id, context, &*nodes[0].entropy_source, &secp_ctx).unwrap(); + let reply_path = BlindedMessagePath::new( + &intermediate_nodes, + nodes[0].node_id, + context, + &*nodes[0].entropy_source, + &secp_ctx, + ) + .unwrap(); let instructions = MessageSendInstructions::WithSpecifiedReplyPath { destination, reply_path }; nodes[0].messenger.send_onion_message(test_msg, instructions).unwrap(); @@ -672,7 +784,7 @@ fn invalid_custom_message_type() { let nodes = create_nodes(2); #[derive(Debug)] - struct InvalidCustomMessage{} + struct InvalidCustomMessage {} impl OnionMessageContents for InvalidCustomMessage { fn tlv_type(&self) -> u64 { // Onion message contents must have a TLV >= 64. @@ -689,7 +801,9 @@ fn invalid_custom_message_type() { } impl Writeable for InvalidCustomMessage { - fn write(&self, _w: &mut W) -> Result<(), io::Error> { unreachable!() } + fn write(&self, _w: &mut W) -> Result<(), io::Error> { + unreachable!() + } } let test_msg = InvalidCustomMessage {}; @@ -707,7 +821,8 @@ fn peer_buffer_full() { let destination = Destination::Node(nodes[1].node_id); let instructions = MessageSendInstructions::WithoutReplyPath { destination }; - for _ in 0..188 { // Based on MAX_PER_PEER_BUFFER_SIZE in OnionMessenger + for _ in 0..188 { + // Based on MAX_PER_PEER_BUFFER_SIZE in OnionMessenger nodes[0].messenger.send_onion_message(test_msg.clone(), instructions.clone()).unwrap(); } let err = nodes[0].messenger.send_onion_message(test_msg, instructions.clone()).unwrap_err(); @@ -723,17 +838,17 @@ fn many_hops() { let test_msg = TestCustomMessage::Pong; let mut intermediate_nodes = vec![]; - for i in 1..(num_nodes-1) { + for i in 1..(num_nodes - 1) { intermediate_nodes.push(nodes[i].node_id); } let path = OnionMessagePath { intermediate_nodes, - destination: Destination::Node(nodes[num_nodes-1].node_id), + destination: Destination::Node(nodes[num_nodes - 1].node_id), first_node_addresses: None, }; nodes[0].messenger.send_onion_message_using_path(path, test_msg, None).unwrap(); - nodes[num_nodes-1].custom_message_handler.expect_message(TestCustomMessage::Pong); + nodes[num_nodes - 1].custom_message_handler.expect_message(TestCustomMessage::Pong); pass_along_path(&nodes); } @@ -744,11 +859,17 @@ fn requests_peer_connection_for_buffered_messages() { let secp_ctx = Secp256k1::new(); add_channel_to_graph(&nodes[0], &nodes[1], &secp_ctx, 42); - let intermediate_nodes = [MessageForwardNode { node_id: nodes[1].node_id, short_channel_id: None }]; + let intermediate_nodes = + [MessageForwardNode { node_id: nodes[1].node_id, short_channel_id: None }]; let context = MessageContext::Custom(Vec::new()); let blinded_path = BlindedMessagePath::new( - &intermediate_nodes, nodes[2].node_id, context, &*nodes[0].entropy_source, &secp_ctx - ).unwrap(); + &intermediate_nodes, + nodes[2].node_id, + context, + &*nodes[0].entropy_source, + &secp_ctx, + ) + .unwrap(); let destination = Destination::BlindedPath(blinded_path); let instructions = MessageSendInstructions::WithoutReplyPath { destination }; @@ -784,11 +905,17 @@ fn drops_buffered_messages_waiting_for_peer_connection() { let secp_ctx = Secp256k1::new(); add_channel_to_graph(&nodes[0], &nodes[1], &secp_ctx, 42); - let intermediate_nodes = [MessageForwardNode { node_id: nodes[1].node_id, short_channel_id: None }]; + let intermediate_nodes = + [MessageForwardNode { node_id: nodes[1].node_id, short_channel_id: None }]; let context = MessageContext::Custom(Vec::new()); let blinded_path = BlindedMessagePath::new( - &intermediate_nodes, nodes[2].node_id, context, &*nodes[0].entropy_source, &secp_ctx - ).unwrap(); + &intermediate_nodes, + nodes[2].node_id, + context, + &*nodes[0].entropy_source, + &secp_ctx, + ) + .unwrap(); let destination = Destination::BlindedPath(blinded_path); let instructions = MessageSendInstructions::WithoutReplyPath { destination }; @@ -819,7 +946,11 @@ fn intercept_offline_peer_oms() { // new_with_offline_peer_interception, we will intercept OMs for offline // peers, generate the right events, and forward OMs when they are re-injected // by the user. - let node_cfgs = vec![MessengerCfg::new(), MessengerCfg::new().with_offline_peer_interception(), MessengerCfg::new()]; + let node_cfgs = vec![ + MessengerCfg::new(), + MessengerCfg::new().with_offline_peer_interception(), + MessengerCfg::new(), + ]; let mut nodes = create_nodes_using_cfgs(node_cfgs); let peer_conn_evs = release_events(&nodes[1]); @@ -830,17 +961,23 @@ fn intercept_offline_peer_oms() { let node_idx = if i == 0 { 0 } else { 2 }; assert_eq!(peer_node_id, &nodes[node_idx].node_id); }, - _ => panic!() + _ => panic!(), } } let message = TestCustomMessage::Pong; let secp_ctx = Secp256k1::new(); - let intermediate_nodes = [MessageForwardNode { node_id: nodes[1].node_id, short_channel_id: None }]; + let intermediate_nodes = + [MessageForwardNode { node_id: nodes[1].node_id, short_channel_id: None }]; let context = MessageContext::Custom(Vec::new()); let blinded_path = BlindedMessagePath::new( - &intermediate_nodes, nodes[2].node_id, context, &*nodes[2].entropy_source, &secp_ctx - ).unwrap(); + &intermediate_nodes, + nodes[2].node_id, + context, + &*nodes[2].entropy_source, + &secp_ctx, + ) + .unwrap(); let destination = Destination::BlindedPath(blinded_path); let instructions = MessageSendInstructions::WithoutReplyPath { destination }; @@ -857,12 +994,15 @@ fn intercept_offline_peer_oms() { assert_eq!(peer_node_id, final_node_vec[0].node_id); message }, - _ => panic!() + _ => panic!(), }; // Ensure that we'll refuse to forward the re-injected OM until after the // outbound peer comes back online. - let err = nodes[1].messenger.forward_onion_message(onion_message.clone(), &final_node_vec[0].node_id).unwrap_err(); + let err = nodes[1] + .messenger + .forward_onion_message(onion_message.clone(), &final_node_vec[0].node_id) + .unwrap_err(); assert_eq!(err, SendError::InvalidFirstHop(final_node_vec[0].node_id)); connect_peers(&nodes[1], &final_node_vec[0]); @@ -872,7 +1012,7 @@ fn intercept_offline_peer_oms() { Event::OnionMessagePeerConnected { peer_node_id } => { assert_eq!(peer_node_id, final_node_vec[0].node_id); }, - _ => panic!() + _ => panic!(), } nodes[1].messenger.forward_onion_message(onion_message, &final_node_vec[0].node_id).unwrap(); @@ -888,10 +1028,10 @@ fn spec_test_vector() { "4343434343434343434343434343434343434343434343434343434343434343", // Carol "4444444444444444444444444444444444444444444444444444444444444444", // Dave ] - .iter() - .map(|secret_hex| SecretKey::from_slice(&>::from_hex(secret_hex).unwrap()).unwrap()) - .map(|secret| MessengerCfg::new().with_node_secret(secret)) - .collect(); + .iter() + .map(|secret_hex| SecretKey::from_slice(&>::from_hex(secret_hex).unwrap()).unwrap()) + .map(|secret| MessengerCfg::new().with_node_secret(secret)) + .collect(); let nodes = create_nodes_using_cfgs(node_cfgs); // Hardcode the sender->Alice onion message, because it includes an unknown TLV of type 1, which @@ -904,7 +1044,16 @@ fn spec_test_vector() { ::read(&mut packet_reader).unwrap(); let secp_ctx = Secp256k1::new(); let sender_to_alice_om = msgs::OnionMessage { - blinding_point: PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&>::from_hex("6363636363636363636363636363636363636363636363636363636363636363").unwrap()).unwrap()), + blinding_point: PublicKey::from_secret_key( + &secp_ctx, + &SecretKey::from_slice( + &>::from_hex( + "6363636363636363636363636363636363636363636363636363636363636363", + ) + .unwrap(), + ) + .unwrap(), + ), onion_routing_packet: sender_to_alice_packet, }; // The spec test vectors prepend the OM message type (513) to the encoded onion message strings, @@ -918,7 +1067,8 @@ fn spec_test_vector() { let bob_to_carol_om = nodes[1].messenger.next_onion_message_for_peer(nodes[2].node_id).unwrap(); assert_eq!(bob_to_carol_om.encode(), >::from_hex("02b684babfd400c8dd48b367e9754b8021a3594a34dc94d7101776c7f6a86d0582055600029a77e8523162efa1f4208f4f2050cd5c386ddb6ce6d36235ea569d217ec52209fb85fdf7dbc4786c373eebdba0ddc184cfbe6da624f610e93f62c70f2c56be1090b926359969f040f932c03f53974db5656233bd60af375517d4323002937d784c2c88a564bcefe5c33d3fc21c26d94dfacab85e2e19685fd2ff4c543650958524439b6da68779459aee5ffc9dc543339acec73ff43be4c44ddcbe1c11d50e2411a67056ba9db7939d780f5a86123fdd3abd6f075f7a1d78ab7daf3a82798b7ec1e9f1345bc0d1e935098497067e2ae5a51ece396fcb3bb30871ad73aee51b2418b39f00c8e8e22be4a24f4b624e09cb0414dd46239de31c7be035f71e8da4f5a94d15b44061f46414d3f355069b5c5b874ba56704eb126148a22ec873407fe118972127e63ff80e682e410f297f23841777cec0517e933eaf49d7e34bd203266b42081b3a5193b51ccd34b41342bc67cf73523b741f5c012ba2572e9dda15fbe131a6ac2ff24dc2a7622d58b9f3553092cfae7fae3c8864d95f97aa49ec8edeff5d9f5782471160ee412d82ff6767030fc63eec6a93219a108cd41433834b26676a39846a944998796c79cd1cc460531b8ded659cedfd8aecefd91944f00476f1496daafb4ea6af3feacac1390ea510709783c2aa81a29de27f8959f6284f4684102b17815667cbb0645396ac7d542b878d90c42a1f7f00c4c4eedb2a22a219f38afadb4f1f562b6e000a94e75cc38f535b43a3c0384ccef127fde254a9033a317701c710b2b881065723486e3f4d3eea5e12f374a41565fe43fa137c1a252c2153dde055bb343344c65ad0529010ece29bbd405effbebfe3ba21382b94a60ac1a5ffa03f521792a67b30773cb42e862a8a02a8bbd41b842e115969c87d1ff1f8c7b5726b9f20772dd57fe6e4ea41f959a2a673ffad8e2f2a472c4c8564f3a5a47568dd75294b1c7180c500f7392a7da231b1fe9e525ea2d7251afe9ca52a17fe54a116cb57baca4f55b9b6de915924d644cba9dade4ccc01939d7935749c008bafc6d3ad01cd72341ce5ddf7a5d7d21cf0465ab7a3233433aef21f9acf2bfcdc5a8cc003adc4d82ac9d72b36eb74e05c9aa6ccf439ac92e6b84a3191f0764dd2a2e0b4cc3baa08782b232ad6ecd3ca6029bc08cc094aef3aebddcaddc30070cb6023a689641de86cfc6341c8817215a4650f844cd2ca60f2f10c6e44cfc5f23912684d4457bf4f599879d30b79bf12ef1ab8d34dddc15672b82e56169d4c770f0a2a7a960b1e8790773f5ff7fce92219808f16d061cc85e053971213676d28fb48925e9232b66533dbd938458eb2cc8358159df7a2a2e4cf87500ede2afb8ce963a845b98978edf26a6948d4932a6b95d022004556d25515fe158092ce9a913b4b4a493281393ca731e8d8e5a3449b9d888fc4e73ffcbb9c6d6d66e88e03cf6e81a0496ede6e4e4172b08c000601993af38f80c7f68c9d5fff9e0e215cff088285bf039ca731744efcb7825a272ca724517736b4890f47e306b200aa2543c363e2c9090bcf3cf56b5b86868a62471c7123a41740392fc1d5ab28da18dca66618e9af7b42b62b23aba907779e73ca03ec60e6ab9e0484b9cae6578e0fddb6386cb3468506bf6420298bf4a690947ab582255551d82487f271101c72e19e54872ab47eae144db66bc2f8194a666a5daec08d12822cb83a61946234f2dfdbd6ca7d8763e6818adee7b401fcdb1ac42f9df1ac5cc5ac131f2869013c8d6cd29d4c4e3d05bccd34ca83366d616296acf854fa05149bfd763a25b9938e96826a037fdcb85545439c76df6beed3bdbd01458f9cf984997cc4f0a7ac3cc3f5e1eeb59c09cadcf5a537f16e444149c8f17d4bdaef16c9fbabc5ef06eb0f0bf3a07a1beddfeacdaf1df5582d6dbd6bb808d6ab31bc22e5d7").unwrap()); nodes[2].messenger.handle_onion_message(nodes[1].node_id, &bob_to_carol_om); - let carol_to_dave_om = nodes[2].messenger.next_onion_message_for_peer(nodes[3].node_id).unwrap(); + let carol_to_dave_om = + nodes[2].messenger.next_onion_message_for_peer(nodes[3].node_id).unwrap(); assert_eq!(carol_to_dave_om.encode(), >::from_hex("025aaca62db7ce6b46386206ef9930daa32e979a35cb185a41cb951aa7d254b03c055600025550b2910294fa73bda99b9de9c851be9cbb481e23194a1743033630efba546b86e7d838d0f6e9cc0ed088dbf6889f0dceca3bfc745bd77d013a31311fa932a8bf1d28387d9ff521eabc651dee8f861fed609a68551145a451f017ec44978addeee97a423c08445531da488fd1ddc998e9cdbfcea59517b53fbf1833f0bbe6188dba6ca773a247220ec934010daca9cc185e1ceb136803469baac799e27a0d82abe53dc48a06a55d1f643885cc7894677dd20a4e4152577d1ba74b870b9279f065f9b340cedb3ca13b7df218e853e10ccd1b59c42a2acf93f489e170ee4373d30ab158b60fc20d3ba73a1f8c750951d69fb5b9321b968ddc8114936412346aff802df65516e1c09c51ef19849ff36c0199fd88c8bec301a30fef0c7cb497901c038611303f64e4174b5daf42832aa5586b84d2c9b95f382f4269a5d1bd4be898618dc78dfd451170f72ca16decac5b03e60702112e439cadd104fb3bbb3d5023c9b80823fdcd0a212a7e1aaa6eeb027adc7f8b3723031d135a09a979a4802788bb7861c6cc85501fb91137768b70aeab309b27b885686604ffc387004ac4f8c44b101c39bc0597ef7fd957f53fc5051f534b10eb3852100962b5e58254e5558689913c26ad6072ea41f5c5db10077cfc91101d4ae393be274c74297da5cc381cd88d54753aaa7df74b2f9da8d88a72bc9218fcd1f19e4ff4aace182312b9509c5175b6988f044c5756d232af02a451a02ca752f3c52747773acff6fd07d2032e6ce562a2c42105d106eba02d0b1904182cdc8c74875b082d4989d3a7e9f0e73de7c75d357f4af976c28c0b206c5e8123fc2391d078592d0d5ff686fd245c0a2de2e535b7cca99c0a37d432a8657393a9e3ca53eec1692159046ba52cb9bc97107349d8673f74cbc97e231f1108005c8d03e24ca813cea2294b39a7a493bcc062708f1f6cf0074e387e7d50e0666ce784ef4d31cb860f6cad767438d9ea5156ff0ae86e029e0247bf94df75ee0cda4f2006061455cb2eaff513d558863ae334cef7a3d45f55e7cc13153c6719e9901c1d4db6c03f643b69ea4860690305651794284d9e61eb848ccdf5a77794d376f0af62e46d4835acce6fd9eef5df73ebb8ea3bb48629766967f446e744ecc57ff3642c4aa1ccee9a2f72d5caa75fa05787d08b79408fce792485fdecdc25df34820fb061275d70b84ece540b0fc47b2453612be34f2b78133a64e812598fbe225fd85415f8ffe5340ce955b5fd9d67dd88c1c531dde298ed25f96df271558c812c26fa386966c76f03a6ebccbca49ac955916929bd42e134f982dde03f924c464be5fd1ba44f8dc4c3cbc8162755fd1d8f7dc044b15b1a796c53df7d8769bb167b2045b49cc71e08908796c92c16a235717cabc4bb9f60f8f66ff4fff1f9836388a99583acebdff4a7fb20f48eedcd1f4bdcc06ec8b48e35307df51d9bc81d38a94992dd135b30079e1f592da6e98dff496cb1a7776460a26b06395b176f585636ebdf7eab692b227a31d6979f5a6141292698e91346b6c806b90c7c6971e481559cae92ee8f4136f2226861f5c39ddd29bbdb118a35dece03f49a96804caea79a3dacfbf09d65f2611b5622de51d98e18151acb3bb84c09caaa0cc80edfa743a4679f37d6167618ce99e73362fa6f213409931762618a61f1738c071bba5afc1db24fe94afb70c40d731908ab9a505f76f57a7d40e708fd3df0efc5b7cbb2a7b75cd23449e09684a2f0e2bfa0d6176c35f96fe94d92fc9fa4103972781f81cb6e8df7dbeb0fc529c600d768bed3f08828b773d284f69e9a203459d88c12d6df7a75be2455fec128f07a497a2b2bf626cc6272d0419ca663e9dc66b8224227eb796f0246dcae9c5b0b6cfdbbd40c3245a610481c92047c968c9fc92c04b89cc41a0c15355a8f").unwrap()); // Dave handles the onion message but he'll log that he errored while decoding the hop data // because he sees it as an empty onion message (the only contents of the sender's OM is "hello" diff --git a/lightning/src/onion_message/messenger.rs b/lightning/src/onion_message/messenger.rs index 7b0bae82ba8..f918c998f6d 100644 --- a/lightning/src/onion_message/messenger.rs +++ b/lightning/src/onion_message/messenger.rs @@ -10,45 +10,51 @@ //! LDK sends, receives, and forwards onion messages via this [`OnionMessenger`], which lives here, //! as well as various types, traits, and utilities that it uses. -use bitcoin::hashes::{Hash, HashEngine}; use bitcoin::hashes::hmac::{Hmac, HmacEngine}; use bitcoin::hashes::sha256::Hash as Sha256; +use bitcoin::hashes::{Hash, HashEngine}; use bitcoin::secp256k1::{self, PublicKey, Scalar, Secp256k1, SecretKey}; -use crate::blinded_path::{IntroductionNode, NodeIdLookUp}; -use crate::blinded_path::message::{BlindedMessagePath, MessageForwardNode, ForwardTlvs, MessageContext, NextMessageHop, ReceiveTlvs}; +#[cfg(async_payments)] +use super::async_payments::AsyncPaymentsMessage; +use super::async_payments::AsyncPaymentsMessageHandler; +use super::dns_resolution::{DNSResolverMessage, DNSResolverMessageHandler}; +use super::offers::OffersMessageHandler; +use super::packet::OnionMessageContents; +use super::packet::ParsedOnionMessageContents; +use super::packet::{ + ForwardControlTlvs, Packet, Payload, ReceiveControlTlvs, BIG_PACKET_HOP_DATA_LEN, + SMALL_PACKET_HOP_DATA_LEN, +}; +use crate::blinded_path::message::{ + BlindedMessagePath, ForwardTlvs, MessageContext, MessageForwardNode, NextMessageHop, + ReceiveTlvs, +}; use crate::blinded_path::utils; +use crate::blinded_path::{IntroductionNode, NodeIdLookUp}; use crate::events::{Event, EventHandler, EventsProvider, ReplayEvent}; -use crate::sign::{EntropySource, NodeSigner, Recipient}; -use crate::types::features::{InitFeatures, NodeFeatures}; use crate::ln::msgs::{self, OnionMessage, OnionMessageHandler, SocketAddress}; use crate::ln::onion_utils; use crate::routing::gossip::{NetworkGraph, NodeId, ReadOnlyNetworkGraph}; -use super::async_payments::AsyncPaymentsMessageHandler; -#[cfg(async_payments)] -use super::async_payments::AsyncPaymentsMessage; -use super::dns_resolution::{DNSResolverMessageHandler, DNSResolverMessage}; -use super::packet::OnionMessageContents; -use super::packet::ParsedOnionMessageContents; -use super::offers::OffersMessageHandler; -use super::packet::{BIG_PACKET_HOP_DATA_LEN, ForwardControlTlvs, Packet, Payload, ReceiveControlTlvs, SMALL_PACKET_HOP_DATA_LEN}; +use crate::sign::{EntropySource, NodeSigner, Recipient}; +use crate::types::features::{InitFeatures, NodeFeatures}; use crate::util::async_poll::{MultiResultFuturePoller, ResultFuture}; use crate::util::logger::{Logger, WithContext}; use crate::util::ser::Writeable; use crate::util::wakers::{Future, Notifier}; +use crate::io; +use crate::prelude::*; +use crate::sync::Mutex; use core::fmt; use core::ops::Deref; use core::sync::atomic::{AtomicBool, Ordering}; -use crate::io; -use crate::sync::Mutex; -use crate::prelude::*; #[cfg(not(c_bindings))] use { - crate::sign::KeysManager, crate::ln::channelmanager::{SimpleArcChannelManager, SimpleRefChannelManager}, crate::ln::peer_handler::IgnoringMessageHandler, + crate::sign::KeysManager, crate::sync::Arc, }; @@ -96,18 +102,40 @@ pub trait AOnionMessenger { /// A type that may be dereferenced to [`Self::CustomOnionMessageHandler`] type CMH: Deref; /// Returns a reference to the actual [`OnionMessenger`] object. - fn get_om(&self) -> &OnionMessenger; + fn get_om( + &self, + ) -> &OnionMessenger< + Self::ES, + Self::NS, + Self::L, + Self::NL, + Self::MR, + Self::OMH, + Self::APH, + Self::DRH, + Self::CMH, + >; } -impl AOnionMessenger -for OnionMessenger where +impl< + ES: Deref, + NS: Deref, + L: Deref, + NL: Deref, + MR: Deref, + OMH: Deref, + APH: Deref, + DRH: Deref, + CMH: Deref, + > AOnionMessenger for OnionMessenger +where ES::Target: EntropySource, NS::Target: NodeSigner, L::Target: Logger, NL::Target: NodeIdLookUp, MR::Target: MessageRouter, OMH::Target: OffersMessageHandler, - APH:: Target: AsyncPaymentsMessageHandler, + APH::Target: AsyncPaymentsMessageHandler, DRH::Target: DNSResolverMessageHandler, CMH::Target: CustomOnionMessageHandler, { @@ -129,7 +157,9 @@ for OnionMessenger where type DRH = DRH; type CustomOnionMessageHandler = CMH::Target; type CMH = CMH; - fn get_om(&self) -> &OnionMessenger { self } + fn get_om(&self) -> &OnionMessenger { + self + } } /// A sender, receiver and forwarder of [`OnionMessage`]s. @@ -251,7 +281,15 @@ for OnionMessenger where /// [`InvoiceRequest`]: crate::offers::invoice_request::InvoiceRequest /// [`Bolt12Invoice`]: crate::offers::invoice::Bolt12Invoice pub struct OnionMessenger< - ES: Deref, NS: Deref, L: Deref, NL: Deref, MR: Deref, OMH: Deref, APH: Deref, DRH: Deref, CMH: Deref + ES: Deref, + NS: Deref, + L: Deref, + NL: Deref, + MR: Deref, + OMH: Deref, + APH: Deref, + DRH: Deref, + CMH: Deref, > where ES::Target: EntropySource, NS::Target: NodeSigner, @@ -353,7 +391,6 @@ impl OnionMessageRecipient { } } - /// The `Responder` struct creates an appropriate [`ResponseInstruction`] for responding to a /// message. #[derive(Clone, Debug, Eq, PartialEq)] @@ -369,9 +406,7 @@ impl_writeable_tlv_based!(Responder, { impl Responder { /// Creates a new [`Responder`] instance with the provided reply path. pub(super) fn new(reply_path: BlindedMessagePath) -> Self { - Responder { - reply_path, - } + Responder { reply_path } } /// Creates a [`ResponseInstruction`] for responding without including a reply path. @@ -450,15 +485,14 @@ pub enum MessageSendInstructions { pub trait MessageRouter { /// Returns a route for sending an [`OnionMessage`] to the given [`Destination`]. fn find_path( - &self, sender: PublicKey, peers: Vec, destination: Destination + &self, sender: PublicKey, peers: Vec, destination: Destination, ) -> Result; /// Creates [`BlindedMessagePath`]s to the `recipient` node. The nodes in `peers` are assumed to /// be direct peers with the `recipient`. - fn create_blinded_paths< - T: secp256k1::Signing + secp256k1::Verification - >( - &self, recipient: PublicKey, context: MessageContext, peers: Vec, secp_ctx: &Secp256k1, + fn create_blinded_paths( + &self, recipient: PublicKey, context: MessageContext, peers: Vec, + secp_ctx: &Secp256k1, ) -> Result, ()>; /// Creates compact [`BlindedMessagePath`]s to the `recipient` node. The nodes in `peers` are @@ -474,11 +508,9 @@ pub trait MessageRouter { /// /// The provided implementation simply delegates to [`MessageRouter::create_blinded_paths`], /// ignoring the short channel ids. - fn create_compact_blinded_paths< - T: secp256k1::Signing + secp256k1::Verification - >( - &self, recipient: PublicKey, context: MessageContext, - peers: Vec, secp_ctx: &Secp256k1, + fn create_compact_blinded_paths( + &self, recipient: PublicKey, context: MessageContext, peers: Vec, + secp_ctx: &Secp256k1, ) -> Result, ()> { let peers = peers .into_iter() @@ -496,7 +528,7 @@ pub trait MessageRouter { /// it will create a one-hop path using the recipient as the introduction node if it is a announced /// node. Otherwise, there is no way to find a path to the introduction node in order to send a /// message, and thus an `Err` is returned. -pub struct DefaultMessageRouter>, L: Deref, ES: Deref> +pub struct DefaultMessageRouter>, L: Deref, ES: Deref> where L::Target: Logger, ES::Target: EntropySource, @@ -505,7 +537,7 @@ where entropy_source: ES, } -impl>, L: Deref, ES: Deref> DefaultMessageRouter +impl>, L: Deref, ES: Deref> DefaultMessageRouter where L::Target: Logger, ES::Target: EntropySource, @@ -517,7 +549,7 @@ where fn create_blinded_paths_from_iter< I: ExactSizeIterator, - T: secp256k1::Signing + secp256k1::Verification + T: secp256k1::Signing + secp256k1::Verification, >( network_graph: &G, recipient: PublicKey, context: MessageContext, peers: I, entropy_source: &ES, secp_ctx: &Secp256k1, compact_paths: bool, @@ -536,18 +568,16 @@ where let has_one_peer = peers.len() == 1; let mut peer_info = peers // Limit to peers with announced channels unless the recipient is unannounced. - .filter_map(|peer| + .filter_map(|peer| { network_graph .node(&NodeId::from_pubkey(&peer.node_id)) - .filter(|info| + .filter(|info| { !is_recipient_announced || info.channels.len() >= MIN_PEER_CHANNELS - ) + }) .map(|info| (peer, info.is_tor_only(), info.channels.len())) // Allow messages directly with the only peer when unannounced. - .or_else(|| (!is_recipient_announced && has_one_peer) - .then(|| (peer, false, 0)) - ) - ) + .or_else(|| (!is_recipient_announced && has_one_peer).then(|| (peer, false, 0))) + }) // Exclude Tor-only nodes when the recipient is announced. .filter(|(_, is_tor_only, _)| !(*is_tor_only && is_recipient_announced)) .collect::>(); @@ -557,9 +587,16 @@ where a_tor_only.cmp(b_tor_only).then(a_channels.cmp(b_channels).reverse()) }); - let paths = peer_info.into_iter() + let paths = peer_info + .into_iter() .map(|(peer, _, _)| { - BlindedMessagePath::new(&[peer], recipient, context.clone(), &**entropy_source, secp_ctx) + BlindedMessagePath::new( + &[peer], + recipient, + context.clone(), + &**entropy_source, + secp_ctx, + ) }) .take(MAX_PATHS) .collect::, _>>(); @@ -586,7 +623,7 @@ where } pub(crate) fn find_path( - network_graph: &G, sender: PublicKey, peers: Vec, mut destination: Destination + network_graph: &G, sender: PublicKey, peers: Vec, mut destination: Destination, ) -> Result { let network_graph = network_graph.deref().read_only(); destination.resolve(&network_graph); @@ -598,19 +635,27 @@ where if peers.contains(&first_node) || sender == first_node { Ok(OnionMessagePath { - intermediate_nodes: vec![], destination, first_node_addresses: None + intermediate_nodes: vec![], + destination, + first_node_addresses: None, }) } else { let node_details = network_graph .node(&NodeId::from_pubkey(&first_node)) .and_then(|node_info| node_info.announcement_info.as_ref()) - .map(|announcement_info| (announcement_info.features(), announcement_info.addresses())); + .map(|announcement_info| { + (announcement_info.features(), announcement_info.addresses()) + }); match node_details { - Some((features, addresses)) if features.supports_onion_messages() && addresses.len() > 0 => { + Some((features, addresses)) + if features.supports_onion_messages() && addresses.len() > 0 => + { let first_node_addresses = Some(addresses.to_vec()); Ok(OnionMessagePath { - intermediate_nodes: vec![], destination, first_node_addresses + intermediate_nodes: vec![], + destination, + first_node_addresses, }) }, _ => Err(()), @@ -618,55 +663,78 @@ where } } - pub(crate) fn create_blinded_paths< - T: secp256k1::Signing + secp256k1::Verification - >( - network_graph: &G, recipient: PublicKey, context: MessageContext, - peers: Vec, entropy_source: &ES, secp_ctx: &Secp256k1, + pub(crate) fn create_blinded_paths( + network_graph: &G, recipient: PublicKey, context: MessageContext, peers: Vec, + entropy_source: &ES, secp_ctx: &Secp256k1, ) -> Result, ()> { - let peers = peers - .into_iter() - .map(|node_id| MessageForwardNode { node_id, short_channel_id: None }); - Self::create_blinded_paths_from_iter(network_graph, recipient, context, peers.into_iter(), entropy_source, secp_ctx, false) + let peers = + peers.into_iter().map(|node_id| MessageForwardNode { node_id, short_channel_id: None }); + Self::create_blinded_paths_from_iter( + network_graph, + recipient, + context, + peers.into_iter(), + entropy_source, + secp_ctx, + false, + ) } - pub(crate) fn create_compact_blinded_paths< - T: secp256k1::Signing + secp256k1::Verification - >( + pub(crate) fn create_compact_blinded_paths( network_graph: &G, recipient: PublicKey, context: MessageContext, peers: Vec, entropy_source: &ES, secp_ctx: &Secp256k1, ) -> Result, ()> { - Self::create_blinded_paths_from_iter(network_graph, recipient, context, peers.into_iter(), entropy_source, secp_ctx, true) + Self::create_blinded_paths_from_iter( + network_graph, + recipient, + context, + peers.into_iter(), + entropy_source, + secp_ctx, + true, + ) } } -impl>, L: Deref, ES: Deref> MessageRouter for DefaultMessageRouter +impl>, L: Deref, ES: Deref> MessageRouter + for DefaultMessageRouter where L::Target: Logger, ES::Target: EntropySource, { fn find_path( - &self, sender: PublicKey, peers: Vec, destination: Destination + &self, sender: PublicKey, peers: Vec, destination: Destination, ) -> Result { Self::find_path(&self.network_graph, sender, peers, destination) } - fn create_blinded_paths< - T: secp256k1::Signing + secp256k1::Verification - >( - &self, recipient: PublicKey, context: MessageContext, peers: Vec, secp_ctx: &Secp256k1, + fn create_blinded_paths( + &self, recipient: PublicKey, context: MessageContext, peers: Vec, + secp_ctx: &Secp256k1, ) -> Result, ()> { - Self::create_blinded_paths(&self.network_graph, recipient, context, peers, &self.entropy_source, secp_ctx) + Self::create_blinded_paths( + &self.network_graph, + recipient, + context, + peers, + &self.entropy_source, + secp_ctx, + ) } - fn create_compact_blinded_paths< - T: secp256k1::Signing + secp256k1::Verification - >( - &self, recipient: PublicKey, context: MessageContext, peers: Vec, secp_ctx: &Secp256k1, + fn create_compact_blinded_paths( + &self, recipient: PublicKey, context: MessageContext, peers: Vec, + secp_ctx: &Secp256k1, ) -> Result, ()> { - Self::create_compact_blinded_paths(&self.network_graph, recipient, context, peers, &self.entropy_source, secp_ctx) + Self::create_compact_blinded_paths( + &self.network_graph, + recipient, + context, + peers, + &self.entropy_source, + secp_ctx, + ) } - } /// A path for sending an [`OnionMessage`]. @@ -688,10 +756,7 @@ pub struct OnionMessagePath { impl OnionMessagePath { /// Returns the first node in the path. pub fn first_node(&self) -> Option { - self.intermediate_nodes - .first() - .copied() - .or_else(|| self.destination.first_node()) + self.intermediate_nodes.first().copied().or_else(|| self.destination.first_node()) } } @@ -731,11 +796,9 @@ impl Destination { fn first_node(&self) -> Option { match self { Destination::Node(node_id) => Some(*node_id), - Destination::BlindedPath(path) => { - match path.introduction_node() { - IntroductionNode::NodeId(pubkey) => Some(*pubkey), - IntroductionNode::DirectedShortChannelId(..) => None, - } + Destination::BlindedPath(path) => match path.introduction_node() { + IntroductionNode::NodeId(pubkey) => Some(*pubkey), + IntroductionNode::DirectedShortChannelId(..) => None, }, } } @@ -813,18 +876,22 @@ pub trait CustomOnionMessageHandler { /// /// The returned [`Self::CustomMessage`], if any, is enqueued to be sent by [`OnionMessenger`]. fn handle_custom_message( - &self, message: Self::CustomMessage, context: Option>, responder: Option + &self, message: Self::CustomMessage, context: Option>, responder: Option, ) -> Option<(Self::CustomMessage, ResponseInstruction)>; /// Read a custom message of type `message_type` from `buffer`, returning `Ok(None)` if the /// message type is unknown. - fn read_custom_message(&self, message_type: u64, buffer: &mut R) -> Result, msgs::DecodeError>; + fn read_custom_message( + &self, message_type: u64, buffer: &mut R, + ) -> Result, msgs::DecodeError>; /// Releases any [`Self::CustomMessage`]s that need to be sent. /// /// Typically, this is used for messages initiating a message flow rather than in response to /// another message. The latter should use the return value of [`Self::handle_custom_message`]. - fn release_pending_custom_messages(&self) -> Vec<(Self::CustomMessage, MessageSendInstructions)>; + fn release_pending_custom_messages( + &self, + ) -> Vec<(Self::CustomMessage, MessageSendInstructions)>; } /// A processed incoming onion message, containing either a Forward (another onion message) @@ -834,10 +901,9 @@ pub enum PeeledOnion { /// Forwarded onion, with the next node id and a new onion Forward(NextMessageHop, OnionMessage), /// Received onion message, with decrypted contents, context, and reply path - Receive(ParsedOnionMessageContents, Option, Option) + Receive(ParsedOnionMessageContents, Option, Option), } - /// Creates an [`OnionMessage`] with the given `contents` for sending to the destination of /// `path`, first calling [`Destination::resolve`] on `path.destination` with the given /// [`ReadOnlyNetworkGraph`]. @@ -845,7 +911,10 @@ pub enum PeeledOnion { /// Returns the node id of the peer to send the message to, the message itself, and any addresses /// needed to connect to the first node. pub fn create_onion_message_resolving_destination< - ES: Deref, NS: Deref, NL: Deref, T: OnionMessageContents + ES: Deref, + NS: Deref, + NL: Deref, + T: OnionMessageContents, >( entropy_source: &ES, node_signer: &NS, node_id_lookup: &NL, network_graph: &ReadOnlyNetworkGraph, secp_ctx: &Secp256k1, @@ -858,7 +927,13 @@ where { path.destination.resolve(network_graph); create_onion_message( - entropy_source, node_signer, node_id_lookup, secp_ctx, path, contents, reply_path, + entropy_source, + node_signer, + node_id_lookup, + secp_ctx, + path, + contents, + reply_path, ) } @@ -890,13 +965,16 @@ where } } - if contents.tlv_type() < 64 { return Err(SendError::InvalidMessage) } + if contents.tlv_type() < 64 { + return Err(SendError::InvalidMessage); + } // If we are sending straight to a blinded path and we are the introduction node, we need to // advance the blinded path by 1 hop so the second hop is the new introduction node. if intermediate_nodes.len() == 0 { if let Destination::BlindedPath(ref mut blinded_path) = destination { - let our_node_id = node_signer.get_node_id(Recipient::Node) + let our_node_id = node_signer + .get_node_id(Recipient::Node) .map_err(|()| SendError::GetNodeIdFailed)?; let introduction_node_id = match blinded_path.introduction_node() { IntroductionNode::NodeId(pubkey) => *pubkey, @@ -908,7 +986,8 @@ where }, }; if introduction_node_id == our_node_id { - blinded_path.advance_path_by_one(node_signer, node_id_lookup, &secp_ctx) + blinded_path + .advance_path_by_one(node_signer, node_id_lookup, &secp_ctx) .map_err(|()| SendError::BlindedPathAdvanceFailed)?; } } @@ -921,23 +1000,27 @@ where } else { match &destination { Destination::Node(pk) => (*pk, PublicKey::from_secret_key(&secp_ctx, &blinding_secret)), - Destination::BlindedPath(path) => { - match path.introduction_node() { - IntroductionNode::NodeId(pubkey) => (*pubkey, path.blinding_point()), - IntroductionNode::DirectedShortChannelId(..) => { - return Err(SendError::UnresolvedIntroductionNode); - }, - } - } + Destination::BlindedPath(path) => match path.introduction_node() { + IntroductionNode::NodeId(pubkey) => (*pubkey, path.blinding_point()), + IntroductionNode::DirectedShortChannelId(..) => { + return Err(SendError::UnresolvedIntroductionNode); + }, + }, } }; let (packet_payloads, packet_keys) = packet_payloads_and_keys( - &secp_ctx, intermediate_nodes, destination, contents, reply_path, &blinding_secret + &secp_ctx, + intermediate_nodes, + destination, + contents, + reply_path, + &blinding_secret, )?; let prng_seed = entropy_source.get_secure_random_bytes(); - let onion_routing_packet = construct_onion_message_packet( - packet_payloads, packet_keys, prng_seed).map_err(|()| SendError::TooBigPacket)?; + let onion_routing_packet = + construct_onion_message_packet(packet_payloads, packet_keys, prng_seed) + .map_err(|()| SendError::TooBigPacket)?; let message = OnionMessage { blinding_point, onion_routing_packet }; Ok((first_node_id, message, first_node_addresses)) @@ -958,10 +1041,10 @@ where { let control_tlvs_ss = match node_signer.ecdh(Recipient::Node, &msg.blinding_point, None) { Ok(ss) => ss, - Err(e) => { + Err(e) => { log_error!(logger, "Failed to retrieve node secret: {:?}", e); return Err(()); - } + }, }; let onion_decode_ss = { let blinding_factor = { @@ -969,60 +1052,81 @@ where hmac.input(control_tlvs_ss.as_ref()); Hmac::from_engine(hmac).to_byte_array() }; - match node_signer.ecdh(Recipient::Node, &msg.onion_routing_packet.public_key, - Some(&Scalar::from_be_bytes(blinding_factor).unwrap())) - { + match node_signer.ecdh( + Recipient::Node, + &msg.onion_routing_packet.public_key, + Some(&Scalar::from_be_bytes(blinding_factor).unwrap()), + ) { Ok(ss) => ss.secret_bytes(), Err(()) => { log_trace!(logger, "Failed to compute onion packet shared secret"); return Err(()); - } + }, } }; match onion_utils::decode_next_untagged_hop( - onion_decode_ss, &msg.onion_routing_packet.hop_data[..], msg.onion_routing_packet.hmac, - (control_tlvs_ss, custom_handler.deref(), logger.deref()) + onion_decode_ss, + &msg.onion_routing_packet.hop_data[..], + msg.onion_routing_packet.hmac, + (control_tlvs_ss, custom_handler.deref(), logger.deref()), ) { - Ok((Payload::Receive::::Target as CustomOnionMessageHandler>::CustomMessage>> { - message, control_tlvs: ReceiveControlTlvs::Unblinded(ReceiveTlvs { context }), reply_path, - }, None)) => { - match (&message, &context) { - (_, None) => { - Ok(PeeledOnion::Receive(message, None, reply_path)) - } - (ParsedOnionMessageContents::Offers(_), Some(MessageContext::Offers(_))) => { - Ok(PeeledOnion::Receive(message, context, reply_path)) - } - #[cfg(async_payments)] - (ParsedOnionMessageContents::AsyncPayments(_), Some(MessageContext::AsyncPayments(_))) => { - Ok(PeeledOnion::Receive(message, context, reply_path)) - } - (ParsedOnionMessageContents::Custom(_), Some(MessageContext::Custom(_))) => { - Ok(PeeledOnion::Receive(message, context, reply_path)) - } - (ParsedOnionMessageContents::DNSResolver(_), Some(MessageContext::DNSResolver(_))) => { - Ok(PeeledOnion::Receive(message, context, reply_path)) - } - _ => { - log_trace!(logger, "Received message was sent on a blinded path with the wrong context."); - Err(()) - } - } + Ok(( + Payload::Receive::< + ParsedOnionMessageContents< + <::Target as CustomOnionMessageHandler>::CustomMessage, + >, + > { + message, + control_tlvs: ReceiveControlTlvs::Unblinded(ReceiveTlvs { context }), + reply_path, + }, + None, + )) => match (&message, &context) { + (_, None) => Ok(PeeledOnion::Receive(message, None, reply_path)), + (ParsedOnionMessageContents::Offers(_), Some(MessageContext::Offers(_))) => { + Ok(PeeledOnion::Receive(message, context, reply_path)) + }, + #[cfg(async_payments)] + ( + ParsedOnionMessageContents::AsyncPayments(_), + Some(MessageContext::AsyncPayments(_)), + ) => Ok(PeeledOnion::Receive(message, context, reply_path)), + (ParsedOnionMessageContents::Custom(_), Some(MessageContext::Custom(_))) => { + Ok(PeeledOnion::Receive(message, context, reply_path)) + }, + (ParsedOnionMessageContents::DNSResolver(_), Some(MessageContext::DNSResolver(_))) => { + Ok(PeeledOnion::Receive(message, context, reply_path)) + }, + _ => { + log_trace!( + logger, + "Received message was sent on a blinded path with the wrong context." + ); + Err(()) + }, }, - Ok((Payload::Forward(ForwardControlTlvs::Unblinded(ForwardTlvs { - next_hop, next_blinding_override - })), Some((next_hop_hmac, new_packet_bytes)))) => { + Ok(( + Payload::Forward(ForwardControlTlvs::Unblinded(ForwardTlvs { + next_hop, + next_blinding_override, + })), + Some((next_hop_hmac, new_packet_bytes)), + )) => { // TODO: we need to check whether `next_hop` is our node, in which case this is a dummy // blinded hop and this onion message is destined for us. In this situation, we should keep // unwrapping the onion layers to get to the final payload. Since we don't have the option // of creating blinded paths with dummy hops currently, we should be ok to not handle this // for now. - let new_pubkey = match onion_utils::next_hop_pubkey(&secp_ctx, msg.onion_routing_packet.public_key, &onion_decode_ss) { + let new_pubkey = match onion_utils::next_hop_pubkey( + &secp_ctx, + msg.onion_routing_packet.public_key, + &onion_decode_ss, + ) { Ok(pk) => pk, Err(e) => { log_trace!(logger, "Failed to compute next hop packet pubkey: {}", e); - return Err(()) - } + return Err(()); + }, }; let outgoing_packet = Packet { version: 0, @@ -1035,15 +1139,17 @@ where Some(blinding_point) => blinding_point, None => { match onion_utils::next_hop_pubkey( - &secp_ctx, msg.blinding_point, control_tlvs_ss.as_ref() + &secp_ctx, + msg.blinding_point, + control_tlvs_ss.as_ref(), ) { Ok(bp) => bp, Err(e) => { log_trace!(logger, "Failed to compute next blinding point: {}", e); - return Err(()) - } + return Err(()); + }, } - } + }, }, onion_routing_packet: outgoing_packet, }; @@ -1061,35 +1167,46 @@ where } } -macro_rules! drop_handled_events_and_abort { ($self: expr, $res_iter: expr, $event_queue: expr) => { - // We want to make sure to cleanly abort upon event handling failure. To this end, we drop all - // successfully handled events from the given queue, reset the events processing flag, and - // return, to have the events eventually replayed upon next invocation. - { - let mut queue_lock = $event_queue.lock().unwrap(); - - // Keep all events which previously error'd *or* any that have been added since we dropped - // the Mutex before. - let mut any_error = false; - queue_lock.retain(|_| { - $res_iter.next().map_or(true, |r| { - let is_err = r.is_err(); - any_error |= is_err; - is_err - }) - }); +macro_rules! drop_handled_events_and_abort { + ($self: expr, $res_iter: expr, $event_queue: expr) => { + // We want to make sure to cleanly abort upon event handling failure. To this end, we drop all + // successfully handled events from the given queue, reset the events processing flag, and + // return, to have the events eventually replayed upon next invocation. + { + let mut queue_lock = $event_queue.lock().unwrap(); + + // Keep all events which previously error'd *or* any that have been added since we dropped + // the Mutex before. + let mut any_error = false; + queue_lock.retain(|_| { + $res_iter.next().map_or(true, |r| { + let is_err = r.is_err(); + any_error |= is_err; + is_err + }) + }); - if any_error { - // We failed handling some events. Return to have them eventually replayed. - $self.pending_events_processor.store(false, Ordering::Release); - $self.event_notifier.notify(); - return; + if any_error { + // We failed handling some events. Return to have them eventually replayed. + $self.pending_events_processor.store(false, Ordering::Release); + $self.event_notifier.notify(); + return; + } } - } -}} + }; +} -impl -OnionMessenger +impl< + ES: Deref, + NS: Deref, + L: Deref, + NL: Deref, + MR: Deref, + OMH: Deref, + APH: Deref, + DRH: Deref, + CMH: Deref, + > OnionMessenger where ES::Target: EntropySource, NS::Target: NodeSigner, @@ -1108,8 +1225,16 @@ where offers_handler: OMH, async_payments_handler: APH, dns_resolver: DRH, custom_handler: CMH, ) -> Self { Self::new_inner( - entropy_source, node_signer, logger, node_id_lookup, message_router, - offers_handler, async_payments_handler, dns_resolver, custom_handler, false, + entropy_source, + node_signer, + logger, + node_id_lookup, + message_router, + offers_handler, + async_payments_handler, + dns_resolver, + custom_handler, + false, ) } @@ -1135,20 +1260,27 @@ where /// onion messages are persisted and only persist onion messages for relevant /// peers. pub fn new_with_offline_peer_interception( - entropy_source: ES, node_signer: NS, logger: L, node_id_lookup: NL, - message_router: MR, offers_handler: OMH, async_payments_handler: APH, dns_resolver: DRH, - custom_handler: CMH, + entropy_source: ES, node_signer: NS, logger: L, node_id_lookup: NL, message_router: MR, + offers_handler: OMH, async_payments_handler: APH, dns_resolver: DRH, custom_handler: CMH, ) -> Self { Self::new_inner( - entropy_source, node_signer, logger, node_id_lookup, message_router, - offers_handler, async_payments_handler, dns_resolver, custom_handler, true, + entropy_source, + node_signer, + logger, + node_id_lookup, + message_router, + offers_handler, + async_payments_handler, + dns_resolver, + custom_handler, + true, ) } fn new_inner( - entropy_source: ES, node_signer: NS, logger: L, node_id_lookup: NL, - message_router: MR, offers_handler: OMH, async_payments_handler: APH, dns_resolver: DRH, - custom_handler: CMH, intercept_messages_for_offline_peers: bool, + entropy_source: ES, node_signer: NS, logger: L, node_id_lookup: NL, message_router: MR, + offers_handler: OMH, async_payments_handler: APH, dns_resolver: DRH, custom_handler: CMH, + intercept_messages_for_offline_peers: bool, ) -> Self { let mut secp_ctx = Secp256k1::new(); secp_ctx.seeded_randomize(&entropy_source.get_secure_random_bytes()); @@ -1188,26 +1320,28 @@ where &self, contents: T, instructions: MessageSendInstructions, log_suffix: fmt::Arguments, ) -> Result { let (destination, reply_path) = match instructions { - MessageSendInstructions::WithSpecifiedReplyPath { destination, reply_path } => - (destination, Some(reply_path)), + MessageSendInstructions::WithSpecifiedReplyPath { destination, reply_path } => { + (destination, Some(reply_path)) + }, MessageSendInstructions::WithReplyPath { destination, context } - |MessageSendInstructions::ForReply { instructions: ResponseInstruction { destination, context: Some(context) } } => - { - match self.create_blinded_path(context) { - Ok(reply_path) => (destination, Some(reply_path)), - Err(err) => { - log_trace!( - self.logger, - "Failed to create reply path {}: {:?}", - log_suffix, err - ); - return Err(err); - } - } + | MessageSendInstructions::ForReply { + instructions: ResponseInstruction { destination, context: Some(context) }, + } => match self.create_blinded_path(context) { + Ok(reply_path) => (destination, Some(reply_path)), + Err(err) => { + log_trace!( + self.logger, + "Failed to create reply path {}: {:?}", + log_suffix, + err + ); + return Err(err); + }, }, MessageSendInstructions::WithoutReplyPath { destination } - |MessageSendInstructions::ForReply { instructions: ResponseInstruction { destination, context: None } } => - (destination, None), + | MessageSendInstructions::ForReply { + instructions: ResponseInstruction { destination, context: None }, + } => (destination, None), }; let mut logger = WithContext::from(&self.logger, None, None, None); @@ -1234,7 +1368,8 @@ where log_trace!( logger, "Buffered onion message waiting on peer connection {}: {}", - log_suffix, node_id + log_suffix, + node_id ); }, } @@ -1243,11 +1378,15 @@ where } fn find_path(&self, destination: Destination) -> Result { - let sender = self.node_signer + let sender = self + .node_signer .get_node_id(Recipient::Node) .map_err(|_| SendError::GetNodeIdFailed)?; - let peers = self.message_recipients.lock().unwrap() + let peers = self + .message_recipients + .lock() + .unwrap() .iter() .filter(|(_, recipient)| matches!(recipient, OnionMessageRecipient::ConnectedPeer(_))) .map(|(node_id, _)| *node_id) @@ -1258,16 +1397,22 @@ where .map_err(|_| SendError::PathNotFound) } - fn create_blinded_path(&self, context: MessageContext) -> Result { - let recipient = self.node_signer + fn create_blinded_path( + &self, context: MessageContext, + ) -> Result { + let recipient = self + .node_signer .get_node_id(Recipient::Node) .map_err(|_| SendError::GetNodeIdFailed)?; let secp_ctx = &self.secp_ctx; - let peers = self.message_recipients.lock().unwrap() + let peers = self + .message_recipients + .lock() + .unwrap() .iter() .filter(|(_, peer)| matches!(peer, OnionMessageRecipient::ConnectedPeer(_))) - .map(|(node_id, _ )| *node_id) + .map(|(node_id, _)| *node_id) .collect::>(); self.message_router @@ -1278,13 +1423,18 @@ where fn enqueue_onion_message( &self, path: OnionMessagePath, contents: T, reply_path: Option, - log_suffix: fmt::Arguments + log_suffix: fmt::Arguments, ) -> Result { log_trace!(self.logger, "Constructing onion message {}: {:?}", log_suffix, contents); let (first_node_id, onion_message, addresses) = create_onion_message( - &self.entropy_source, &self.node_signer, &self.node_id_lookup, &self.secp_ctx, path, - contents, reply_path, + &self.entropy_source, + &self.node_signer, + &self.node_id_lookup, + &self.secp_ctx, + path, + contents, + reply_path, )?; let mut message_recipients = self.message_recipients.lock().unwrap(); @@ -1318,7 +1468,7 @@ where /// and want to forward a previously intercepted onion message to a peer that /// has just come online. pub fn forward_onion_message( - &self, message: OnionMessage, peer_node_id: &PublicKey + &self, message: OnionMessage, peer_node_id: &PublicKey, ) -> Result<(), SendError> { let mut message_recipients = self.message_recipients.lock().unwrap(); if outbound_buffer_full(&peer_node_id, &message_recipients) { @@ -1330,22 +1480,26 @@ where e.get_mut().enqueue_message(message); Ok(()) }, - _ => Err(SendError::InvalidFirstHop(*peer_node_id)) + _ => Err(SendError::InvalidFirstHop(*peer_node_id)), } } #[cfg(any(test, feature = "_test_utils"))] pub fn send_onion_message_using_path( - &self, path: OnionMessagePath, contents: T, reply_path: Option + &self, path: OnionMessagePath, contents: T, reply_path: Option, ) -> Result { self.enqueue_onion_message(path, contents, reply_path, format_args!("")) } pub(crate) fn peel_onion_message( - &self, msg: &OnionMessage + &self, msg: &OnionMessage, ) -> Result::Target as CustomOnionMessageHandler>::CustomMessage>, ()> { peel_onion_message( - msg, &self.secp_ctx, &*self.node_signer, &*self.logger, &*self.custom_handler + msg, + &self.secp_ctx, + &*self.node_signer, + &*self.logger, + &*self.custom_handler, ) } @@ -1362,11 +1516,9 @@ where ) -> Result { let message_type = response.msg_type(); self.send_onion_message_internal( - response, instructions.into_instructions(), - format_args!( - "when responding with {} to an onion message", - message_type, - ) + response, + instructions.into_instructions(), + format_args!("when responding with {} to an onion message", message_type,), ) } @@ -1386,11 +1538,11 @@ where const MAX_EVENTS_BUFFER_SIZE: usize = (1 << 10) * 256; let mut pending_intercepted_msgs_events = self.pending_intercepted_msgs_events.lock().unwrap(); - let total_buffered_bytes: usize = pending_intercepted_msgs_events.iter() - .map(|ev| ev.serialized_length()).sum(); + let total_buffered_bytes: usize = + pending_intercepted_msgs_events.iter().map(|ev| ev.serialized_length()).sum(); if total_buffered_bytes >= MAX_EVENTS_BUFFER_SIZE { log_trace!(self.logger, "Dropping event {:?}: buffer full", event); - return + return; } pending_intercepted_msgs_events.push(event); self.event_notifier.notify(); @@ -1414,10 +1566,17 @@ where /// have an ordering requirement. /// /// See the trait-level documentation of [`EventsProvider`] for requirements. - pub async fn process_pending_events_async> + core::marker::Unpin, H: Fn(Event) -> Future>( - &self, handler: H + pub async fn process_pending_events_async< + Future: core::future::Future> + core::marker::Unpin, + H: Fn(Event) -> Future, + >( + &self, handler: H, ) { - if self.pending_events_processor.compare_exchange(false, true, Ordering::Acquire, Ordering::Relaxed).is_err() { + if self + .pending_events_processor + .compare_exchange(false, true, Ordering::Acquire, Ordering::Relaxed) + .is_err() + { return; } @@ -1440,7 +1599,10 @@ where let intercepted_msgs_offset = futures.len(); for ev in intercepted_msgs { - if let Event::OnionMessageIntercepted { .. } = ev {} else { debug_assert!(false); } + if let Event::OnionMessageIntercepted { .. } = ev { + } else { + debug_assert!(false); + } log_trace!(self.logger, "Handling event {:?} async...", ev); let future = ResultFuture::Pending(handler(ev)); futures.push(future); @@ -1451,7 +1613,11 @@ where let res = MultiResultFuturePoller::new(futures).await; log_trace!(self.logger, "Done handling events async, results: {:?}", res); let mut res_iter = res.iter().skip(intercepted_msgs_offset); - drop_handled_events_and_abort!(self, res_iter, self.pending_intercepted_msgs_events); + drop_handled_events_and_abort!( + self, + res_iter, + self.pending_intercepted_msgs_events + ); } } @@ -1461,7 +1627,10 @@ where if num_peer_connecteds <= 1 { for event in peer_connecteds { if handler(event).await.is_ok() { - self.pending_peer_connected_events.lock().unwrap().drain(..num_peer_connecteds); + self.pending_peer_connected_events + .lock() + .unwrap() + .drain(..num_peer_connecteds); } else { // We failed handling the event. Return to have it eventually replayed. self.pending_events_processor.store(false, Ordering::Release); @@ -1480,7 +1649,11 @@ where let res = MultiResultFuturePoller::new(futures).await; log_trace!(self.logger, "Done handling events async, results: {:?}", res); let mut res_iter = res.iter(); - drop_handled_events_and_abort!(self, res_iter, self.pending_peer_connected_events); + drop_handled_events_and_abort!( + self, + res_iter, + self.pending_peer_connected_events + ); } } } @@ -1488,7 +1661,9 @@ where } } -fn outbound_buffer_full(peer_node_id: &PublicKey, buffer: &HashMap) -> bool { +fn outbound_buffer_full( + peer_node_id: &PublicKey, buffer: &HashMap, +) -> bool { const MAX_TOTAL_BUFFER_SIZE: usize = (1 << 20) * 128; const MAX_PER_PEER_BUFFER_SIZE: usize = (1 << 10) * 256; let mut total_buffered_bytes = 0; @@ -1501,18 +1676,27 @@ fn outbound_buffer_full(peer_node_id: &PublicKey, buffer: &HashMap= MAX_TOTAL_BUFFER_SIZE || - peer_buffered_bytes >= MAX_PER_PEER_BUFFER_SIZE + if total_buffered_bytes >= MAX_TOTAL_BUFFER_SIZE + || peer_buffered_bytes >= MAX_PER_PEER_BUFFER_SIZE { - return true + return true; } } } false } -impl EventsProvider -for OnionMessenger +impl< + ES: Deref, + NS: Deref, + L: Deref, + NL: Deref, + MR: Deref, + OMH: Deref, + APH: Deref, + DRH: Deref, + CMH: Deref, + > EventsProvider for OnionMessenger where ES::Target: EntropySource, NS::Target: NodeSigner, @@ -1524,8 +1708,15 @@ where DRH::Target: DNSResolverMessageHandler, CMH::Target: CustomOnionMessageHandler, { - fn process_pending_events(&self, handler: H) where H::Target: EventHandler { - if self.pending_events_processor.compare_exchange(false, true, Ordering::Acquire, Ordering::Relaxed).is_err() { + fn process_pending_events(&self, handler: H) + where + H::Target: EventHandler, + { + if self + .pending_events_processor + .compare_exchange(false, true, Ordering::Acquire, Ordering::Relaxed) + .is_err() + { return; } @@ -1542,16 +1733,24 @@ where let intercepted_msgs; let peer_connecteds; { - let pending_intercepted_msgs_events = self.pending_intercepted_msgs_events.lock().unwrap(); + let pending_intercepted_msgs_events = + self.pending_intercepted_msgs_events.lock().unwrap(); intercepted_msgs = pending_intercepted_msgs_events.clone(); let pending_peer_connected_events = self.pending_peer_connected_events.lock().unwrap(); peer_connecteds = pending_peer_connected_events.clone(); - #[cfg(debug_assertions)] { + #[cfg(debug_assertions)] + { for ev in pending_intercepted_msgs_events.iter() { - if let Event::OnionMessageIntercepted { .. } = ev {} else { panic!(); } + if let Event::OnionMessageIntercepted { .. } = ev { + } else { + panic!(); + } } for ev in pending_peer_connected_events.iter() { - if let Event::OnionMessagePeerConnected { .. } = ev {} else { panic!(); } + if let Event::OnionMessagePeerConnected { .. } = ev { + } else { + panic!(); + } } } } @@ -1564,15 +1763,16 @@ where log_trace!(self.logger, "Done handling event, result: {:?}", res); match res { Ok(()) => num_handled_intercepted_events += 1, - Err(ReplayEvent ()) => { + Err(ReplayEvent()) => { handling_intercepted_msgs_failed = true; break; - } + }, } } { - let mut pending_intercepted_msgs_events = self.pending_intercepted_msgs_events.lock().unwrap(); + let mut pending_intercepted_msgs_events = + self.pending_intercepted_msgs_events.lock().unwrap(); pending_intercepted_msgs_events.drain(..num_handled_intercepted_events); } @@ -1589,15 +1789,16 @@ where log_trace!(self.logger, "Done handling event, result: {:?}", res); match res { Ok(()) => num_handled_peer_connecteds += 1, - Err(ReplayEvent ()) => { + Err(ReplayEvent()) => { self.event_notifier.notify(); break; - } + }, } } { - let mut pending_peer_connected_events = self.pending_peer_connected_events.lock().unwrap(); + let mut pending_peer_connected_events = + self.pending_peer_connected_events.lock().unwrap(); pending_peer_connected_events.drain(..num_handled_peer_connecteds); pending_peer_connected_events.shrink_to(10); // Limit total heap usage } @@ -1606,8 +1807,17 @@ where } } -impl OnionMessageHandler -for OnionMessenger +impl< + ES: Deref, + NS: Deref, + L: Deref, + NL: Deref, + MR: Deref, + OMH: Deref, + APH: Deref, + DRH: Deref, + CMH: Deref, + > OnionMessageHandler for OnionMessenger where ES::Target: EntropySource, NS::Target: NodeSigner, @@ -1626,7 +1836,9 @@ where log_trace!( logger, "Received an onion message with {} reply_path: {:?}", - if reply_path.is_some() { "a" } else { "no" }, message); + if reply_path.is_some() { "a" } else { "no" }, + message + ); let responder = reply_path.map(Responder::new); match message { @@ -1636,50 +1848,60 @@ where Some(MessageContext::Offers(context)) => Some(context), _ => { debug_assert!(false, "Checked in peel_onion_message"); - return - } + return; + }, }; - let response_instructions = self.offers_handler.handle_message(msg, context, responder); + let response_instructions = + self.offers_handler.handle_message(msg, context, responder); if let Some((msg, instructions)) = response_instructions { let _ = self.handle_onion_message_response(msg, instructions); } }, #[cfg(async_payments)] - ParsedOnionMessageContents::AsyncPayments(AsyncPaymentsMessage::HeldHtlcAvailable(msg)) => { + ParsedOnionMessageContents::AsyncPayments( + AsyncPaymentsMessage::HeldHtlcAvailable(msg), + ) => { let context = match context { Some(MessageContext::AsyncPayments(context)) => context, Some(_) => { debug_assert!(false, "Checked in peel_onion_message"); - return + return; }, None => return, }; - let response_instructions = self.async_payments_handler.handle_held_htlc_available( - msg, context, responder - ); + let response_instructions = self + .async_payments_handler + .handle_held_htlc_available(msg, context, responder); if let Some((msg, instructions)) = response_instructions { let _ = self.handle_onion_message_response(msg, instructions); } }, #[cfg(async_payments)] - ParsedOnionMessageContents::AsyncPayments(AsyncPaymentsMessage::ReleaseHeldHtlc(msg)) => { + ParsedOnionMessageContents::AsyncPayments( + AsyncPaymentsMessage::ReleaseHeldHtlc(msg), + ) => { let context = match context { Some(MessageContext::AsyncPayments(context)) => context, Some(_) => { debug_assert!(false, "Checked in peel_onion_message"); - return + return; }, None => return, }; self.async_payments_handler.handle_release_held_htlc(msg, context); }, - ParsedOnionMessageContents::DNSResolver(DNSResolverMessage::DNSSECQuery(msg)) => { - let response_instructions = self.dns_resolver_handler.handle_dnssec_query(msg, responder); + ParsedOnionMessageContents::DNSResolver(DNSResolverMessage::DNSSECQuery( + msg, + )) => { + let response_instructions = + self.dns_resolver_handler.handle_dnssec_query(msg, responder); if let Some((msg, instructions)) = response_instructions { let _ = self.handle_onion_message_response(msg, instructions); } }, - ParsedOnionMessageContents::DNSResolver(DNSResolverMessage::DNSSECProof(msg)) => { + ParsedOnionMessageContents::DNSResolver(DNSResolverMessage::DNSSECProof( + msg, + )) => { let context = match context { Some(MessageContext::DNSResolver(context)) => context, _ => return, @@ -1692,10 +1914,11 @@ where Some(MessageContext::Custom(data)) => Some(data), _ => { debug_assert!(false, "Checked in peel_onion_message"); - return - } + return; + }, }; - let response_instructions = self.custom_handler.handle_custom_message(msg, context, responder); + let response_instructions = + self.custom_handler.handle_custom_message(msg, context, responder); if let Some((msg, instructions)) = response_instructions { let _ = self.handle_onion_message_response(msg, instructions); } @@ -1705,12 +1928,14 @@ where Ok(PeeledOnion::Forward(next_hop, onion_message)) => { let next_node_id = match next_hop { NextMessageHop::NodeId(pubkey) => pubkey, - NextMessageHop::ShortChannelId(scid) => match self.node_id_lookup.next_node_id(scid) { - Some(pubkey) => pubkey, - None => { - log_trace!(self.logger, "Dropping forwarded onion messager: unable to resolve next hop using SCID {}", scid); - return - }, + NextMessageHop::ShortChannelId(scid) => { + match self.node_id_lookup.next_node_id(scid) { + Some(pubkey) => pubkey, + None => { + log_trace!(self.logger, "Dropping forwarded onion messager: unable to resolve next hop using SCID {}", scid); + return; + }, + } }, }; @@ -1719,8 +1944,9 @@ where log_trace!( logger, "Dropping forwarded onion message to peer {}: outbound buffer full", - next_node_id); - return + next_node_id + ); + return; } #[cfg(fuzzing)] @@ -1729,46 +1955,49 @@ where .or_insert_with(|| OnionMessageRecipient::ConnectedPeer(VecDeque::new())); match message_recipients.entry(next_node_id) { - hash_map::Entry::Occupied(mut e) if matches!( - e.get(), OnionMessageRecipient::ConnectedPeer(..) - ) => { + hash_map::Entry::Occupied(mut e) + if matches!(e.get(), OnionMessageRecipient::ConnectedPeer(..)) => + { e.get_mut().enqueue_message(onion_message); log_trace!(logger, "Forwarding an onion message to peer {}", next_node_id); }, _ if self.intercept_messages_for_offline_peers => { - self.enqueue_intercepted_event( - Event::OnionMessageIntercepted { - peer_node_id: next_node_id, message: onion_message - } - ); + self.enqueue_intercepted_event(Event::OnionMessageIntercepted { + peer_node_id: next_node_id, + message: onion_message, + }); }, _ => { log_trace!( logger, "Dropping forwarded onion message to disconnected peer {}", - next_node_id); - return + next_node_id + ); + return; }, } }, Err(e) => { log_error!(logger, "Failed to process onion message {:?}", e); - } + }, } } - fn peer_connected(&self, their_node_id: PublicKey, init: &msgs::Init, _inbound: bool) -> Result<(), ()> { + fn peer_connected( + &self, their_node_id: PublicKey, init: &msgs::Init, _inbound: bool, + ) -> Result<(), ()> { if init.features.supports_onion_messages() { - self.message_recipients.lock().unwrap() + self.message_recipients + .lock() + .unwrap() .entry(their_node_id) .or_insert_with(|| OnionMessageRecipient::ConnectedPeer(VecDeque::new())) .mark_connected(); if self.intercept_messages_for_offline_peers { let mut pending_peer_connected_events = self.pending_peer_connected_events.lock().unwrap(); - pending_peer_connected_events.push( - Event::OnionMessagePeerConnected { peer_node_id: their_node_id } - ); + pending_peer_connected_events + .push(Event::OnionMessagePeerConnected { peer_node_id: their_node_id }); self.event_notifier.notify(); } } else { @@ -1825,14 +2054,19 @@ where // Enqueue any initiating `OffersMessage`s to send. for (message, instructions) in self.offers_handler.release_pending_messages() { let _ = self.send_onion_message_internal( - message, instructions, format_args!("when sending OffersMessage") + message, + instructions, + format_args!("when sending OffersMessage"), ); } - #[cfg(async_payments)] { + #[cfg(async_payments)] + { for (message, instructions) in self.async_payments_handler.release_pending_messages() { let _ = self.send_onion_message_internal( - message, instructions, format_args!("when sending AsyncPaymentsMessage") + message, + instructions, + format_args!("when sending AsyncPaymentsMessage"), ); } } @@ -1840,18 +2074,24 @@ where // Enqueue any initiating `DNSResolverMessage`s to send. for (message, instructions) in self.dns_resolver_handler.release_pending_messages() { let _ = self.send_onion_message_internal( - message, instructions, format_args!("when sending DNSResolverMessage") + message, + instructions, + format_args!("when sending DNSResolverMessage"), ); } // Enqueue any initiating `CustomMessage`s to send. for (message, instructions) in self.custom_handler.release_pending_custom_messages() { let _ = self.send_onion_message_internal( - message, instructions, format_args!("when sending CustomMessage") + message, + instructions, + format_args!("when sending CustomMessage"), ); } - self.message_recipients.lock().unwrap() + self.message_recipients + .lock() + .unwrap() .get_mut(&peer_node_id) .and_then(|buffer| buffer.dequeue_message()) } @@ -1877,7 +2117,7 @@ pub type SimpleArcOnionMessenger = OnionMessenger< Arc>, Arc>, Arc>, - IgnoringMessageHandler + IgnoringMessageHandler, >; /// Useful for simplifying the parameters of [`SimpleArcChannelManager`] and @@ -1898,7 +2138,7 @@ pub type SimpleArcOnionMessenger = OnionMessenger< Arc>, Arc>, IgnoringMessageHandler, - IgnoringMessageHandler + IgnoringMessageHandler, >; /// Useful for simplifying the parameters of [`SimpleRefChannelManager`] and @@ -1910,19 +2150,18 @@ pub type SimpleArcOnionMessenger = OnionMessenger< /// [`SimpleRefPeerManager`]: crate::ln::peer_handler::SimpleRefPeerManager #[cfg(not(c_bindings))] #[cfg(feature = "dnssec")] -pub type SimpleRefOnionMessenger< - 'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, 'i, 'j, M, T, F, L -> = OnionMessenger< - &'a KeysManager, - &'a KeysManager, - &'b L, - &'j SimpleRefChannelManager<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, 'i, M, T, F, L>, - &'i DefaultMessageRouter<&'g NetworkGraph<&'b L>, &'b L, &'a KeysManager>, - &'j SimpleRefChannelManager<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, 'i, M, T, F, L>, - &'j SimpleRefChannelManager<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, 'i, M, T, F, L>, - &'j SimpleRefChannelManager<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, 'i, M, T, F, L>, - IgnoringMessageHandler ->; +pub type SimpleRefOnionMessenger<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, 'i, 'j, M, T, F, L> = + OnionMessenger< + &'a KeysManager, + &'a KeysManager, + &'b L, + &'j SimpleRefChannelManager<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, 'i, M, T, F, L>, + &'i DefaultMessageRouter<&'g NetworkGraph<&'b L>, &'b L, &'a KeysManager>, + &'j SimpleRefChannelManager<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, 'i, M, T, F, L>, + &'j SimpleRefChannelManager<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, 'i, M, T, F, L>, + &'j SimpleRefChannelManager<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, 'i, M, T, F, L>, + IgnoringMessageHandler, + >; /// Useful for simplifying the parameters of [`SimpleRefChannelManager`] and /// [`SimpleRefPeerManager`]. See their docs for more details. @@ -1933,25 +2172,27 @@ pub type SimpleRefOnionMessenger< /// [`SimpleRefPeerManager`]: crate::ln::peer_handler::SimpleRefPeerManager #[cfg(not(c_bindings))] #[cfg(not(feature = "dnssec"))] -pub type SimpleRefOnionMessenger< - 'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, 'i, 'j, M, T, F, L -> = OnionMessenger< - &'a KeysManager, - &'a KeysManager, - &'b L, - &'j SimpleRefChannelManager<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, 'i, M, T, F, L>, - &'i DefaultMessageRouter<&'g NetworkGraph<&'b L>, &'b L, &'a KeysManager>, - &'j SimpleRefChannelManager<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, 'i, M, T, F, L>, - &'j SimpleRefChannelManager<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, 'i, M, T, F, L>, - IgnoringMessageHandler, - IgnoringMessageHandler ->; +pub type SimpleRefOnionMessenger<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, 'i, 'j, M, T, F, L> = + OnionMessenger< + &'a KeysManager, + &'a KeysManager, + &'b L, + &'j SimpleRefChannelManager<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, 'i, M, T, F, L>, + &'i DefaultMessageRouter<&'g NetworkGraph<&'b L>, &'b L, &'a KeysManager>, + &'j SimpleRefChannelManager<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, 'i, M, T, F, L>, + &'j SimpleRefChannelManager<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, 'i, M, T, F, L>, + IgnoringMessageHandler, + IgnoringMessageHandler, + >; /// Construct onion packet payloads and keys for sending an onion message along the given /// `unblinded_path` to the given `destination`. -fn packet_payloads_and_keys( +fn packet_payloads_and_keys< + T: OnionMessageContents, + S: secp256k1::Signing + secp256k1::Verification, +>( secp_ctx: &Secp256k1, unblinded_path: Vec, destination: Destination, message: T, - mut reply_path: Option, session_priv: &SecretKey + mut reply_path: Option, session_priv: &SecretKey, ) -> Result<(Vec<(Payload, [u8; 32])>, Vec), SendError> { let num_hops = unblinded_path.len() + destination.num_hops(); let mut payloads = Vec::with_capacity(num_hops); @@ -1976,30 +2217,44 @@ fn packet_payloads_and_keys(payloads: Vec<(Payload, [u8; 32])>, onion_keys: Vec, prng_seed: [u8; 32]) -> Result { +fn construct_onion_message_packet( + payloads: Vec<(Payload, [u8; 32])>, onion_keys: Vec, + prng_seed: [u8; 32], +) -> Result { // Spec rationale: // "`len` allows larger messages to be sent than the standard 1300 bytes allowed for an HTLC // onion, but this should be used sparingly as it is reduces anonymity set, hence the @@ -2047,8 +2308,14 @@ fn construct_onion_message_packet(payloads: Vec<(Payloa SMALL_PACKET_HOP_DATA_LEN } else if payloads_ser_len <= BIG_PACKET_HOP_DATA_LEN { BIG_PACKET_HOP_DATA_LEN - } else { return Err(()) }; + } else { + return Err(()); + }; onion_utils::construct_onion_message_packet::<_, _>( - payloads, onion_keys, prng_seed, hop_data_len) + payloads, + onion_keys, + prng_seed, + hop_data_len, + ) } diff --git a/lightning/src/onion_message/mod.rs b/lightning/src/onion_message/mod.rs index a5735e372f3..79fd69f2cbe 100644 --- a/lightning/src/onion_message/mod.rs +++ b/lightning/src/onion_message/mod.rs @@ -23,8 +23,8 @@ pub mod async_payments; pub mod dns_resolution; +#[cfg(test)] +mod functional_tests; pub mod messenger; pub mod offers; pub mod packet; -#[cfg(test)] -mod functional_tests; diff --git a/lightning/src/onion_message/offers.rs b/lightning/src/onion_message/offers.rs index f93c0854ea5..1d0f9c7b664 100644 --- a/lightning/src/onion_message/offers.rs +++ b/lightning/src/onion_message/offers.rs @@ -9,20 +9,20 @@ //! Message handling for BOLT 12 Offers. -use core::fmt; use crate::blinded_path::message::OffersContext; use crate::io::{self, Read}; use crate::ln::msgs::DecodeError; +use crate::offers::invoice::Bolt12Invoice; use crate::offers::invoice_error::InvoiceError; use crate::offers::invoice_request::InvoiceRequest; -use crate::offers::invoice::Bolt12Invoice; use crate::offers::parse::Bolt12ParseError; #[cfg(async_payments)] use crate::offers::static_invoice::StaticInvoice; +use crate::onion_message::messenger::{MessageSendInstructions, Responder, ResponseInstruction}; use crate::onion_message::packet::OnionMessageContents; use crate::util::logger::Logger; use crate::util::ser::{Readable, ReadableArgs, Writeable, Writer}; -use crate::onion_message::messenger::{ResponseInstruction, Responder, MessageSendInstructions}; +use core::fmt; use crate::prelude::*; @@ -51,7 +51,9 @@ pub trait OffersMessageHandler { /// /// Typically, this is used for messages initiating a payment flow rather than in response to /// another message. The latter should use the return value of [`Self::handle_message`]. - fn release_pending_messages(&self) -> Vec<(OffersMessage, MessageSendInstructions)> { vec![] } + fn release_pending_messages(&self) -> Vec<(OffersMessage, MessageSendInstructions)> { + vec![] + } } /// Possible BOLT 12 Offers messages sent and received via an [`OnionMessage`]. @@ -81,9 +83,7 @@ impl OffersMessage { /// Returns whether `tlv_type` corresponds to a TLV record for Offers. pub fn is_known_type(tlv_type: u64) -> bool { match tlv_type { - INVOICE_REQUEST_TLV_TYPE - | INVOICE_TLV_TYPE - | INVOICE_ERROR_TLV_TYPE => true, + INVOICE_REQUEST_TLV_TYPE | INVOICE_TLV_TYPE | INVOICE_ERROR_TLV_TYPE => true, #[cfg(async_payments)] STATIC_INVOICE_TLV_TYPE => true, _ => false, @@ -116,17 +116,17 @@ impl fmt::Debug for OffersMessage { match self { OffersMessage::InvoiceRequest(message) => { write!(f, "{:?}", message.as_tlv_stream()) - } + }, OffersMessage::Invoice(message) => { write!(f, "{:?}", message.as_tlv_stream()) - } + }, #[cfg(async_payments)] OffersMessage::StaticInvoice(message) => { write!(f, "{:?}", message) - } + }, OffersMessage::InvoiceError(message) => { write!(f, "{:?}", message) - } + }, } } } diff --git a/lightning/src/onion_message/packet.rs b/lightning/src/onion_message/packet.rs index 8ec85a6bed7..780eab2bd95 100644 --- a/lightning/src/onion_message/packet.rs +++ b/lightning/src/onion_message/packet.rs @@ -9,26 +9,29 @@ //! Structs and enums useful for constructing and reading an onion message packet. -use bitcoin::secp256k1::PublicKey; use bitcoin::secp256k1::ecdh::SharedSecret; +use bitcoin::secp256k1::PublicKey; -use crate::blinded_path::message::{BlindedMessagePath, ForwardTlvs, NextMessageHop, ReceiveTlvs}; -use crate::blinded_path::utils::Padding; -use crate::ln::msgs::DecodeError; -use crate::ln::onion_utils; #[cfg(async_payments)] use super::async_payments::AsyncPaymentsMessage; use super::dns_resolution::DNSResolverMessage; use super::messenger::CustomOnionMessageHandler; use super::offers::OffersMessage; +use crate::blinded_path::message::{BlindedMessagePath, ForwardTlvs, NextMessageHop, ReceiveTlvs}; +use crate::blinded_path::utils::Padding; use crate::crypto::streams::{ChaChaPolyReadAdapter, ChaChaPolyWriteAdapter}; +use crate::ln::msgs::DecodeError; +use crate::ln::onion_utils; use crate::util::logger::Logger; -use crate::util::ser::{BigSize, FixedLengthReader, LengthRead, LengthReadable, LengthReadableArgs, Readable, ReadableArgs, Writeable, Writer}; +use crate::util::ser::{ + BigSize, FixedLengthReader, LengthRead, LengthReadable, LengthReadableArgs, Readable, + ReadableArgs, Writeable, Writer, +}; -use core::cmp; -use core::fmt; use crate::io::{self, Read}; use crate::prelude::*; +use core::cmp; +use core::fmt; // Per the spec, an onion message packet's `hop_data` field length should be // SMALL_PACKET_HOP_DATA_LEN if it fits, else BIG_PACKET_HOP_DATA_LEN if it fits. @@ -56,18 +59,17 @@ pub struct Packet { impl onion_utils::Packet for Packet { type Data = Vec; fn new(public_key: PublicKey, hop_data: Vec, hmac: [u8; 32]) -> Packet { - Self { - version: 0, - public_key, - hop_data, - hmac, - } + Self { version: 0, public_key, hop_data, hmac } } } impl fmt::Debug for Packet { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.write_fmt(format_args!("Onion message packet version {} with hmac {:?}", self.version, &self.hmac[..])) + f.write_fmt(format_args!( + "Onion message packet version {} with hmac {:?}", + self.version, + &self.hmac[..] + )) } } @@ -100,12 +102,7 @@ impl LengthReadable for Packet { } let hmac = Readable::read(r)?; - Ok(Packet { - version, - public_key, - hop_data, - hmac, - }) + Ok(Packet { version, public_key, hop_data, hmac }) } } @@ -116,11 +113,7 @@ pub(super) enum Payload { /// This payload is for an intermediate hop. Forward(ForwardControlTlvs), /// This payload is for the final hop. - Receive { - control_tlvs: ReceiveControlTlvs, - reply_path: Option, - message: T, - } + Receive { control_tlvs: ReceiveControlTlvs, reply_path: Option, message: T }, } /// The contents of an [`OnionMessage`] as read from the wire. @@ -225,12 +218,12 @@ impl Writeable for (Payload, [u8; 32]) { fn write(&self, w: &mut W) -> Result<(), io::Error> { match &self.0 { Payload::Forward(ForwardControlTlvs::Blinded(encrypted_bytes)) => { - _encode_varint_length_prefixed_tlv!(w, { - (4, *encrypted_bytes, required_vec) - }) + _encode_varint_length_prefixed_tlv!(w, { (4, *encrypted_bytes, required_vec) }) }, Payload::Receive { - control_tlvs: ReceiveControlTlvs::Blinded(encrypted_bytes), reply_path, message, + control_tlvs: ReceiveControlTlvs::Blinded(encrypted_bytes), + reply_path, + message, } => { _encode_varint_length_prefixed_tlv!(w, { (2, reply_path, option), @@ -240,12 +233,12 @@ impl Writeable for (Payload, [u8; 32]) { }, Payload::Forward(ForwardControlTlvs::Unblinded(control_tlvs)) => { let write_adapter = ChaChaPolyWriteAdapter::new(self.1, &control_tlvs); - _encode_varint_length_prefixed_tlv!(w, { - (4, write_adapter, required) - }) + _encode_varint_length_prefixed_tlv!(w, { (4, write_adapter, required) }) }, Payload::Receive { - control_tlvs: ReceiveControlTlvs::Unblinded(control_tlvs), reply_path, message, + control_tlvs: ReceiveControlTlvs::Unblinded(control_tlvs), + reply_path, + message, } => { let write_adapter = ChaChaPolyWriteAdapter::new(self.1, &control_tlvs); _encode_varint_length_prefixed_tlv!(w, { @@ -261,7 +254,8 @@ impl Writeable for (Payload, [u8; 32]) { // Uses the provided secret to simultaneously decode and decrypt the control TLVs and data TLV. impl ReadableArgs<(SharedSecret, &H, &L)> -for Payload::CustomMessage>> { + for Payload::CustomMessage>> +{ fn read(r: &mut R, args: (SharedSecret, &H, &L)) -> Result { let (encrypted_tlvs_ss, handler, logger) = args; @@ -311,13 +305,13 @@ for Payload::CustomM match read_adapter { None => return Err(DecodeError::InvalidValue), - Some(ChaChaPolyReadAdapter { readable: ControlTlvs::Forward(tlvs)}) => { + Some(ChaChaPolyReadAdapter { readable: ControlTlvs::Forward(tlvs) }) => { if message_type.is_some() { - return Err(DecodeError::InvalidValue) + return Err(DecodeError::InvalidValue); } Ok(Payload::Forward(ForwardControlTlvs::Unblinded(tlvs))) }, - Some(ChaChaPolyReadAdapter { readable: ControlTlvs::Receive(tlvs)}) => { + Some(ChaChaPolyReadAdapter { readable: ControlTlvs::Receive(tlvs) }) => { Ok(Payload::Receive { control_tlvs: ReceiveControlTlvs::Unblinded(tlvs), reply_path, @@ -366,11 +360,9 @@ impl Readable for ControlTlvs { next_blinding_override, }) } else if valid_recv_fmt { - ControlTlvs::Receive(ReceiveTlvs { - context, - }) + ControlTlvs::Receive(ReceiveTlvs { context }) } else { - return Err(DecodeError::InvalidValue) + return Err(DecodeError::InvalidValue); }; Ok(payload_fmt) diff --git a/rustfmt_excluded_files b/rustfmt_excluded_files index 973ecff3392..b4d91fbd67f 100644 --- a/rustfmt_excluded_files +++ b/rustfmt_excluded_files @@ -53,11 +53,6 @@ lightning/src/offers/payer.rs lightning/src/offers/refund.rs lightning/src/offers/signer.rs lightning/src/offers/test_utils.rs -lightning/src/onion_message/functional_tests.rs -lightning/src/onion_message/messenger.rs -lightning/src/onion_message/mod.rs -lightning/src/onion_message/offers.rs -lightning/src/onion_message/packet.rs lightning/src/routing/mod.rs lightning/src/routing/router.rs lightning/src/routing/scoring.rs