Skip to content

Commit

Permalink
Merge pull request #1650 from valentinewallace/2022-08-take-onionmsgs…
Browse files Browse the repository at this point in the history
…-public
  • Loading branch information
TheBlueMatt authored Sep 2, 2022
2 parents 00f08c9 + a8ea0bd commit fc7b14b
Show file tree
Hide file tree
Showing 7 changed files with 148 additions and 61 deletions.
4 changes: 0 additions & 4 deletions lightning/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,11 +79,7 @@ pub mod util;
pub mod chain;
pub mod ln;
pub mod routing;
#[cfg(fuzzing)]
pub mod onion_message;
#[cfg(not(fuzzing))]
#[allow(unused)]
mod onion_message; // To be exposed after sending/receiving OMs is supported in PeerManager.

#[cfg(feature = "std")]
/// Re-export of either `core2::io` or `std::io`, depending on the `std` feature flag.
Expand Down
7 changes: 6 additions & 1 deletion lightning/src/ln/features.rs
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,11 @@ mod sealed {
define_feature!(27, ShutdownAnySegwit, [InitContext, NodeContext],
"Feature flags for `opt_shutdown_anysegwit`.", set_shutdown_any_segwit_optional,
set_shutdown_any_segwit_required, supports_shutdown_anysegwit, requires_shutdown_anysegwit);
// We do not yet advertise the onion messages feature bit, but we need to detect when peers
// support it.
define_feature!(39, OnionMessages, [InitContext, NodeContext],
"Feature flags for `option_onion_messages`.", set_onion_messages_optional,
set_onion_messages_required, supports_onion_messages, requires_onion_messages);
define_feature!(45, ChannelType, [InitContext, NodeContext],
"Feature flags for `option_channel_type`.", set_channel_type_optional,
set_channel_type_required, supports_channel_type, requires_channel_type);
Expand Down Expand Up @@ -767,7 +772,7 @@ impl<T: sealed::GossipQueries> Features<T> {

impl<T: sealed::InitialRoutingSync> Features<T> {
// We are no longer setting initial_routing_sync now that gossip_queries
// is enabled. This feature is ignored by a peer when gossip_queries has
// is enabled. This feature is ignored by a peer when gossip_queries has
// been negotiated.
#[cfg(test)]
pub(crate) fn clear_initial_routing_sync(&mut self) {
Expand Down
6 changes: 6 additions & 0 deletions lightning/src/ln/msgs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -949,6 +949,12 @@ pub trait RoutingMessageHandler : MessageSendEventsProvider {
pub trait OnionMessageHandler : OnionMessageProvider {
/// Handle an incoming onion_message message from the given peer.
fn handle_onion_message(&self, peer_node_id: &PublicKey, msg: &OnionMessage);
/// Called when a connection is established with a peer. Can be used to track which peers
/// advertise onion message support and are online.
fn peer_connected(&self, their_node_id: &PublicKey, init: &Init);
/// Indicates a connection to the peer failed/an existing connection was lost. Allows handlers to
/// drop and refuse to forward onion messages to this peer.
fn peer_disconnected(&self, their_node_id: &PublicKey, no_connection_possible: bool);
}

mod fuzzy_internal_msgs {
Expand Down
10 changes: 9 additions & 1 deletion lightning/src/ln/peer_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ impl OnionMessageProvider for IgnoringMessageHandler {
}
impl OnionMessageHandler for IgnoringMessageHandler {
fn handle_onion_message(&self, _their_node_id: &PublicKey, _msg: &msgs::OnionMessage) {}
fn peer_connected(&self, _their_node_id: &PublicKey, _init: &msgs::Init) {}
fn peer_disconnected(&self, _their_node_id: &PublicKey, _no_connection_possible: bool) {}
}
impl Deref for IgnoringMessageHandler {
type Target = IgnoringMessageHandler;
Expand Down Expand Up @@ -1173,8 +1175,9 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CM
}

self.message_handler.route_handler.peer_connected(&their_node_id, &msg);

self.message_handler.chan_handler.peer_connected(&their_node_id, &msg);
self.message_handler.onion_message_handler.peer_connected(&their_node_id, &msg);

peer_lock.their_features = Some(msg.features);
return Ok(None);
} else if peer_lock.their_features.is_none() {
Expand Down Expand Up @@ -1729,6 +1732,7 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CM
}
descriptor.disconnect_socket();
self.message_handler.chan_handler.peer_disconnected(&node_id, false);
self.message_handler.onion_message_handler.peer_disconnected(&node_id, false);
}
}
}
Expand Down Expand Up @@ -1756,6 +1760,7 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CM
log_pubkey!(node_id), if no_connection_possible { "no " } else { "" });
self.node_id_to_descriptor.lock().unwrap().remove(&node_id);
self.message_handler.chan_handler.peer_disconnected(&node_id, no_connection_possible);
self.message_handler.onion_message_handler.peer_disconnected(&node_id, no_connection_possible);
}
}
};
Expand All @@ -1776,6 +1781,7 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CM
log_trace!(self.logger, "Disconnecting peer with id {} due to client request", node_id);
peers_lock.remove(&descriptor);
self.message_handler.chan_handler.peer_disconnected(&node_id, no_connection_possible);
self.message_handler.onion_message_handler.peer_disconnected(&node_id, no_connection_possible);
descriptor.disconnect_socket();
}
}
Expand All @@ -1791,6 +1797,7 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CM
if let Some(node_id) = peer.lock().unwrap().their_node_id {
log_trace!(self.logger, "Disconnecting peer with id {} due to client request to disconnect all peers", node_id);
self.message_handler.chan_handler.peer_disconnected(&node_id, false);
self.message_handler.onion_message_handler.peer_disconnected(&node_id, false);
}
descriptor.disconnect_socket();
}
Expand Down Expand Up @@ -1881,6 +1888,7 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CM
log_trace!(self.logger, "Disconnecting peer with id {} due to ping timeout", node_id);
self.node_id_to_descriptor.lock().unwrap().remove(&node_id);
self.message_handler.chan_handler.peer_disconnected(&node_id, false);
self.message_handler.onion_message_handler.peer_disconnected(&node_id, false);
}
}
}
Expand Down
41 changes: 28 additions & 13 deletions lightning/src/onion_message/functional_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,14 @@
//! Onion message testing and test utilities live here.

