X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Fonion_message%2Fmessenger.rs;h=2a9c830d38bec8e7a56e6e4cb98c6389f6cce60b;hb=327142894dc51200255af73721fd58a8187c6021;hp=7d5f4a22ec8573e17764c31017f5804083161b21;hpb=8866ed35330bae1af2237c1951d9c4025938aa65;p=rust-lightning diff --git a/lightning/src/onion_message/messenger.rs b/lightning/src/onion_message/messenger.rs index 7d5f4a22..2a9c830d 100644 --- a/lightning/src/onion_message/messenger.rs +++ b/lightning/src/onion_message/messenger.rs @@ -15,7 +15,9 @@ use bitcoin::hashes::hmac::{Hmac, HmacEngine}; use bitcoin::hashes::sha256::Hash as Sha256; use bitcoin::secp256k1::{self, PublicKey, Scalar, Secp256k1, SecretKey}; -use crate::blinded_path::{BlindedPath, ForwardTlvs, ReceiveTlvs, utils}; +use crate::blinded_path::BlindedPath; +use crate::blinded_path::message::{advance_path_by_one, ForwardTlvs, ReceiveTlvs}; +use crate::blinded_path::utils; use crate::sign::{EntropySource, KeysManager, NodeSigner, Recipient}; use crate::events::OnionMessageProvider; use crate::ln::features::{InitFeatures, NodeFeatures}; @@ -281,6 +283,36 @@ where &self, path: OnionMessagePath, message: OnionMessageContents, reply_path: Option ) -> Result<(), SendError> { + let (introduction_node_id, onion_msg) = Self::create_onion_message( + &self.entropy_source, + &self.node_signer, + &self.secp_ctx, + path, + message, + reply_path + )?; + + let mut pending_per_peer_msgs = self.pending_messages.lock().unwrap(); + if outbound_buffer_full(&introduction_node_id, &pending_per_peer_msgs) { return Err(SendError::BufferFull) } + match pending_per_peer_msgs.entry(introduction_node_id) { + hash_map::Entry::Vacant(_) => Err(SendError::InvalidFirstHop), + hash_map::Entry::Occupied(mut e) => { + e.get_mut().push_back(onion_msg); + Ok(()) + } + } + } + + /// Create an onion message with contents `message` to the destination of `path`. + /// Returns (introduction_node_id, onion_msg) + pub fn create_onion_message( + entropy_source: &ES, + node_signer: &NS, + secp_ctx: &Secp256k1, + path: OnionMessagePath, + message: OnionMessageContents, + reply_path: Option, + ) -> Result<(PublicKey, msgs::OnionMessage), SendError> { let OnionMessagePath { intermediate_nodes, mut destination } = path; if let Destination::BlindedPath(BlindedPath { ref blinded_hops, .. }) = destination { if blinded_hops.len() < 2 { @@ -294,43 +326,38 @@ where // 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 = self.node_signer.get_node_id(Recipient::Node) + let our_node_id = node_signer.get_node_id(Recipient::Node) .map_err(|()| SendError::GetNodeIdFailed)?; if blinded_path.introduction_node_id == our_node_id { - blinded_path.advance_message_path_by_one(&self.node_signer, &self.secp_ctx) + advance_path_by_one(blinded_path, node_signer, &secp_ctx) .map_err(|()| SendError::BlindedPathAdvanceFailed)?; } } } - let blinding_secret_bytes = self.entropy_source.get_secure_random_bytes(); + let blinding_secret_bytes = entropy_source.get_secure_random_bytes(); let blinding_secret = SecretKey::from_slice(&blinding_secret_bytes[..]).expect("RNG is busted"); let (introduction_node_id, blinding_point) = if intermediate_nodes.len() != 0 { - (intermediate_nodes[0], PublicKey::from_secret_key(&self.secp_ctx, &blinding_secret)) + (intermediate_nodes[0], PublicKey::from_secret_key(&secp_ctx, &blinding_secret)) } else { match destination { - Destination::Node(pk) => (pk, PublicKey::from_secret_key(&self.secp_ctx, &blinding_secret)), + Destination::Node(pk) => (pk, PublicKey::from_secret_key(&secp_ctx, &blinding_secret)), Destination::BlindedPath(BlindedPath { introduction_node_id, blinding_point, .. }) => (introduction_node_id, blinding_point), } }; let (packet_payloads, packet_keys) = packet_payloads_and_keys( - &self.secp_ctx, &intermediate_nodes, destination, message, reply_path, &blinding_secret) + &secp_ctx, &intermediate_nodes, destination, message, reply_path, &blinding_secret) .map_err(|e| SendError::Secp256k1(e))?; - let prng_seed = self.entropy_source.get_secure_random_bytes(); + 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 mut pending_per_peer_msgs = self.pending_messages.lock().unwrap(); - if outbound_buffer_full(&introduction_node_id, &pending_per_peer_msgs) { return Err(SendError::BufferFull) } - match pending_per_peer_msgs.entry(introduction_node_id) { - hash_map::Entry::Vacant(_) => Err(SendError::InvalidFirstHop), - hash_map::Entry::Occupied(mut e) => { - e.get_mut().push_back(msgs::OnionMessage { blinding_point, onion_routing_packet }); - Ok(()) - } - } + Ok((introduction_node_id, msgs::OnionMessage { + blinding_point, + onion_routing_packet + })) } fn respond_with_onion_message( @@ -648,46 +675,48 @@ fn packet_payloads_and_keys