use chain::keysinterface::{KeysInterface, Recipient};
use ln::msgs::OnionMessageHandler;
use ln::features::InitFeatures;
use ln::msgs::{self, OnionMessageHandler};
use super::{BlindedRoute, Destination, OnionMessenger, SendError};
use util::enforcing_trait_impls::EnforcingSigner;
use util::test_utils;

use bitcoin::network::constants::Network;
use bitcoin::secp256k1::{PublicKey, Secp256k1, SecretKey};
use bitcoin::secp256k1::{PublicKey, Secp256k1};

use sync::Arc;

Expand All @@ -34,26 +35,33 @@ impl MessengerNode {
}

fn create_nodes(num_messengers: u8) -> Vec<MessengerNode> {
let mut res = Vec::new();
let mut nodes = Vec::new();
for i in 0..num_messengers {
let logger = Arc::new(test_utils::TestLogger::with_id(format!("node {}", i)));
let seed = [i as u8; 32];
let keys_manager = Arc::new(test_utils::TestKeysInterface::new(&seed, Network::Testnet));
res.push(MessengerNode {
nodes.push(MessengerNode {
keys_manager: keys_manager.clone(),
messenger: OnionMessenger::new(keys_manager, logger.clone()),
logger,
});
}
res
for idx in 0..num_messengers - 1 {
let i = idx as usize;
let mut features = InitFeatures::known();
features.set_onion_messages_optional();
let init_msg = msgs::Init { features, remote_network_address: None };
nodes[i].messenger.peer_connected(&nodes[i + 1].get_node_pk(), &init_msg.clone());
nodes[i + 1].messenger.peer_connected(&nodes[i].get_node_pk(), &init_msg.clone());
}
nodes
}

fn pass_along_path(path: &Vec<MessengerNode>, expected_path_id: Option<[u8; 32]>) {
let mut prev_node = &path[0];
let num_nodes = path.len();
for (idx, node) in path.into_iter().skip(1).enumerate() {
let events = prev_node.messenger.release_pending_msgs();
assert_eq!(events.len(), 1);
let onion_msg = {
let msgs = events.get(&node.get_node_pk()).unwrap();
assert_eq!(msgs.len(), 1);
Expand Down Expand Up @@ -110,12 +118,9 @@ fn three_blinded_hops() {
#[test]
fn too_big_packet_error() {
// Make sure we error as expected if a packet is too big to send.
let nodes = create_nodes(1);

let hop_secret = SecretKey::from_slice(&hex::decode("0101010101010101010101010101010101010101010101010101010101010101").unwrap()[..]).unwrap();
let secp_ctx = Secp256k1::new();
let hop_node_id = PublicKey::from_secret_key(&secp_ctx, &hop_secret);
let nodes = create_nodes(2);

let hop_node_id = nodes[1].get_node_pk();
let hops = [hop_node_id; 400];
let err = nodes[0].messenger.send_onion_message(&hops, Destination::Node(hop_node_id), None).unwrap_err();
assert_eq!(err, SendError::TooBigPacket);
Expand All @@ -124,7 +129,7 @@ fn too_big_packet_error() {
#[test]
fn invalid_blinded_route_error() {
// Make sure we error as expected if a provided blinded route has 0 or 1 hops.
let mut nodes = create_nodes(3);
let nodes = create_nodes(3);

// 0 hops
let secp_ctx = Secp256k1::new();
Expand All @@ -143,7 +148,7 @@ fn invalid_blinded_route_error() {

#[test]
fn reply_path() {
let mut nodes = create_nodes(4);
let nodes = create_nodes(4);
let secp_ctx = Secp256k1::new();

// Destination::Node
Expand All @@ -165,3 +170,13 @@ fn reply_path() {
"lightning::onion_message::messenger".to_string(),
format!("Received an onion message with path_id: None and reply_path").to_string(), 2);
}

#[test]
fn peer_buffer_full() {
let nodes = create_nodes(2);
for _ in 0..188 { // Based on MAX_PER_PEER_BUFFER_SIZE in OnionMessenger
nodes[0].messenger.send_onion_message(&[], Destination::Node(nodes[1].get_node_pk()), None).unwrap();
}
let err = nodes[0].messenger.send_onion_message(&[], Destination::Node(nodes[1].get_node_pk()), None).unwrap_err();
assert_eq!(err, SendError::BufferFull);
}
Loading

0 comments on commit fc7b14b

Please sign in to comment.